跳转至

Redis配置文件和配置项注解手册大全

文档概览

内存单位转换介绍

@引入版本: 2.0.x

关于单位的注意事项:当需要内存大小时,可以用通常的形式“1k”、“5GB”、“4M” 等指定它:

# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units are case insensitive so 1GB 1Gb 1gB are all the same.

Note

  • k, m, g: 十进制 (SI)
  • kb, mb, gb: 二进制

INCLUDES

include

包含一个或多个额外配置文件。

@引入版本: 1.x

@配置语法

# include /path/to/local.conf
# include /path/to/other.conf

# 默认:禁用

@官方参考

在此处包含一个或多个其他配置文件。如果你有一个适用于所有 Redis 服务器的标准模板,但又需要针对每个服务器自定义一些设置,这将非常有用。包含的文件还可以再包含其他文件,因此请谨慎使用。

Note

  • "include" 选项不会被管理员或 Redis 哨兵(Sentinel)发出的 "CONFIG REWRITE" 命令重写。
  • 由于 Redis 始终使用最后处理的行作为配置指令的值,因此最好将 include 语句放在本文件的开头,以避免在运行时覆盖配置更改。
  • 如果你希望使用 include 来覆盖配置选项,那么最好将 include 语句作为文件的最后一行。

MODULES

loadmodule

在启动时加载模块。

@引入版本: 4.0.x

@配置语法

# loadmodule /path/to/my_module.so
# loadmodule /path/to/other_module.so

# 默认:禁用

@官方参考

在启动时加载模块。如果服务器无法加载模块,它将中止启动。可以使用多个 loadmodule 指令。

NETWORK

bind

@引入版本: 1.x

@配置语法

# bind 192.168.1.100 10.0.0.1     # 监听两个特定的 IPv4 地址
# bind 127.0.0.1 ::1              # 在回环、IPv4 和 IPv6 上监听
# bind * -::*                     # 与默认设置一样,在所有可用的网络接口上监听

# 默认 
bind 127.0.0.1 -::1

# 建议: 绑定固定IP
bind 192.168.0.100

@官方参考

默认情况下,如果没有指定 "bind" 配置指令,Redis 会监听主机上所有可用网络接口的连接。可以使用 "bind" 配置指令,后跟一个或多个 IP 地址,来让 Redis 仅监听一个或多个选定的接口。

每个地址前面都可以加上 "-" 前缀,这意味着如果该地址不可用,Redis 也不会启动失败。这里的“不可用”仅指那些不对应任何网络接口的地址。对于已被占用的地址,Redis 始终会启动失败;而对于不支持的协议,则会自动静默跳过。

Warning

如果运行 Redis 的计算机直接暴露在互联网上,绑定到所有接口是危险的,这会使实例暴露给互联网上的任何人。因此,默认情况下我们取消注释以下 bind 指令,这将强制 Redis 仅在 IPv4 和 IPv6(如果可用)的回环接口地址上监听(这意味着 Redis 只能接受来自其运行所在主机的客户端连接)。

# 取消注释后,仅在 IPv4 和 IPv6(如果可用)的回环接口地址上监听
bind 127.0.0.1 -::1

如果你确定希望你的实例监听所有接口,请注释掉下面这一行:

# 注释后,监听主机上所有可用网络接口的连接
# bind 127.0.0.1 -::1

protected-mode

@引入版本: 3.2.x

@配置语法

protected-mode yes

# 默认:yes
# 建议:yes

@官方参考

保护模式是一种安全保护机制,旨在防止在互联网上公开的 Redis 实例被访问和利用。

当保护模式开启时,如果同时满足以下两个条件:

  1. 服务器未通过 "bind" 指令显式绑定到一组特定地址。
  2. 未配置密码。

那么服务器将仅接受来自 IPv4 和 IPv6 回环地址 127.0.0.1::1 的客户端连接,以及来自 Unix 域套接字的连接。

默认情况下,保护模式是启用的。只有当你明确希望来自其他主机的客户端能够连接到 Redis,即使未配置身份验证,也没有使用 "bind" 指令显式列出特定接口时,才应禁用此模式。

port

指定TCP 监听端口。

@引入版本: 1.x

@配置语法

port 6379

# 默认: 6379
# 建议: 自定义端口

@官方参考

在指定端口上接受连接,默认端口为 6379(IANA #815344)。如果指定端口为 0,则 Redis 将不会在 TCP 套接字上监听。

tcp-backlog

TCP listen() 连接请求队列长度(backlog)。

@引入版本: 2.8.x

@配置语法

tcp-backlog 511

# 默认:511
# 建议:使用默认或者自定义

@相关配置

@官方参考

在每秒请求数很高的环境中,你需要设置一个较大的 backlog 值,以避免因慢速客户端连接而引发问题。

请注意,Linux 内核会将其静默截断为 /proc/sys/net/core/somaxconn 文件中设置的值,因此务必同时调高 somaxconntcp_max_syn_backlog 的值,才能达到预期效果。

unixsocket

@引入版本: 2.2.x

@配置语法

# unixsocket /run/redis.sock
# unixsocketperm 700

# 默认: 禁用

@官方参考

指定用于监听传入连接的 Unix 套接字的路径。默认没有设置此选项,因此如果不指定,Redis 将不会监听 Unix 套接字。

timeout

@引入版本: 1.x

@配置语法

timeout 0

# 默认:0

@官方参考

当客户端空闲 N 秒后关闭其连接(设置为 0 表示禁用此功能)。

tcp-keepalive

@引入版本: 2.8.x

@配置语法

tcp-keepalive 300

# 默认:300

@官方参考

如果设置为非零值,则使用 SO_KEEPALIVE 在无通信时向客户端发送 TCP ACK 包。这有两个好处:

  1. 检测已失效的对端(客户端)。
  2. 强制中间的网络设备认为该连接仍然处于活动状态。

在 Linux 系统上,所指定的值(以秒为单位)即为发送 ACK 包的时间间隔。请注意,需要真正关闭连接所需的时间是该值的两倍。在其他内核系统上,该时间间隔取决于内核的配置。

该选项的一个合理取值是 300 秒,从 Redis 3.2.1 版本开始的新默认值。

TLS/SSL

tls-port

@引入版本: 6.0.x

@配置语法

# port 0
# tls-port 6379

# 默认: 禁用

@官方参考

默认情况下,TLS/SSL 是禁用的。要启用它,可以使用 "tls-port" 配置指令来定义用于监听 TLS 连接的端口。若要在默认端口上启用 TLS,请使用:

port 0
tls-port 6379

tls-cert-file and tls-key-file

@引入版本: 6.0.x

@配置语法

# tls-cert-file redis.crt 
# tls-key-file redis.key

# 默认:禁用

@官方参考

配置用于向连接的客户端、主服务器或集群节点进行身份验证的 X.509 证书和私钥。这些文件应为 PEM 格式。

tls-key-file-pass

@引入版本: 6.2.x

@配置语法

# tls-key-file-pass secret

# 默认:禁用

@官方参考

如果密钥文件是使用密码加密的,它也可以包含在这里。

tls-client-cert-file and tls-client-key-file

@引入版本: 6.2.x

@配置语法

# tls-client-cert-file client.crt
# tls-client-key-file client.key

# 默认:禁用

@官方参考

通常情况下,Redis 对服务器功能(接受连接)和客户端功能(从主节点复制数据、建立集群总线连接等)使用相同的证书。

有时,证书会带有属性,将其指定为仅限客户端或仅限服务器使用。在这种情况下,可能需要对传入(服务器端)和传出(客户端)连接使用不同的证书。

为此,请使用以下配置指令:

tls-client-cert-file client.crt
tls-client-key-file client.key

tls-client-key-file-pass

@引入版本: 6.2.x

@配置语法

# tls-client-key-file-pass secret

# 默认:禁用

@官方参考

如果密钥文件是使用密码加密的,它也可以包含在这里。

tls-dh-params-file

@引入版本: 6.0.x

@配置语法

# tls-dh-params-file redis.dh

# 默认:禁用

@官方参考

配置一个 DH 参数文件,以启用 Diffie-Hellman (DH) 密钥交换,这是较旧版本的 OpenSSL(<3.0)所必需的。较新版本的 OpenSSL 不需要此配置,并且不建议使用。

tls-ca-cert-file and tls-ca-cert-dir

@引入版本: 6.0.x

@配置语法

# tls-ca-cert-file ca.crt
# tls-ca-cert-dir /etc/ssl/certs

# 默认:禁用

@官方参考

配置一个 CA 证书包或目录,用于验证 TLS/SSL 客户端和对等节点(peers)。Redis 要求必须显式配置至少其中一项,不会隐式使用系统范围的配置。

tls-auth-clients and tls-auth-clients

@引入版本: 6.0.x

@配置语法

# tls-auth-clients no
# tls-auth-clients optional

# 默认:禁用

@官方参考

默认情况下,连接到 TLS 端口的客户端(包括副本服务器)必须使用有效的客户端证书进行身份验证。

  • 如果设置为 "no",则不需要也不接受客户端证书。
  • 如果设置为 "optional",则接受客户端证书,若提供了证书则必须有效,但并非必须提供。

tls-replication

@引入版本: 6.0.x

@配置语法

# tls-replication yes

# 默认:禁用

@官方参考

默认情况下,Redis 副本不会尝试与其主服务器建立 TLS 连接。

使用以下指令在复制链路上启用 TLS:

tls-replication yes

tls-cluster

@引入版本: 6.0.x

@配置语法

# tls-cluster yes

# 默认:禁用

@官方参考

默认情况下,Redis 集群总线使用普通的 TCP 连接。要为总线协议启用 TLS,请使用以下指令:

# tls-cluster yes

# 默认:禁用

tls-protocols

@引入版本: 6.0.x

@配置语法

# tls-protocols "TLSv1.2 TLSv1.3"

# 默认:禁用

@官方参考

默认情况下,仅启用 TLSv1.2TLSv1.3,强烈建议保持禁用已正式弃用的旧版本,以减少攻击面。你可以显式指定支持的 TLS 版本。允许的值不区分大小写,包括 "TLSv1"、"TLSv1.1"、"TLSv1.2"、"TLSv1.3"(OpenSSL >= 1.1.1)或它们的任意组合。

要仅启用 TLSv1.2 和 TLSv1.3,请使用:

tls-protocols "TLSv1.2 TLSv1.3"

tls-ciphers

@引入版本: 6.0.x

@配置语法

# tls-ciphers DEFAULT:!MEDIUM

# 默认:禁用

@官方参考

配置允许的加密算法(密码套件)。有关此字符串语法的更多信息,请参阅 ciphers(1ssl) 手册页。

Warning

此配置仅适用于 TLSv1.2 及更低版本。

tls-ciphersuites

@引入版本: 6.0.x

@配置语法

# tls-ciphersuites TLS_CHACHA20_POLY1305_SHA256

# 默认:禁用

@官方参考

配置允许的 TLSv1.3 密码套件。有关此字符串语法的更多信息,请参阅 ciphers(1ssl) 手册页,特别是关于 TLSv1.3 密码套件的部分。

tls-prefer-server-ciphers

@引入版本: 6.0.x

@配置语法

# tls-prefer-server-ciphers yes

# 默认:禁用

@官方参考

在选择加密套件时,使用服务器的偏好配置而非客户端的配置。默认情况下,服务器会遵循客户端的优先级顺序。

tls-session-caching

@引入版本: 6.2.x

@配置语法

# tls-session-caching no

# 默认:禁用

@官方参考

默认情况下,TLS 会话缓存是启用的,以允许支持此功能的客户端进行更快且成本更低的重新连接。使用以下指令可禁用缓存。

tls-session-cache-size

@引入版本: 6.2.x

@配置语法

# tls-session-cache-size 5000

# 默认:禁用

@官方参考

更改默认的TLS会话缓存数量。设置为 0 表示缓存大小无限制。默认大小为20480

tls-session-cache-timeout

@引入版本: 6.2.x

@配置语法

# tls-session-cache-timeout 60

# 默认:禁用

@官方参考

更改缓存的 TLS 会话的默认超时时间。默认超时时间为 300 秒。

GENERAL

daemonize

@引入版本: 1.x

@配置语法

daemonize no

# 默认:no
# 建议: yes

@官方参考

默认情况下,Redis 不以守护进程方式运行。如果需要,请设置为 'yes'。

Note

当 Redis 以守护进程方式运行时,会将进程 ID(pid)写入 /var/run/redis.pid 文件中。当 Redis 由 upstartsystemd 进行管理时,此参数无效。

supervised

@引入版本: 3.2.x

@配置语法

# supervised auto

# 默认:禁用

@可选项

  • supervised no:默认值,不进行任何监管交互。
  • supervised upstart:通过将 Redis 置于 SIGSTOP 模式来通知 upstart,要求在 upstart 任务配置中包含 "expect stop"。
  • supervised systemd:在启动时向 $NOTIFY_SOCKET 写入 READY=1 来通知 systemd,并定期更新 Redis 的状态。
  • supervised auto:根据环境变量 UPSTART_JOBNOTIFY_SOCKET 自动检测使用 upstart 还是 systemd 方式。

Note

这些监管方法仅用于发送“进程已就绪(process is ready)”的信号,不会启用持续向监管进程发送心跳(ping)的功能。

@官方参考

如果你通过 upstartsystemd 运行 Redis,Redis 可以与你的监管进程树进行交互。

默认值为 "no"。要在 upstart/systemd 下运行,你只需取消注释下面这一行:

supervised auto

pidfile

@引入版本: 1.x

@配置语法

pidfile /var/run/redis_6379.pid

# 建议:自定义路径

@官方参考

如果指定了 pid 文件,Redis 会在启动时将其写入指定位置,并在退出时删除该文件。

当服务器以非守护进程方式运行时,如果配置中未指定 pid 文件,则不会创建该文件。当服务器以守护进程方式运行时,即使未在配置中指定,也会使用 pid 文件,默认路径为 /var/run/redis.pid

创建 pid 文件是尽力而为的操作:如果 Redis 无法创建该文件,也不会造成严重问题,服务器仍会正常启动和运行。

Note:在现代 Linux 系统中,更符合规范的做法是使用 /run/redis.pid,应优先使用此路径。

loglevel

指定服务器日志级别。

@引入版本: 1.x

@配置语法

loglevel notice

# 默认:notice

@可选项

  • debug: 大量信息,适用于开发/测试阶段。
  • verbose: 包含许多不太常用的信息,但不像 debug 级别那样冗杂。
  • notice: 默认,适度的详细程度,可能是你在生产环境中所需要的。
  • warning: 仅记录非常重要/致命的消息。

logfile

@引入版本: 1.x

@配置语法

logfile ""

# 默认: "" 输出到标准输出
# 建议: 自定义日志路径,/app/redis/logs/redis.log
logfile "/app/redis/logs/redis.log"

@官方参考

指定日志文件的名称。也可以使用空字符串来强制 Redis 将日志输出到标准输出。

Warning

如果你使用标准输出进行日志记录但同时启用了守护进程模式(daemonize),日志将被发送到 /dev/null

syslog-enabled

@引入版本: 2.2.x

@配置语法

# syslog-enabled no

# 默认禁用

@官方参考

要启用将日志记录到系统日志(syslog),只需将 'syslog-enabled' 设置为 yes,并可根据需要选择性地更新其他 syslog 参数。

syslog-ident

指定syslog标识。

@引入版本: 2.2.x

@配置语法

# syslog-ident redis

# 默认:禁用

syslog-facility

@引入版本: 2.2.x

@配置语法

# syslog-facility local0

# 默认:禁用

@官方参考

指定 syslog 设施(facility)。必须是 USERLOCAL0LOCAL7 之间的值。

crash-log-enabled

@引入版本: 6.2.x

@配置语法

# crash-log-enabled no

# 默认:禁用

@官方参考

要禁用内置的崩溃日志记录功能(这可能在需要时生成更干净的 core dump 文件),请取消以下行的注释:

# crash-log-enabled no

# 默认:禁用

crash-memcheck-enabled

@引入版本: 6.2.x

@配置语法

# crash-memcheck-enabled no

# 默认:禁用

@官方参考

要禁用作为崩溃日志一部分运行的快速内存检查(这可能会让 Redis 更快地终止),请取消以下行的注释:

crash-memcheck-enabled no

databases

@引入版本: 1.x

@配置语法

databases 16

# Default 16

@官方参考

设置数据库的数量。默认数据库为 DB 0,你可以通过每连接使用 SELECT <dbid> 命令来选择不同的数据库,其中 dbid 是一个介于 0 和 'databases' -1 之间的数字。

@引入版本: 4.0.x

@配置语法

always-show-logo no

@官方参考

默认情况下,仅当 Redis 启动时日志输出到标准输出、标准输出是 TTY 且未启用 syslog 日志记录时,才会显示 ASCII 艺术标志。这基本上意味着通常只有在交互式会话中才会显示标志。

但是,可以通过将以下选项设置为 yes,强制使用 4.0 版本之前的行为,在启动日志中始终显示 ASCII 艺术标志。

set-proc-title

@引入版本: 6.2.x

@配置语法

set-proc-title yes

# 默认:yes

@官方参考

默认情况下,Redis 会修改进程标题(在 'top' 和 'ps' 命令中可见),以提供一些运行时信息。可以通过将以下选项设置为 no 来禁用此功能,使进程名称保持为最初执行时的名称。

proc-title-template

@引入版本: 6.2.x

@配置语法

proc-title-template "{title} {listen-addr} {server-mode}"

@可选项

  • {title} 进程启动时的名称(如果是父进程)或子进程的类型。
  • {listen-addr} 绑定的地址,或后跟正在监听的 TCP 或 TLS 端口的 '*',如果仅支持 Unix 套接字,则显示该套接字路径。
  • {server-mode} 特殊模式,例如 "[sentinel]" 或 "[cluster]"。
  • {port} 正在监听的 TCP 端口,或 0。
  • {tls-port} 正在监听的 TLS 端口,或 0。
  • {unixsocket} 正在监听的 Unix 域套接字,或空字符串。
  • {config-file} 使用的配置文件名称。

@官方参考

在修改进程标题时,Redis 使用以下模板来构造修改后的标题。

模板变量用花括号指定。

SNAPSHOTTING

save

将数据库保存到磁盘。

@引入版本: 1.x

@配置语法

# save <seconds> <changes>

@官方参考

如果在指定的秒数内,针对数据库的写操作次数达到了指定的数量,Redis 将会保存数据库。

你可以通过取消下面三行的注释来显式设置这些条件。

# default: 
# save 3600 1   # 3600 秒(1小时)后,如果至少有 1 个键被更改。
# save 300 100  # 300 秒(5分钟)后,如果至少有 100 个键被更改。
# save 60 10000 # 60 秒后,如果至少有 10000 个键被更改。

可以通过使用一个空字符串参数来完全禁用快照功能,如下例所示:

# save ""

Warning

除非另有指定,Redis 默认会启用数据库保存功能。

stop-writes-on-bgsave-error

@引入版本: 2.6.x

@配置语法

stop-writes-on-bgsave-error yes

# 默认:yes 

@官方参考

默认情况下,如果启用了 RDB 快照功能(即至少设置了一个保存点)且最近一次后台保存失败,Redis 将停止接受写入操作。这样可以让用户(以一种强制的方式)意识到数据未能正确持久化到磁盘,否则很可能无人察觉,最终导致严重问题。

如果后台保存进程恢复运行,Redis 会自动重新允许写入操作。

然而,如果你已经为 Redis 服务器和持久化机制设置了完善的监控,你可能希望禁用此功能,以便即使出现磁盘、权限等方面的问题,Redis 仍能继续正常工作。

rdbcompression

@引入版本: 1.x

@配置语法

rdbcompression yes

# 默认: yes 

@官方参考

在转储 .rdb 数据库时,是否使用 LZF 压缩字符串对象?默认情况下压缩是启用(enabled)的,因为这几乎总是有利的。如果你希望在执行保存操作的子进程中节省一些 CPU 资源,可以将其设置为 'no',但如果存在可压缩的值或键,数据集很可能会更大。

rdbchecksum

@引入版本: 2.6.x

@配置语法

rdbchecksum yes

# 默认: yes 

@官方参考

从 RDB 版本 5 开始,会在文件末尾添加一个 CRC64 校验和。这使得文件格式更能抵抗损坏,但在保存和加载 RDB 文件时会带来一定的性能损失(大约 10%),因此你可以禁用此功能以获得最佳性能。

Note

禁用校验和后创建的 RDB 文件其校验和为零,加载代码会据此跳过校验。

sanitize-dump-payload

@引入版本: 6.2.x

@配置语法

# sanitize-dump-payload no

# 默认:禁用

@可选项

  • no: 从不执行完全清理。
  • yes: 始终执行完全清理。
  • clients: 仅对用户连接执行完全清理。排除的情况包括:RDB 文件、从主节点连接接收到的 RESTORE 命令,以及具有 skip-sanitize-payload ACL 标志的客户端连接。

@官方参考

在加载 RDB 文件或 RESTORE 命令的数据时,启用或禁用对 ziplistlistpack 等结构的完整性检查。这可以降低后续处理命令时发生断言错误或崩溃的风险。

默认值应为 'clients',但由于目前该选项会影响通过 MIGRATE 进行的集群重新分片操作,因此暂时(temporarily)默认设置为 'no'。

dbfilename

转储数据库的文件名。

@引入版本: 1.x

@配置语法

dbfilename dump.rdb

rdb-del-sync-files

@引入版本: 6.0.x

@配置语法

rdb-del-sync-files no

# 默认: no

@官方参考

在未启用持久化的实例中,删除复制所使用的 RDB 文件。默认情况下此选项是禁用的,但在某些环境中,由于法规或其它安全考虑,主节点为同步副本而生成的 RDB 文件,或副本为初始同步而保存在磁盘上的 RDB 文件,应当尽快删除。

Note: 此选项仅(ONLY WORKS)在同时禁用了 AOF 和 RDB 持久化的实例中生效,否则将被完全忽略。

另一种(有时更优)实现相同效果的方法是在主节点和副本节点上都使用无盘复制(diskless replication)——repl-diskless-sync。然而,对于副本节点而言,无盘复制并不总是可行的选项。

dir of redis

Redis 工作目录。

@引入版本: 1.x

@配置语法

dir ./

# 建议: 自定义
dir /app/redis/db 

@官方参考

数据库将被写入此目录中,文件名由上述使用 dbfilename 配置指令指定。

附加文件(AOF)也将在该目录下创建。

Note: 你必须在此指定一个目录,而不是文件名。

REPLICATION

replicaof

@引入版本: 1.x

@配置语法

# @since: 1.x
# slaveof <masterip> <masterport>

# @since: 5.0.x
# replicaof <masterip> <masterport>

@官方参考

主从复制。使用 replicaof 配置可使一个 Redis 实例成为另一个 Redis 服务器的副本。关于 Redis 复制,你需要尽快了解以下几个要点。

#   +------------------+      +---------------+
#   |      Master      | ---> |    Replica    |
#   | (receive writes) |      |  (exact copy) |
#   +------------------+      +---------------+
  1. Redis 复制是异步(asynchronous)的,但你可以配置主节点,使其在与至少指定数量的副本断开连接时停止接受写操作。
  2. 如果复制连接中断的时间相对较短,Redis 副本能够与主节点执行部分重同步。你可能需要根据实际需求,为复制积压缓冲区(replication backlog)的大小配置一个合理的值(参见本文件的后续章节)。
  3. 复制过程是自动的,无需人工干预。在网络分区恢复后,副本会自动尝试重新连接主节点并与之同步。

masterauth

@引入版本: 1.x

@配置语法

# masterauth <master-password>

@官方参考

如果主节点设置了密码保护(通过下面的 "requirepass" 配置指令)——requirepass,则可以配置副本在开始复制同步过程之前进行身份验证,否则主节点将拒绝副本的请求。

masteruser

配置一个专门用于复制的用户。

@引入版本: 6.0.x

@配置语法

# masteruser <username>

@官方参考

然而,如果你使用的是 Redis ACLs(适用于 Redis 6 或更高版本),并且默认用户没有权限执行 PSYNC 命令和/或(and/or)复制所需的其他命令,则上述配置是不够的。在这种情况下,最好配置一个专门用于复制的用户,并将 masteruser 配置设置为该用户:

masteruser <username>

当指定了 masteruser 时,副本将使用新的 AUTH 格式向其主节点进行身份验证:

AUTH `<username>` `<password>`

replica-serve-stale-data

@引入版本: 2.2.x

@配置语法

# @since: 2.2.x
slave-serve-stale-data yes

# @since: 5.0.x
replica-serve-stale-data yes

@官方参考

当副本与主节点失去连接,或复制仍在进行中时,副本可以采取两种不同的行为方式:

  1. 如果 replica-serve-stale-data 设置为 'yes'(默认值),副本将继续响应客户端请求,但返回的数据可能是过时的;如果这是首次同步,数据集甚至可能是空的。
  2. 如果 replica-serve-stale-data 设置为 'no',副本将对所有命令返回错误信息 "SYNC with master in progress",但以下命令除外:INFOREPLICAOFAUTHPINGSHUTDOWNREPLCONFROLECONFIGSUBSCRIBEUNSUBSCRIBEPSUBSCRIBEPUNSUBSCRIBEPUBLISHPUBSUBCOMMANDPOSTHOSTLATENCY

replica-read-only

@引入版本: 2.6.x

@配置语法

# @since: 2.6.x
slave-read-only yes

# @since: 5.0.x
replica-read-only yes

@官方参考

你可以配置副本实例是否接受写操作。允许向副本实例写入数据可能对存储某些临时(ephemeral)数据有用(因为在副本上写入的数据会在与主节点重新同步后被轻易删除),但如果客户端因配置错误而写入副本,则可能会引发问题。

自 Redis 2.6 版本起,默认情况下副本为只读状态。

Note: 只读副本并非设计用于向互联网上的不可信客户端公开。它仅仅是一层防止误用的保护机制。尽管如此,默认情况下,只读副本仍会开放所有管理类命令,例如 CONFIGDEBUG 等。你可以在一定程度上通过使用 rename-command 命令来重命名或隐藏这些管理和危险命令,从而提升只读副本的安全性。

repl-diskless-sync

@引入版本: 2.6

@配置语法

repl-diskless-sync no

@官方参考

复制同步策略:基于磁盘或基于套接字。

新的副本或重新连接且无法仅通过接收差异数据来继续复制的副本,需要执行所谓的“全量同步(full synchronization)”。在此过程中,主节点会向副本传输一个 RDB 文件。

传输可以通过两种不同的方式进行:

  • Disk-backed: 基于磁盘(Disk-backed):Redis 主节点创建一个子进程,将 RDB 文件写入磁盘。随后,父进程将该文件逐步传输给副本。
  • Diskless: 无盘(Diskless):Redis 主节点创建一个子进程,直接将 RDB 文件写入副本的套接字,完全不经过磁盘。

在基于磁盘的复制中,当 RDB 文件生成时,可以排队多个副本,并在当前生成 RDB 文件的子进程完成工作后,立即使用该文件为它们服务。而在无盘复制中,一旦传输开始,新到达的副本将被排队,当前传输结束后才会启动新的传输。

使用无盘复制时,主节点会在开始传输前等待一段可配置的时间(以秒为单位),希望有多个副本到达,从而实现并行传输。

在磁盘较慢而网络较快(带宽较大)的情况下,无盘(Diskless)复制表现更佳。

repl-diskless-sync-delay

@引入版本: 2.6

@配置语法

repl-diskless-sync-delay 5

@官方参考

当启用无盘复制时,可以配置服务器在派生子进程通过套接字向副本传输 RDB 之前等待的延迟时间。

这一点非常重要,因为一旦传输开始,就无法再为新到达的副本提供服务,这些副本将被排队等待下一次 RDB 传输。因此,服务器会等待一段延迟时间,以便让更多副本能够到达。

延迟时间以秒为单位,默认值为 5 秒。若要完全禁用此延迟,只需将其设置为 0 秒,传输将立即开始。

Warning

RDB 无盘加载功能处于实验阶段。由于在此配置下,副本不会立即将 RDB 文件存储到磁盘,因此在故障转移期间可能导致数据丢失。此外,如果 RDB 无盘加载与无法处理 I/O 读取的 Redis 模块结合使用,在与主节点初始同步阶段发生 I/O 错误时,也可能导致 Redis 中止运行。请仅在明确了解其影响的情况下使用。

repl-diskless-load

@引入版本: 2.6

@配置语法

repl-diskless-load disabled

@官方参考

副本可以从复制连接的套接字直接加载 RDB,也可以先将 RDB 保存到文件中,在从主节点完全接收后再读取该文件。

在许多情况下,磁盘速度比网络慢,存储和加载 RDB 文件可能会增加复制所需的时间(甚至可能增加主节点的写时复制内存和副本的缓冲区)。然而,直接从套接字解析 RDB 文件可能意味着我们必须在完整 RDB 文件接收完毕之前,就清空当前数据库的内容。因此,我们提供了以下选项:

@可选项

  • disabled: 不使用无盘加载(先将 RDB 文件存储到磁盘)。
  • on-empty-db: 仅在绝对安全的情况下使用无盘加载(例如当前数据库为空时)。
  • swapdb: 在直接从套接字解析数据的同时,将当前数据库内容的副本保留在内存中。注意,这需要足够的内存,如果内存不足,可能会导致因内存耗尽(OOM)而被系统终止。

repl-ping-replica-period

@引入版本: 2.6.x

@配置语法

# @since: 2.6.x
# repl-ping-slave-period 10

# @since: 5.0.x
# repl-ping-replica-period 10

@官方参考

副本会按照预定义的时间间隔向主服务器发送 PINGs 命令。可以通过 repl_ping_replica_period 选项来修改该间隔。默认值为 10 秒。

repl-timeout

@引入版本: 2.6.x

@配置语法

# repl-timeout 60

@官方参考

以下选项设置复制超时时间,用于:

  • 从副本的角度看,在 SYNC 过程中的批量传输 I/O。
  • 从副本的角度看,主节点的超时(数据、PING 消息)。
  • 从主节点的角度看,副本的超时(REPLCONF ACK PING 消息)。

必须确保此值大于 repl-ping-replica-period 的值,否则在主节点与副本之间流量较低时,每次都会检测到超时。默认值为 60 秒。

repl-disable-tcp-nodelay

@引入版本: 2.8.x

@配置语法

repl-disable-tcp-nodelay no

@官方参考

SYNC 之后是否禁用副本套接字上的 TCP_NODELAY

如果选择 "yes",Redis 将使用更少的 TCP 数据包和更少的带宽向副本发送数据。但这可能会导致数据在副本端出现延迟,在使用默认配置的 Linux 内核上,延迟最长可达 40 毫秒。

如果选择 "no",数据在副本端的延迟将减少,但复制会消耗更多的带宽。

默认情况下,我们优先考虑低延迟。但在极高流量的情况下,或当主节点与副本之间相隔很多网络跳数时,将其设置为 "yes" 可能是个不错的选择。

repl-backlog-size

@引入版本: 2.8.x

@配置语法

# repl-backlog-size 1mb

@官方参考

设置复制积压缓冲区(replication backlog)的大小。当副本断开连接一段时间时,积压缓冲区会累积副本数据,以便当副本重新连接时,通常不需要进行完整的全量同步,而只需进行部分同步,仅传递副本在断开期间错过的那部分数据即可。

复制积压缓冲区越大,副本能够容忍的断开连接时间就越长,之后仍可执行部分同步。

仅当至少有一个副本连接时,才会分配此积压缓冲区。

repl-backlog-ttl

@引入版本: 2.8.x

@配置语法

# repl-backlog-ttl 3600

@官方参考

当主节点在一段时间内没有任何连接的副本时,积压缓冲区(backlog)将被释放。以下选项配置了从最后一个副本(last replica)断开连接开始,需要经过多少秒后,才释放积压缓冲区。

Note: 副本永远不会因超时而释放积压缓冲区,因为它们之后可能被提升为新的主节点,应能正确地与其他副本进行“部分重同步”;因此,它们应始终持续累积积压数据。

设置为 0 表示永不释放积压缓冲区。

replica-priority

@引入版本: 2.6.x

@配置语法

# @since: 2.6.x
slave-priority 100

# @since: 5.0.x
replica-priority 100

# default: 100

@官方参考

副本优先级是一个由 Redis 在 INFO 命令输出中公布的整数值。Redis Sentinel 使用该值来选择一个合适的副本,在主节点无法正常工作时将其提升为新的主节点。

Note: 优先级数值越低的副本,在晋升时越优先。例如,如果有三个副本的优先级分别为 10、100 和 25,Sentinel 将会选择优先级为 10 的副本(即最低值)进行提升。

然而,优先级为 0 具有特殊含义,表示该副本不能担任主节点角色。因此,优先级为 0 的副本永远不会被 Redis Sentinel 选中晋升。

默认优先级为 100

replica-announced

@引入版本: 6.2.x

@配置语法

# replica-announced yes

@官方参考

默认情况下,Redis Sentinel 会将其管理的所有副本包含在报告中。可以将某个副本排除在 Redis Sentinel 的通告之外。被排除的副本将被 sentinel replicas <master> 命令忽略,并且不会暴露给 Redis Sentinel 的客户端。

此选项不会改变 replica-priority 的行为。即使将 replica-announced 设置为 'no',该副本仍然可以被提升为 master。若要阻止此行为,需将 replica-priority 设置为 0。

min-replicas-to-write and min-replicas-max-lag

@引入版本: 2.8.x

@配置语法

# @since: 2.8.x
# min-slaves-to-write 3
# min-slaves-max-lag 10

# @since: 5.0.x
# min-replicas-to-write 3
# min-replicas-max-lag 10

@官方参考

当连接的副本数量少于 N 个,且这些副本的延迟小于或等于 M 秒时,主节点可以停止接受写操作。

这里要求的 N 个副本必须处于“在线”状态。

延迟(以秒为单位)是根据从副本最后一次接收到的 PING 消息计算的,该 PING 消息通常每秒发送一次。

此选项并不能保证一定有 N 个副本成功接收写入,但它可以在可用副本不足的情况下,将可能丢失写操作的风险窗口限制在指定的秒数内。

例如,要求至少 3 个副本且延迟(lag) ≤ 10 秒,可使用如下配置:

# @since: 2.8.x
# min-slaves-to-write 3
# min-slaves-max-lag 10

# @since: 5.0.x
# min-replicas-to-write 3
# min-replicas-max-lag 10

将其中一个或两个参数设置为 0 将禁用此功能。

默认情况下,min-replicas-to-write 设置为 0(功能禁用),min-replicas-max-lag 设置为 10。

replica-announce-ip and replica-announce-port

@引入版本: 4.0.x

@配置语法

# @since: 4.0.x
# slave-announce-ip 5.5.5.5
# slave-announce-port 1234

# @since: 5.0.x
# replica-announce-ip 5.5.5.5
# replica-announce-port 1234

@官方参考

Redis 主节点能够以多种方式列出所连接副本的地址和端口。例如,“INFO replication”部分就提供了此信息,其他工具(包括 Redis Sentinel)会利用这些信息来发现副本实例。

另一个提供此信息的地方是主节点执行“ROLE”命令的输出结果中。

副本通常报告的 IP 地址和端口通过以下方式获得:

  • IP: 通过检查副本用于连接主节点的套接字的对等地址,自动检测得到。
  • Port: 在复制握手期间由副本向主节点声明,通常就是副本用于监听连接的端口。

然而,当使用端口转发或网络地址转换(NAT)时,副本实际上可能通过不同的 IP 地址和端口组合才能访问。副本可以使用以下两个选项,向其主节点报告特定的 IP 和端口,从而使“INFO”和“ROLE”命令返回这些指定的值。

如果只需要覆盖端口或 IP 地址其中之一,则无需同时使用这两个选项。

KEYS TRACKING

tracking-table-max-keys

@引入版本: 6.0.x

@配置语法

# tracking-table-max-keys 1000000

@官方参考

Redis 实现了服务端辅助的客户端缓存功能。该功能通过一个失效表(invalidation table)来实现,该表使用以键名作为索引的基数树(radix tree),记录哪些客户端缓存了哪些键,进而用于向客户端发送键失效消息。请参考以下页面以了解更多该功能的细节:

https://redis.io/topics/client-side-caching

当客户端启用了键跟踪(tracking)功能后,所有只读查询都被视为已缓存,这会促使 Redis 在失效表中存储相关信息。当键被修改时,这些信息会被清除,并向相关客户端发送失效消息。然而,如果工作负载以读操作为主,Redis 可能会消耗越来越多的内存来跟踪大量客户端所访问的键。

因此,可以配置失效表的最大容量。默认值为 100 万个键。一旦达到此限制,Redis 将开始淘汰失效表中的键,即使这些键本身未被修改,目的只是为了回收内存;这反过来会强制客户端将其缓存中对应的数据标记为失效。本质上,该表的最大大小是在服务端用于跟踪缓存状态的内存开销与客户端保持缓存对象的能力之间的一种权衡。

如果将此值设置为 0,表示无限制,Redis 将根据需要在失效表中保留任意数量的键。在 INFO 命令的 "stats" 部分,你可以随时查看当前失效表中包含的键的数量。

Note: 当键跟踪使用广播(broadcasting)模式时,服务端不使用内存来维护失效表,因此此设置无效。

SECURITY

user acl

@引入版本: 6.0.x

@配置语法

#   user <username> ... acl rules ...

@官方参考

Warning: 由于 Redis 非常快速,外部用户在现代服务器上每秒可尝试多达 100 万个密码。这意味着你应该使用非常强的密码,否则密码将很容易被破解。

请注意,由于密码实际上是客户端与服务器之间的共享密钥,并且不应由任何人记忆,因此密码可以是来自 /dev/urandom 或其他来源的长字符串。通过使用长且不可猜测的密码,可以有效防止暴力破解攻击。

Redis ACL 用户的定义格式如下:

#   user <username> ... acl rules ...

例如:

#   user worker +@list +@connection ~jobs:* on >ffa9203c493aa99

特殊用户名 "default" 用于新建立的连接。如果该用户设置了 "nopass" 规则,则新连接将立即以 "default" 用户身份通过认证,无需通过 AUTH 命令提供任何密码。否则,如果 "default" 用户未设置 "nopass" 标志,则连接将以未认证状态开始,必须通过 AUTH 命令(或 HELLO 命令的 AUTH 选项)进行认证后才能正常使用。

描述用户权限的 ACL 规则如下:

  • on: 启用该用户:可以以此用户身份进行认证。
  • off: 禁用该用户:不再允许使用此用户进行认证,但已通过认证的连接仍可继续工作。
  • skip-sanitize-payload: 跳过对 RESTORE 命令 dump 载荷的完整性检查。
  • sanitize-payload: 对 RESTORE 命令的 dump 载荷进行完整性检查(默认行为)。
  • +<command>: 允许执行指定命令。
  • -<command>: 禁止执行指定命令。
  • +@<category>: 允许执行指定类别中的所有命令。有效类别包括 @admin@set@sortedset 等,完整列表可参考 server.c 文件中对 Redis 命令表的定义。特殊类别 @all 表示服务器当前存在以及未来通过模块加载的所有命令。
  • +<command>|subcommand: 允许执行某个已被禁用命令的特定子命令。注意,此形式仅支持以 + 开头的添加操作,不支持以 - 开头的删除操作(例如 -DEBUG|SEGFAULT 是不允许的)。
  • allcommands: 等同于 +@all。注意,这意味着用户可以执行当前以及未来通过模块系统加载的所有命令。
  • nocommands: 等同于 -@all
  • ~<pattern>: 添加一个键名模式,表示用户可在命令中引用符合该模式的键。例如 ~* 允许所有键。模式采用类似 KEYS 命令的 glob 风格通配符,可指定多个模式。
  • allkeys: 等同于 ~*。
  • resetkeys: 清空允许的键名模式列表。
  • &<pattern>: 添加一个 glob 风格的 Pub/Sub 频道模式,表示用户可访问符合该模式的频道。可指定多个频道模式。
  • allchannels: 等同于 &*。
  • resetchannels: 清空允许的频道模式列表。
  • ><password>: 将指定密码添加到该用户的有效密码列表中。例如 >mypass 会将 "mypass" 加入列表。此指令会清除 "nopass" 标志(见下文)。
  • <<password>: 从有效密码列表中移除指定密码。
  • nopass: 移除该用户的所有密码,并标记该用户无需密码:意味着任何密码均可通过此用户认证。若此指令用于 "default" 用户,则每个新连接将自动以 default 用户身份认证,无需显式执行 AUTH 命令。注意,"resetpass" 指令会清除此状态。
  • resetpass: 清空有效密码列表,并移除 "nopass" 状态。执行 "resetpass" 后,该用户不再有关联密码,必须添加密码(或后续设置为 "nopass")才能进行认证。
  • reset: 执行以下操作:resetpass、resetkeys、off、-@all。该用户将恢复到刚创建时的初始状态。

ACL 规则可以任意顺序指定:例如可以先写密码,再写标志或键模式。但请注意,添加和删除规则的处理顺序会影响最终结果。例如,考虑以下示例:

#   user alice on +@all -DEBUG ~* >somepassword

这将允许 "alice" 执行所有命令,除了 DEBUG 命令,因为 +@all 首先将所有命令添加到 alice 可用的命令集中,随后 DEBUG 被移除。但如果颠倒两条 ACL 规则的顺序,结果将不同:

#   user alice on -DEBUG +@all ~* >somepassword

此时,在 alice 的允许命令集中尚无任何命令时,DEBUG 就已被移除;之后才添加所有命令,因此用户最终可以执行所有命令。

本质上,ACL 规则是从左到右依次处理的。

有关 ACL 配置的更多信息,请参考 Redis 官方网站:https://redis.io/topics/acl

acllog-max-len

@引入版本: 6.0.x

@配置语法

acllog-max-len 128

@官方参考

ACL 日志用于记录与 ACL 相关的命令执行失败和认证事件。ACL 日志有助于排查被 ACL 阻止的失败命令问题。ACL 日志存储在内存中,可通过 ACL LOG RESET 命令释放内存。请在下方定义 ACL 日志的最大条目长度。

aclfile

@引入版本: 6.0.x

@配置语法

# aclfile /etc/redis/users.acl

@官方参考

使用外部 ACL 文件除了在本文件中配置用户外,还可以使用一个独立的文件来专门列出用户。

这两种方法不能混合使用:

  • 如果你在此处配置了用户,同时又启用了外部 ACL 文件,服务器将拒绝启动。
  • 外部 ACL 用户文件的格式与 redis.conf 文件中描述用户的格式完全相同。

requirepass

@引入版本: 1.x

@配置语法

# requirepass foobared

@官方参考

IMPORTANT NOTE: 从 Redis 6 开始,“requirepass” 只是新 ACL 系统之上的一层兼容机制。该选项的作用等同于为默认用户(default user)设置密码。客户端仍然可以像以往一样使用 AUTH <password> 进行认证,或者根据新协议更明确地使用 AUTH default <password> 进行认证:两种方式都有效。

Warning

requirepassaclfile 选项以及 ACL LOAD 命令不兼容,如果使用了这些功能,requirepass 将被忽略。

acl-pubsub-default

@引入版本: 6.2.x

@配置语法

# acl-pubsub-default resetchannels

@官方参考

默认情况下,新用户会通过等效于以下 ACL 规则的方式初始化,具有严格的权限限制:off resetkeys -@all。从 Redis 6.2 开始,也可以使用 ACL 规则来管理对 Pub/Sub 频道的访问权限。新用户的默认 Pub/Sub 频道权限由 acl-pubsub-default 配置指令控制,该指令可接受以下值之一:

  • allchannels:授予访问所有 Pub/Sub 频道的权限
  • resetchannels:撤销访问所有 Pub/Sub 频道的权限

为了在升级到 Redis 6.0 时确保向后兼容,acl-pubsub-default 的默认值设置为 allchannels。

未来兼容性说明:在未来的 Redis 版本中,该指令的默认值很可能会从 allchannels 更改为 resetchannels,以便在开箱即用的情况下提供更好的 Pub/Sub 安全性。因此,建议你为所有用户显式定义 Pub/Sub 权限,而不是依赖隐式的默认值。在为所有现有用户设置了明确的 Pub/Sub 权限后,你应该取消注释下一行(配置)。

rename-command

@引入版本: 2.2.x

@已弃用: 6.0.x

@配置语法

# rename-command CONFIG ""

@官方参考

WARNING: 请尽量避免使用此选项。建议改为使用 ACL 机制,将危险命令从默认用户中移除,并仅将其赋予为管理目的而创建的特定管理员用户。

在共享环境中,可以更改危险命令的名称。例如,可以将 CONFIG 命令重命名为一个难以猜测的名称,使其仍可用于内部管理工具,但普通客户端无法轻易使用。

示例:

# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

It is also possible to completely kill a command by renaming it into an empty string:

也可以通过将命令重命名为空字符串来完全禁用该命令:

# rename-command CONFIG ""

请注意,更改那些会被记录到 AOF 文件或传输给副本的命令名称,可能会导致问题。

CLIENTS

maxclients

@引入版本: 1.x

@配置语法

# maxclients 10000

@官方参考

设置同时连接的客户端最大数量。默认情况下,此限制为 10000 个客户端。但如果 Redis 服务器无法将进程的文件描述符限制配置为达到指定值,则允许的最大客户端数量将设置为当前文件描述符限制减去 32(因为 Redis 会为内部用途预留一些文件描述符)。

一旦达到此限制,Redis 将拒绝所有新连接,并返回错误信息:“max number of clients reached”(已达到客户端最大连接数)。

IMPORTANT: 当使用 Redis 集群时,最大连接数限制也与集群总线共享:集群中的每个节点会使用两个连接(一个入站连接和一个出站连接)。因此,在构建大规模集群时,务必相应地调整该限制的大小。

MEMORY MANAGEMENT

maxmemory

@引入版本: 1.x

@配置语法

# maxmemory <bytes>

@官方参考

设置内存使用量上限为指定的字节数。当内存使用达到该限制时,Redis 会根据所选的驱逐策略(参见 maxmemory-policy)尝试删除键。

如果 Redis 无法根据策略删除键,或者策略被设置为 'noeviction',Redis 将开始对那些会消耗更多内存的命令(如 SETLPUSH 等)返回错误,但仍会继续处理只读命令(如 GET)。

此选项通常在将 Redis 用作 LRU 或 LFU 缓存时,或为实例设置硬性内存限制时(使用 'noeviction' 策略)非常有用。

WARNING: 如果你在启用了 maxmemory 的实例上连接了副本,用于向副本传输数据的输出缓冲区大小将从已用内存的统计中扣除。这样可以避免在网络问题或全量重同步时触发一个循环:即键被驱逐 → 副本的输出缓冲区充满被删除键的 DEL 命令 → 导致更多键被删除 → 如此往复,直至数据库被完全清空。

简而言之……如果你连接了副本,建议将 maxmemory 设置得更低一些,以便系统中留出部分空闲内存供副本输出缓冲区使用(但如果驱逐策略为 'noeviction',则无需这样做)。

maxmemory-policy

@引入版本: 2.2.x

@配置语法

# maxmemory-policy noeviction
  • LRU:表示最近最少使用(Least Recently Used)。
  • LFU:表示最不经常使用(Least Frequently Used)
  • LRULFUvolatile-ttl 都是通过近似的随机化算法实现的。

MAXMEMORY POLICY: how Redis will select what to remove when maxmemory is reached. You can select one from the following behaviors:

MAXMEMORY 策略:当达到最大内存限制时,Redis 将根据该策略决定删除哪些数据。可从以下行为中选择一种:

  • volatile-lru: 使用近似 LRU 算法进行驱逐,但仅针对设置了过期时间的键。
  • allkeys-lru: 使用近似 LRU 算法驱逐任意键。
  • volatile-lfu: 使用近似 LFU 算法进行驱逐,但仅针对设置了过期时间的键。
  • allkeys-lfu: 使用近似 LFU 算法驱逐任意键。
  • volatile-random: 随机删除一个设置了过期时间的键。
  • allkeys-random: 随机删除任意一个键。
  • volatile-ttl: 删除剩余生存时间(TTL)最短的键(即最快过期的键)。
  • noeviction: 默认,不驱逐任何数据,仅在执行写操作时返回错误。

@官方参考

在使用上述任何一种策略时,如果当前没有合适的键可以驱逐,Redis 将对需要更多内存的写操作返回错误。这类操作通常包括创建新键、添加数据或修改现有键的命令。一些常见的例子有:SETINCRHSETLPUSHSUNIONSTORESORT(由于包含 STORE 参数),以及 EXEC(如果事务中包含任何需要内存的命令)。

maxmemory-samples

@引入版本: 2.2.x

@配置语法

# maxmemory-samples 5

@官方参考

LRULFU 和最小 TTL 算法并非精确算法,而是近似算法(目的是节省内存),因此你可以在速度和准确性之间进行调整。默认情况下,Redis 会检查 5 个键,并选择其中最近最少使用的那个。你可以通过以下配置指令调整采样大小。

默认值 5 已能提供足够好的效果。设置为 10 可以非常接近真正的 LRU 效果,但会消耗更多 CPU 资源。设置为 3 则速度更快,但准确性较低。

maxmemory-eviction-tenacity

@引入版本: 6.2.x

@配置语法

# maxmemory-eviction-tenacity 10

@官方参考

驱逐处理机制的设计适用于默认设置。如果写入流量异常巨大,可能需要增加此值。降低此值可能会减少延迟,但会影响驱逐处理的有效性。0 = 最小延迟,10 = 默认值,100 = 不考虑延迟,优先处理驱逐。

replica-ignore-maxmemory

@引入版本: 5.0.x

@配置语法

# replica-ignore-maxmemory yes

@官方参考

从 Redis 5 开始,默认情况下,副本将忽略其自身的 maxmemory 设置(除非在故障转移后被提升为 master,或被手动提升)。这意味着键的驱逐将仅由主节点处理,当主节点侧的键被驱逐时,会向副本发送 DEL 命令。

此行为确保了主节点和副本之间数据的一致性,通常也是用户所期望的。然而,如果你的副本是可写的,或者你希望副本具有不同的内存设置,并且你确定所有对副本的写入操作都是幂等的(idempotent),那么你可以更改此默认行为(但请务必清楚自己在做什么)。

请注意,由于副本默认不执行键驱逐,它最终可能使用的内存超过通过 maxmemory 设置的限制(例如,某些缓冲区在副本上可能更大,或某些数据结构有时会占用更多内存等)。因此,请确保监控你的副本,并保证它们有足够的内存,以确保在主节点达到配置的 maxmemory 限制之前,副本不会真正遭遇内存耗尽的情况。

active-expire-effort

@引入版本: 6.0.x

@配置语法

# active-expire-effort 1

@官方参考

Redis 通过两种方式回收过期的键:一种是在访问时发现键已过期而进行回收;另一种是在后台进行,称为“主动过期键清理”(active expire key)。系统会以渐进和交互的方式扫描键空间,寻找已过期的键进行回收,从而能够在短时间内释放那些已经过期且不会再被访问的键所占用的内存。

默认的过期键清理策略会尽量确保内存中已过期但仍未被删除的键不超过 10%,同时尽量避免占用超过 25% 的 CPU 资源,以减少对系统延迟的影响。然而,可以将默认设置为 "1" 的过期清理“努力程度”(effort)调高,最大可设置为 "10"。当该值达到最大时,系统将消耗更多的 CPU 资源,清理周期更长(理论上可能引入更高的延迟),但能容忍更少的过期键残留在内存中。这本质上是在内存占用、CPU 使用率和延迟之间的一种权衡。

LAZY FREEING

lazyfree * and replica-lazy-flush

@引入版本: 4.0.x

@配置语法

# @since: 4.0.x
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
slave-lazy-flush no

# @since: 5.0.x
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no

@官方参考

Redis 提供了两种删除键的基本机制。一种是 DEL,它会以阻塞方式同步删除对象。这意味着服务器会暂停处理新命令,以便立即回收与该对象关联的所有内存。如果被删除的键对应的是一个小型对象,执行 DEL 命令所需的时间非常短,与其他大多数 O(1) 或 O(log N) 复杂度的 Redis 命令相当。然而,如果该键对应的是一个包含数百万元素的聚合对象,服务器可能会阻塞较长时间(甚至数秒)才能完成该操作。

出于上述原因,Redis 还提供了非阻塞的删除机制,例如 UNLINK(非阻塞的 DEL)以及 FLUSHALLFLUSHDB 命令的 ASYNC 选项,这些机制可在后台异步回收内存。这些命令本身执行时间是恒定的,随后由另一个线程在后台尽可能快地逐步释放对象所占内存。

DELUNLINK 以及 FLUSHALLFLUSHDBASYNC 选项均由用户控制。应用程序的设计者需要自行判断在何种场景下使用哪种方式更为合适。然而,Redis 服务器有时也会因其他操作的副作用而需要删除键或清空整个数据库。具体来说,Redis 在以下场景中会独立于用户调用而自动删除对象:

  • 内存驱逐:由于 maxmemory 和 maxmemory-policy 的配置,为了为新数据腾出空间而不超过指定的内存限制。
  • 过期删除:当设置了生存时间(TTL)的键(参见 EXPIRE 命令)到达过期时间,需要从内存中删除。
  • 命令副作用:某些命令在向已存在的键写入数据时,会产生删除旧内容的副作用。例如,RENAME 命令在用新键替换旧键时,会删除旧键的内容;类似地,SUNIONSTORE 或带有 STORE 选项的 SORT 命令可能会删除已存在的键;SET 命令本身也会先移除指定键的旧内容,再用新字符串替换。
  • 复制过程:在复制过程中,当副本与主节点进行全量重同步时,会清空整个数据库的内容,以便加载刚刚传输过来的 RDB 文件。

在上述所有情况下,默认行为是以阻塞方式删除对象,就像调用了 DEL 一样。但你可以通过以下配置指令,分别为每种情况配置为以非阻塞方式释放内存(就像调用 UNLINK 一样)。

lazyfree-lazy-user-del

@引入版本: 6.0.x

@配置语法

lazyfree-lazy-user-del no

@官方参考

此外,当难以将用户代码中的 DEL 调用替换为 UNLINK 调用时,还可以通过以下配置指令修改 DEL 命令的默认行为,使其表现完全与 UNLINK 相同:

lazyfree-lazy-user-del no

lazyfree-lazy-user-flush

@引入版本: 6.2.x

@配置语法

lazyfree-lazy-user-flush no

@官方参考

FLUSHDBFLUSHALLSCRIPT FLUSH 命令支持异步和同步删除,可以通过向这些命令传递 [SYNC|ASYNC] 标志来控制删除方式。当未传递任何标志时,将使用此配置指令来决定数据是否应异步删除。

lazyfree-lazy-user-flush no

THREADED I/O

io-threads

@引入版本: 6.0.x

@配置语法

# io-threads 4

@官方参考

Redis 主要是单线程的,但也有某些操作(如 UNLINK、慢速 I/O 访问等)会在独立的线程中执行。

现在,还可以使用不同的 I/O 线程来处理 Redis 客户端套接字的读写操作。由于写操作通常较慢,用户通常使用管道(pipelining)技术来提升单核性能,并通过启动多个 Redis 实例来实现横向扩展。而使用 I/O 线程,无需依赖管道化或实例分片,就能轻松将 Redis 性能提升约一倍。

默认情况下,线程功能是禁用的。我们建议仅在拥有至少 4 个或更多核心的机器上启用该功能,并至少保留一个核心空闲。使用超过 8 个线程通常不会带来显著收益。我们也建议仅在确实遇到性能瓶颈,且 Redis 实例能够占用较高 CPU 时间比例的情况下才使用 I/O 线程,否则没有必要启用此功能。

例如,如果你使用的是 4 核机器,可以尝试使用 2 或 3 个 I/O 线程;如果是 8 核机器,可以尝试使用 6 个线程。要启用 I/O 线程,请使用以下配置指令:

# io-threads 4

io-threads-do-reads

@引入版本: 6.0.x

@配置语法

# io-threads-do-reads no

@官方参考

io-threads 设置为 1 将仅使用主线程,与通常情况相同。当启用 I/O 线程后,我们目前仅对写操作使用线程,即将 write(2) 系统调用以及将客户端缓冲区数据传输到套接字的过程进行线程化处理。但是,也可以通过将以下配置指令设置为 yes,来启用对读操作和协议解析的线程化处理:

# io-threads-do-reads no

通常,对读取操作进行线程化处理带来的性能提升并不明显。

  • 注意 1:此配置指令无法通过 CONFIG SET 在运行时动态更改。此外,当前在启用 SSL 时,此功能无法正常工作。

  • 注意 2:如果你想使用 redis-benchmark 测试 Redis 的性能提升,请确保你也以线程模式运行基准测试工具,使用 --threads 选项使其线程数与 Redis 的线程数相匹配,否则你将无法观察到性能改善。

KERNEL OOM CONTROL

oom-score-adj

@引入版本: 6.2.x

@配置语法

oom-score-adj no

@可选项

  • no: 默认,不对 oom-score-adj 进行任何修改。
  • yes: 等同于 "relative",见下文。
  • absolute: 将 oom-score-adj-values 中的值原样写入内核。
  • relative: 相对于服务器启动时 oom_score_adj 的初始值进行设置,然后将其限制在 -1000 到 1000 的范围内。由于初始值通常为 0,因此这些值往往与绝对值相同。

@官方参考

在 Linux 系统中,可以向内核的 OOM killer(内存不足时的进程终止机制)提供提示,指明在内存耗尽时应优先终止哪些进程。

启用此功能后,Redis 会根据其各个进程的角色,主动控制它们的 oom_score_adj 值。默认的评分策略旨在让后台子进程优先于其他进程被终止,而副本(replica)进程则优先于主节点(master)进程被终止。

oom-score-adj-values

@引入版本: 6.2.x

@配置语法

oom-score-adj-values 0 200 800

@官方参考

当启用 oom-score-adj 时,此指令用于控制主节点、副本以及后台子进程所使用的具体值。取值范围为 -2000 到 2000(数值越高,越可能被 OOM killer 选中终止)。

非特权进程(非 root 用户,且不具备 CAP_SYS_RESOURCE 能力)可以自由增加自身的 oom_score_adj 值,但不能将其降低到低于初始值。这意味着,将 oom-score-adj 设置为 "relative" 模式,并将 oom-score-adj-values 设为正值,将始终能够成功设置。

KERNEL transparent hugepage CONTROL

disable-thp

@引入版本: 6.2.x

@配置语法

disable-thp yes

@官方参考

通常情况下,内核的透明大页(Transparent Huge Pages)设置默认为 "madvise" 或 "never"(位于 /sys/kernel/mm/transparent_hugepage/enabled),此时该配置项无效。在某些系统上,如果该设置被设为 "always",Redis 会尝试专门为 Redis 进程禁用此功能,以避免在调用 fork(2) 和写时复制(CoW)过程中产生延迟问题。如果由于某些原因你希望保持该功能启用,可以将此配置项设为 "no",并将内核全局设置保留为 "always"。

APPEND ONLY MODE

appendonly

@引入版本: 1.x

@配置语法

appendonly no

@官方参考

默认情况下,Redis 会异步地将数据集转储到磁盘。这种模式在许多应用中已经足够好,但如果 Redis 进程出现问题或发生断电,可能会导致几分钟的写入数据丢失(具体取决于配置的保存点)。

Append Only File(AOF,仅追加文件)是另一种持久化模式,提供了更好的数据持久性。例如,使用默认的 fsync 数据策略(见配置文件后面的设置),在服务器突然断电等极端情况下,Redis 最多只会丢失一秒的写入数据;如果只是 Redis 进程本身出现问题而操作系统仍正常运行,则可能只丢失一次写入。

AOF 和 RDB 持久化可以同时启用而不会产生问题。如果启动时启用了 AOF,Redis 将优先加载 AOF 文件,因为该文件具有更强的数据持久性保证。

更多信息请参阅:https://redis.io/topics/persistence

appendfilename

@引入版本: 1.x

@配置语法

appendfilename "appendonly.aof"

@官方参考

仅追加文件的名称(默认值:“appendonly.aof”)。

appendfsync

@引入版本: 1.x

@配置语法

# appendfsync always
  appendfsync everysec
# appendfsync no

@可选项

  • no: 不进行 fsync,仅让操作系统在其认为合适的时候刷新数据。速度最快。
  • always: 每次向 AOF(仅追加文件)写入后都执行 fsync。速度最慢,但最安全。
  • everysec: 每秒执行一次 fsync。在速度和安全性之间的一种折中方案。

@官方参考

fsync()系统调用会通知操作系统立即将数据写入磁盘,而不是继续在输出缓冲区中等待更多数据。不同的操作系统对此调用的处理方式不同:一些系统会真正将数据刷新到磁盘,而另一些系统则只是尽快尝试执行。

默认设置为 "everysec"(每秒一次),因为在速度和数据安全之间,这通常是一个合适的折中方案。你需要自行判断是否可以将其放宽为 "no",该选项会让操作系统自行决定何时刷新输出缓冲区,从而获得更好的性能(但如果你能接受一定程度的数据丢失,也可以考虑使用默认的快照持久化模式);或者相反,选择 "always"(每次写入都同步),虽然速度非常慢,但比 "everysec" 更安全一些。

更多详细信息,请参考以下文章:http://antirez.com/post/redis-persistence-demystified.html。如果不确定,建议使用 "everysec"。

no-appendfsync-on-rewrite

@引入版本: 2.2.x

@配置语法

no-appendfsync-on-rewrite no

@官方参考

当 AOF 的 fsync 策略设置为 alwayseverysec 时,如果后台保存进程(如执行 BGSAVE 或 AOF 日志后台重写)正在进行大量的磁盘 I/O 操作,在某些 Linux 配置下,Redis 主进程可能会在 fsync() 调用上阻塞过长时间。请注意,目前对此问题尚无根本性解决方案,因为即使在另一个线程中执行 fsync,也会阻塞主线程的同步 write(2) 调用。

为了缓解此问题,可以启用以下选项。该选项会在 BGSAVEBGREWRITEAOF 执行期间,阻止主进程调用 fsync()。

这意味着,当有其他子进程正在进行保存操作时,Redis 的数据持久性等同于 appendfsync none。实际影响是,在最坏的情况下(基于默认的 Linux 设置),你可能丢失最多 30 秒的 AOF 日志。

如果你遇到延迟问题,可以将此选项设置为 "yes"。否则,建议保持为 "no",因为从数据持久性的角度来看,这是最安全的选择。

auto-aof-rewrite-percentage and auto-aof-rewrite-min-size

@引入版本: 2.4.x

@配置语法

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

@官方参考

自动重写仅追加文件(AOF)。当 AOF 日志文件的大小增长超过指定的百分比时,Redis 能够自动隐式调用 BGREWRITEAOF 来重写日志文件。

其工作原理如下:Redis 会记住最近一次重写后 AOF 文件的大小(如果自重启以来尚未进行过重写,则使用启动时的 AOF 文件大小)。

这个基础大小会与当前大小进行比较。如果当前大小比基础大小增长了超过指定的百分比,就会触发重写操作。此外,你还需要指定 AOF 文件重写的最小大小,这有助于避免在文件增长百分比达到要求但文件本身仍然很小时进行不必要的重写。

将百分比设置为零可以禁用 AOF 文件的自动重写功能。

aof-load-truncated

@引入版本: 3.0.x

@配置语法

aof-load-truncated yes

@官方参考

在 Redis 启动过程中,当 AOF 数据被重新加载到内存时,可能会发现 AOF 文件在末尾被截断。这种情况通常发生在 Redis 运行的系统发生崩溃时,尤其是在 ext4 文件系统未使用 data=ordered 选项挂载的情况下(不过,如果仅仅是 Redis 自身崩溃或中止,而操作系统仍正常运行,则不会发生此问题)。

当发生这种情况时,Redis 可以选择以错误退出,或者尽可能多地加载数据(当前默认行为)并在发现 AOF 文件末尾被截断时继续启动。以下选项用于控制此行为。

如果 aof-load-truncated 设置为 yes,则会加载被截断的 AOF 文件,Redis 服务器启动并发出日志通知用户该事件。反之,如果该选项设置为 no,服务器将中止并报错,拒绝启动。当此选项设置为 no 时,用户需要先使用 redis-check-aof 工具修复 AOF 文件,然后才能重新启动服务器。

请注意,如果 AOF 文件在中间部分被发现损坏,服务器仍将报错退出。此选项仅适用于 Redis 尝试从 AOF 文件读取更多数据但未能找到足够字节的情况(即文件末尾被截断)。

aof-use-rdb-preamble

@引入版本: 4.0.x

@配置语法

aof-use-rdb-preamble yes

@官方参考

在重写 AOF 文件时,Redis 能够在 AOF 文件中使用 RDB 前导码(preamble),以实现更快的重写和恢复。当此选项开启后,重写后的 AOF 文件将由两个不同的部分组成:

# [RDB file][AOF tail]

在加载时,Redis 会识别到 AOF 文件以 "REDIS" 字符串开头,于是先加载前面的 RDB 文件部分,然后再继续加载后续的 AOF 尾部数据。

LUA SCRIPTING

lua-time-limit

@引入版本: 2.6.x

@配置语法

lua-time-limit 5000

@官方参考

Lua 脚本的最大执行时间(以毫秒为单位)。

当脚本执行时间达到此限制时,Redis 会记录一条日志,提示脚本仍在执行且已超过允许的最大时间,并开始对后续的查询请求返回错误。

当一个长时间运行的脚本超过最大执行时间后,只有 SCRIPT KILLSHUTDOWN NOSAVE 命令可用。SCRIPT KILL 可用于停止尚未执行任何写命令的脚本;而如果脚本已经执行了写命令,但用户又不希望等待脚本自然结束,那么 SHUTDOWN NOSAVE 是唯一能够关闭服务器的方法。

将此值设置为 0 或负数,表示不限制执行时间,且不会产生警告。

REDIS CLUSTER

cluster-enabled

@引入版本: 3.0.x

@配置语法

# cluster-enabled yes

@官方参考

普通的 Redis 实例不能成为 Redis 集群的一部分;只有以集群节点模式启动的节点才可以。要将 Redis 实例作为集群节点启动,需通过取消注释以下配置来启用集群支持:

# cluster-enabled yes

cluster-config-file

@引入版本: 3.0.x

@配置语法

# cluster-config-file nodes-6379.conf

@官方参考

每个集群节点都有一个集群配置文件。该文件不打算由人工手动编辑,而是由 Redis 节点创建和更新。每个 Redis 集群节点都需要一个不同的集群配置文件。请确保在同一系统中运行的实例不使用重叠或相同的集群配置文件名。

cluster-node-timeout

@引入版本: 3.0.x

@配置语法

# cluster-node-timeout 15000

@官方参考

集群节点超时时间是指一个节点被认为处于故障状态之前,必须不可达的毫秒数。大多数其他内部时间限制都是节点超时时间的倍数。

cluster-replica-validity-factor

@引入版本: 3.0.x

@配置语法

# @since: 3.0.x
# cluster-slave-validity-factor 10

# @since: 5.0.x
# cluster-replica-validity-factor 10

@官方参考

当主节点发生故障时,其副本节点如果发现自己的数据过于陈旧,将避免启动故障转移。

副本节点实际上无法精确衡量其“数据的新旧程度”,因此会执行以下两项检查:

  • 基于复制偏移量的竞争机制:如果有多个副本具备故障转移能力,它们会相互交换消息,以尽可能让拥有最佳复制偏移量(即从主节点处理了更多数据)的副本获得优势。副本会根据其复制偏移量计算自己的优先级排名,并根据该排名在故障转移开始时引入一个相应的延迟。
  • 基于最后交互时间的检查:每个副本会计算其与主节点最后一次交互的时间。这可以是收到主节点最后一个 ping 或命令的时间(如果主节点仍处于“已连接”状态),也可以是与主节点断开连接后经过的时间(如果当前复制链路已中断)。如果最后一次交互时间过久,副本将完全不尝试进行故障转移。

上述第 2 点可以通过用户配置进行调整。具体来说,如果自上次与主节点交互以来,经过的时间超过了以下公式计算的值,副本将不会尝试故障转移:

# (node-timeout * cluster-replica-validity-factor) + repl-ping-replica-period

例如,如果 node-timeout 为 30 秒,cluster-replica-validity-factor 为 10,且 repl-ping-replica-period 的默认值为 10 秒,那么当副本与主节点失联时间超过 310 秒时,它将不会尝试故障转移。

cluster-replica-validity-factor 的值过大,可能导致数据过于陈旧的副本进行故障转移;而值过小,则可能完全阻止集群选出新的主节点。

为了实现最大可用性,可以将 cluster-replica-validity-factor 设置为 0。这意味着副本将始终尝试对主节点进行故障转移,无论其与主节点最后一次交互是什么时候(但它们仍会根据自身的偏移量排名尝试引入相应的延迟)。

0 是唯一能够保证在所有网络分区恢复后,集群始终能继续运行的值。

cluster-migration-barrier

@引入版本: 3.0.x

@配置语法

# cluster-migration-barrier 1

@官方参考

集群中的副本节点能够迁移到“孤儿主节点”(orphaned masters),即那些失去了所有正常工作的副本的主节点。这一机制提升了集群的抗故障能力,因为如果一个主节点没有可用的副本,一旦它发生故障,将无法进行故障转移。

副本只有在满足以下条件时才会迁移到孤儿主节点:其原始主节点仍然至少有指定数量的其他正常工作的副本。这个指定的数量被称为“迁移屏障”(migration barrier)。迁移屏障设置为 1 表示,只有当其主节点至少还有 1 个其他正常工作的副本时,该副本才会迁移;以此类推。这个值通常反映了你希望集群中每个主节点拥有的副本数量。

默认值为 1(即副本只有在迁移后其原始主节点至少仍保留一个副本时才会迁移)。要禁用此迁移功能,可以将其设置为一个非常大的值,或者将 cluster-allow-replica-migration 设置为 'no'。可以将值设为 0,但这仅对调试有用,在生产环境中使用非常危险。

cluster-allow-replica-migration

@引入版本: 6.2.x

@配置语法

# cluster-allow-replica-migration yes

@官方参考

关闭此选项可以减少集群的自动配置行为。它会同时禁用副本向“孤儿主节点”(无副本的主节点)的迁移,以及从已变为空(没有副本)的主节点上的副本迁移。

默认值为 'yes'(允许自动迁移)。

cluster-require-full-coverage

@引入版本: 3.0.x

@配置语法

# cluster-require-full-coverage yes

@官方参考

默认情况下,如果 Redis 集群节点检测到至少有一个哈希槽未被覆盖(即没有可用的节点在服务该槽),它们将停止接受查询。通过这种方式,当集群部分失效时(例如,一段哈希槽不再被覆盖),整个集群最终会变得不可用。一旦所有槽再次被覆盖,集群将自动恢复为可用状态。

然而,有时你希望集群中仍在正常工作的子集,能够继续接受针对已覆盖键空间部分的查询。为了实现这一点,只需将 cluster-require-full-coverage 选项设置为 no 即可。

cluster-replica-no-failover

@引入版本: 5.0.x

@配置语法

# cluster-replica-no-failover no

@官方参考

当此选项设置为 yes 时,会阻止副本在主节点发生故障时尝试进行故障转移。但仍然可以通过强制方式对副本执行手动故障转移。

此功能在多种场景下非常有用,尤其是在多数据中心(multi-DC)操作中。例如,我们希望某个数据中心(一侧)在没有发生整个数据中心完全失效的情况下,永远不会被提升为主节点。

cluster-allow-reads-when-down

@引入版本: 6.0.x

@配置语法

# cluster-allow-reads-when-down no

@官方参考

当此选项设置为 yes 时,即使集群处于不可用(down)状态,只要节点认为自己拥有相应的哈希槽,就允许其继续处理读取请求。

这在两种情况下非常有用。第一种情况是应用程序在节点故障或网络分区期间不要求数据一致性。一个典型的例子是缓存场景,只要节点本地保存了数据,就应该能够提供服务。

第二种使用场景是:集群配置尚未达到推荐的三个分片(shard),但希望先启用集群模式,并计划未来再进行扩展。在只有 1 个或 2 个分片的配置中,如果未设置此选项,主节点故障会导致整个集群的读写中断;而启用此选项后,将仅导致写操作中断,读操作仍可继续。需要注意的是,在没有主节点法定数量(quorum)的情况下,哈希槽的所有权不会自动变更。

# cluster-allow-reads-when-down no

要搭建你的集群,请务必阅读 https://redis.io 网站上的相关文档。

CLUSTER DOCKER/NAT support

cluster-announce

@引入版本: 4.0.x

@配置语法

# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-tls-port
# * cluster-announce-bus-port

@官方参考

在某些部署环境中,Redis 集群节点的地址发现会失败,原因可能是地址经过了网络地址转换(NAT),或者端口被转发了(典型的场景是 Docker 和其他容器环境)。

为了让 Redis 集群在这些环境中正常工作,需要一种静态配置,即每个节点都知道自己的公网地址。以下四个选项就是用于此目的:

# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-tls-port
# * cluster-announce-bus-port

这些选项用于向节点告知其自身地址、客户端端口(用于非 TLS 和 TLS 连接)以及集群消息总线端口。这些信息会被发布在总线数据包的头部,以便其他节点能够正确映射发布信息节点的地址。

如果 cluster-tls 设置为 yes,且 cluster-announce-tls-port 被省略或设置为 0,则 cluster-announce-port 指的是 TLS 端口。另外请注意,如果 cluster-tls 设置为 no,则 cluster-announce-tls-port 选项无效。

如果未使用上述选项,则将使用正常的 Redis 集群自动发现机制。

请注意,当端口被重新映射时,总线端口可能不再固定为客户端端口 + 10000 的偏移量。因此,你可以根据端口映射的具体情况,分别指定任意的客户端端口和总线端口。如果未设置总线端口,则仍会像往常一样使用 10000 的固定偏移量。

示例:

# cluster-announce-ip 10.1.1.5
# cluster-announce-tls-port 6379
# cluster-announce-port 0
# cluster-announce-bus-port 6380

SLOW LOG

slowlog-log-slower-than

@引入版本: 2.4.x

@配置语法

slowlog-log-slower-than 10000

@官方参考

Redis 慢查询日志(Slow Log)是一个用于记录执行时间超过指定阈值的查询的系统。这里的执行时间不包括与客户端通信、发送回复等 I/O 操作时间,而仅计算实际执行命令所需的时间(这是命令执行过程中唯一会阻塞线程、使其无法同时处理其他请求的阶段)。

你可以通过两个参数来配置慢查询日志:一个参数告诉 Redis,命令的执行时间(单位为微秒)超过多少时需要被记录;另一个参数是慢日志的长度。当有新的命令被记录时,队列中最旧的记录将被移除。

以下时间以微秒为单位,因此 1000000 等于一秒。请注意,负数会禁用慢查询日志,而设置为零则会强制记录每一个命令。

slowlog-max-len

@引入版本: 2.4.x

@配置语法

slowlog-max-len 128

@官方参考

对此长度没有限制,但请注意它会消耗内存。你可以通过使用 SLOWLOG RESET 命令来回收慢日志所占用的内存。

LATENCY MONITOR

latency-monitor-threshold

@引入版本: 3.0.x

@配置语法

latency-monitor-threshold 0

@官方参考

Redis 延迟监控子系统会在运行时对不同的操作进行采样,以收集与 Redis 实例可能的延迟来源相关的数据。

用户可以通过 LATENCY 命令获取这些信息,并生成图表或获取报告。

该系统仅记录执行时间大于或等于通过 latency-monitor-threshold 配置指令指定的毫秒数的操作。当该值设置为零时,延迟监控功能将被关闭。

默认情况下,延迟监控是禁用的,因为如果你没有遇到延迟问题,通常并不需要此功能。虽然数据收集带来的性能影响非常小,但在高负载下仍可被测量到。如果需要,可以在运行时使用命令 "CONFIG SET latency-monitor-threshold <毫秒数>" 轻松启用延迟监控。

EVENT NOTIFICATION

PUBLISH

@引入版本: 2.8.x

@配置语法

# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo

@官方参考

Redis 可以通过发布/订阅(Pub/Sub)机制向客户端发送键空间(key space)内发生的事件通知。此功能的详细说明请参见:https://redis.io/topics/notifications

例如,如果启用了键空间事件通知,当一个客户端在数据库 0 中对键 "foo" 执行 DEL 操作时,将通过 Pub/Sub 发布两条消息:

# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo

notify-keyspace-events

@引入版本: 2.8.x

@配置语法

# notify-keyspace-events Elg
# notify-keyspace-events Ex

# default:
notify-keyspace-events ""

@官方参考

可以在一系列类别中选择 Redis 将要通知的事件。每个类别由一个单独的字符标识:

#  K     Keyspace events, published with __keyspace@<db>__ prefix.
#  E     Keyevent events, published with __keyevent@<db>__ prefix.
#  g     Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
#  $     String commands
#  l     List commands
#  s     Set commands
#  h     Hash commands
#  z     Sorted set commands
#  x     Expired events (events generated every time a key expires)
#  e     Evicted events (events generated when a key is evicted for maxmemory)
#  t     Stream commands
#  d     Module key type events
#  m     Key-miss events (Note: It is not included in the 'A' class)
#  A     Alias for g$lshzxetd, so that the "AKE" string means all the events
#        (Except key-miss events which are excluded from 'A' due to their
#         unique nature).

notify-keyspace-events 配置项接受一个由零个或多个字符组成的字符串作为参数。空字符串表示禁用所有通知。

示例:若要从事件名称的角度启用列表(List)事件和通用(Generic)事件,请使用:

# notify-keyspace-events Elg

示例 2:若要通过订阅频道 __keyevent@0__:expired 来获取过期键的事件流,请使用:

#  notify-keyspace-events Ex

默认情况下,所有通知都是禁用的,因为大多数用户并不需要此功能,而且该功能会带来一定的性能开销。请注意,如果你没有至少指定 K 或 E 中的任意一个,将不会有任何事件被发送。

notify-keyspace-events ""

GOPHER SERVER

gopher-enabled

@引入版本: 6.0.x

@配置语法

# gopher-enabled no

@官方参考

Redis 实现了 Gopher 协议,符合 RFC 1436 规范(https://www.ietf.org/rfc/rfc1436.txt)。

Gopher 协议在 20 世纪 90 年代末曾非常流行,它是一种替代万维网的协议,其服务端和客户端的实现都非常简单。为此,Redis 服务器仅用约 100 行代码就实现了对 Gopher 的支持。

如今使用 Gopher 能做什么?实际上,Gopher 从未真正“消亡”。最近,有一股复兴 Gopher 的潮流,希望重新唤起这种以纯文本文档构成的、层级分明的内容体系。一些人向往更简单的互联网,另一些人则认为主流互联网已被过度控制,因此创建一个另类空间,为渴望清新空气的人们提供选择,显得很有意义。

无论如何,在 Redis 十周年之际,我们以支持 Gopher 协议作为一份礼物。

--- 它如何工作? --- Redis 的 Gopher 支持使用 Redis 的内联协议(inline protocol),特别是两种原本非法的内联请求:空请求,或以 "/" 开头的任何请求(Redis 没有任何命令是以斜杠开头的)。正常的 RESP2/RESP3 请求完全不受 Gopher 协议实现的影响,仍按常规方式处理。

当你在启用 Gopher 的情况下连接到 Redis,并发送类似 "/foo" 的字符串时,如果存在一个名为 "/foo" 的键,其内容将通过 Gopher 协议提供服务。

要创建一个真正的 Gopher “洞穴”(Gopher 术语中对 Gopher 站点的称呼),你可能需要一个类似以下的脚本: https://github.com/antirez/gopher2redis

--- 安全警告 --- 如果你计划将 Redis 部署在互联网上的公开可访问地址以提供 Gopher 页面,请务必为实例设置密码。一旦设置了密码:

  1. Gopher 服务器(在启用时,非默认)仍可通过 Gopher 协议提供内容。
  2. 但在客户端完成身份验证之前,无法调用其他 Redis 命令。

因此,请使用 requirepass 选项来保护你的实例。

请注意,当启用 io-threads-do-reads 时,目前不支持 Gopher 协议。

要启用 Gopher 支持,请取消注释以下行,并将选项从默认的 no 改为 yes

# gopher-enabled no

ADVANCED CONFIG

hash-max-ziplist-entries and hash-max-ziplist-value

@引入版本: 2.2.x

@配置语法

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

@官方参考

当哈希(Hashes)包含的条目数量较少,并且最大的条目不超过指定阈值时,Redis 会使用一种内存高效的结构对其进行编码。这些阈值可以通过以下指令进行配置。

list-max-ziplist-size

@引入版本: 2.2.x

@配置语法

list-max-ziplist-size -2

@官方参考

列表(Lists)也采用一种特殊方式编码,以节省大量内存空间。每个内部列表节点允许的条目数量可以设置为固定的大小上限或最大元素数量。对于固定的大小上限,可使用 -5 到 -1 的数值,其含义如下:

# -5: max size: 64 Kb  <-- 不推荐用于常规工作负载
# -4: max size: 32 Kb  <-- 不推荐
# -3: max size: 16 Kb  <-- 可能也不推荐
# -2: max size: 8 Kb   <-- 推荐
# -1: max size: 4 Kb   <-- 推荐

正数表示每个列表节点最多存储 _exactly_ 的该数量元素。通常性能最高的选项是 -2(8 KB 大小)或 -1(4 KB 大小),但如果您的使用场景特殊,可根据需要调整这些设置。

list-compress-depth

@引入版本: 3.x.x

@配置语法

list-compress-depth 0

@官方参考

列表也可以进行压缩。压缩深度(compress depth)表示从列表的每一端(头和尾)起,从外向内数多少个 quicklistziplist 节点不进行压缩。列表的头部和尾部节点始终保持未压缩状态,以确保 PUSH/POP 等操作的快速执行。

具体设置如下:

  • 0:禁用所有列表压缩。
  • 1:深度 1 表示“从头部或尾部开始,前 1 个节点之后才开始压缩”。例如:[head]->node->node->...->node->[tail]。其中 [head] 和 [tail] 始终不压缩,中间的节点将被压缩。
  • 2:[head]->[next]->node->node->...->node->[prev]->[tail]。这里的 2 表示:头部、头部的下一个节点、尾部的上一个节点以及尾部这四个节点不压缩,它们之间的所有节点都将被压缩。
  • 3:[head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail],以此类推。

数值越大,从两端保留不压缩的节点越多。

set-max-intset-entries

@引入版本: 2.2.x

@配置语法

set-max-intset-entries 512

@官方参考

集合(Sets)只在一种特殊情况下会使用特殊编码:当集合中的所有元素都是恰好能表示为十进制的 64 位有符号整数范围内的字符串时。以下配置项用于设置使用这种特殊内存节省编码的集合大小上限。

zset-max-ziplist-entries and zset-max-ziplist-value

@引入版本: 2.4.x

@配置语法

zset-max-ziplist-entries 128
zset-max-ziplist-value 64

@官方参考

与哈希(hashes)和列表(lists)类似,有序集合(sorted sets)也采用特殊编码方式以节省大量内存空间。仅当有序集合的长度和元素大小同时低于以下限制时,才会使用这种特殊编码:

zset-max-ziplist-entries 128
zset-max-ziplist-value 64

hll-sparse-max-bytes

@引入版本: 3.0.x

@配置语法

hll-sparse-max-bytes 3000

@官方参考

HyperLogLog 稀疏表示的字节限制。该限制包含 16 字节的头部信息。当使用稀疏表示的 HyperLogLog 超过此字节限制时,它将被转换为密集表示。

大于 16000 的值完全无用,因为在达到该点时,密集表示的内存效率更高。

建议设置为约 3000,这样可以在享受稀疏编码节省空间优势的同时,避免 PFADD 命令(在稀疏编码下时间复杂度为 O(N))变得过慢。当 CPU 性能不是问题,而更关注内存空间,并且数据集中包含大量基数在 0 到 15000 范围内的 HyperLogLog 时,可将该值提高到约 10000。

stream-node-max-bytes and stream-node-max-entries

@引入版本: 5.0.x

@配置语法

stream-node-max-bytes 4096
stream-node-max-entries 100

@官方参考

流(Streams)宏观节点的最大大小/项目数。流数据结构是一种由大型节点构成的基数树(radix tree),每个节点内部可编码多个项目。通过此配置,可以设置单个节点的最大字节数,以及在追加新的流条目时,节点在切换到新节点前最多可包含的项目数量。如果以下任一设置为零,则忽略该限制。例如,可以通过将 max-bytes 设为 0,max-entries 设为期望值,来仅设置最大条目数限制。

activerehashing

@引入版本: 2.2.x

@配置语法

activerehashing yes

@官方参考

主动重新哈希(Active rehashing)会每 100 毫秒从 CPU 时间中抽取 1 毫秒,用于帮助重新哈希 Redis 的主哈希表(即用于映射顶级键到值的哈希表)。Redis 使用的哈希表实现(见 dict.c)采用惰性重新哈希机制:在重新哈希过程中,对哈希表执行的操作越多,完成的“步数”就越多。因此,如果服务器处于空闲状态,重新哈希将永远不会完成,哈希表会持续占用额外的内存。

默认情况下,每秒使用该 1 毫秒时间片 10 次(即每 100 毫秒执行一次),以主动对主字典进行重新哈希,从而在可能的情况下尽快释放内存。

如果不确定如何设置:

  • 如果你的应用场景对延迟要求非常严格,不希望 Redis 偶尔因重新哈希而使查询响应延迟 2 毫秒左右,那么请使用 "activerehashing no"。
  • 如果你没有如此严格的延迟要求,并希望尽可能快地释放内存,那么请使用 "activerehashing yes"。

client-output-buffer-limit

@引入版本: 2.8.x

@配置语法

# @since: 2.8.x
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

# @since: 6.x
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60

@官方参考

客户端输出缓冲区限制可用于强制断开那些由于某种原因未能及时从服务器读取数据的客户端连接(一个常见原因是,发布/订阅客户端无法像发布者产生消息那样快速地消费消息)。

该限制可以为三类不同的客户端分别设置:

  • normal -> 普通客户端,包括 MONITOR 客户端。
  • replica -> 副本(从)客户端。
  • pubsub -> 至少订阅了一个发布/订阅频道或模式的客户端。

每条 client-output-buffer-limit 指令的语法如下:

# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
# client-output-buffer-limit <类> <硬限制> <软限制> <软限制持续秒数>

一旦达到硬限制,客户端将被立即断开;或者,如果达到软限制并持续达到该限制指定的秒数,客户端也会被断开。例如,如果硬限制为 32 兆字节,软限制为 16 兆字节 / 10 秒,那么当输出缓冲区大小达到 32 兆字节时,客户端将立即被断开;如果客户端缓冲区达到 16 兆字节并连续 10 秒超过此限制,也会被断开。

默认情况下,普通客户端没有限制,因为它们不会在未请求的情况下被动接收数据(即非“推送”方式),而仅在发出请求后接收响应数据,因此只有异步客户端才可能产生请求数据速度远超读取速度的情况。

相反,对于发布/订阅客户端和副本客户端,默认设置了限制,因为订阅者和副本是以“推送”方式接收数据的。

通过将硬限制或软限制设置为零,可以禁用相应的限制。

client-query-buffer-limit

@引入版本: 5.0.x

@配置语法

# client-query-buffer-limit 1gb

@官方参考

客户端查询缓冲区用于累积新的命令。默认情况下,其大小被限制为一个固定值,以避免因协议不同步(例如客户端存在 bug)导致查询缓冲区的内存使用无限制地增长。但是,如果你有非常特殊的需求,例如需要处理巨大的 multi/exec 请求等,可以在此处进行配置。

proto-max-bulk-len

@引入版本: 5.0.x

@配置语法

# proto-max-bulk-len 512mb

@官方参考

在 Redis 协议中,批量请求(bulk requests)——即表示单个字符串的元素——通常被限制为 512 MB。但是,你可以在此处修改此限制,不过其值必须大于或等于 1 MB。

hz

@引入版本: 2.8.x

@配置语法

hz 10

@官方参考

Redis 会调用一个内部函数来执行许多后台任务,例如关闭超时的客户端连接、清理长时间未被访问的过期键等。

并非所有任务都以相同的频率执行,Redis 会根据指定的 "hz" 值来检查并执行相应的任务。

默认情况下,"hz" 设置为 10。提高该值会在 Redis 空闲时消耗更多的 CPU 资源,但同时在大量键同时过期时,能使 Redis 更加灵敏,并能更精确地处理超时事件。

该值的范围是 1 到 500,但通常不建议设置超过 100。大多数用户应使用默认值 10,只有在对延迟要求极低的环境中才建议将其提高到 100。

dynamic-hz

@引入版本: 5.0.x

@配置语法

dynamic-hz yes

@官方参考

通常,将 HZ 值设置为与连接的客户端数量成正比是很有用的。这样做的目的是为了避免在每次后台任务执行时处理过多的客户端,从而防止出现延迟尖峰。

由于默认的 HZ 值保守地设置为 10,Redis 提供了(并默认启用)动态自适应 HZ 的功能,当连接的客户端数量较多时,该功能会临时提高 HZ 值。

当启用动态 HZ 时,实际配置的 HZ 值将作为基准值使用。但随着连接的客户端增多,系统会根据需要实际使用该配置值的倍数。通过这种方式,空闲的 Redis 实例将消耗极少的 CPU 时间,而繁忙的实例则能具备更高的响应性。

aof-rewrite-incremental-fsync

@引入版本: 2.8.x

@配置语法

aof-rewrite-incremental-fsync yes

@官方参考

当子进程重写 AOF 文件时,如果启用了以下选项,每生成 32 MB 的数据就会对文件执行一次 fsync 操作。这有助于更渐进地将文件提交到磁盘,避免出现较大的延迟峰值。

rdb-save-incremental-fsync

@引入版本: 5.0.x

@配置语法

rdb-save-incremental-fsync yes

@官方参考

当 Redis 保存 RDB 文件时,如果启用了以下选项,每生成 32 MB 的数据就会对文件执行一次 fsync 操作。这有助于更渐进地将文件写入磁盘,避免因一次性大量写入而导致明显的延迟尖峰。

lfu-log-factor and lfu-decay-time

@引入版本: 4.0.x

@配置语法

# lfu-log-factor 10
# lfu-decay-time 1

@官方参考

Redis 的 LFU(Least Frequently Used,最不经常使用)淘汰策略(参见 maxmemory 配置)可以进行调优。但建议先使用默认设置,在深入了解如何提升性能以及键的 LFU 值随时间变化的情况后再进行调整。可以通过 OBJECT FREQ 命令来检查键的访问频率。

Redis 的 LFU 实现中有两个可调参数:计数器对数因子(counter logarithm factor)计数器衰减时间(counter decay time)。在修改这两个参数之前,理解它们的含义非常重要。

每个键的 LFU 计数器仅占 8 位,最大值为 255。因此,Redis 采用一种具有对数特性的概率递增方式进行计数。具体来说,当一个键被访问时,给定其旧的计数器值,计数器按以下方式递增:

  1. 生成一个介于 0 和 1 之间的随机数 R。
  2. 计算概率 P,公式为:P = 1 / (旧值 × lfu_log_factor + 1)。
  3. 仅当 R < P 时,计数器才会递增。
# 默认的 lfu-log-factor 为 10。以下是使用不同的对数因子时,频率计数器随访问次数变化的对照表:
#
# +--------+------------+------------+------------+------------+------------+
# | factor | 100 hits   | 1000 hits  | 100K hits  | 1M hits    | 10M hits   |
# +--------+------------+------------+------------+------------+------------+
# | 0      | 104        | 255        | 255        | 255        | 255        |
# +--------+------------+------------+------------+------------+------------+
# | 1      | 18         | 49         | 255        | 255        | 255        |
# +--------+------------+------------+------------+------------+------------+
# | 10     | 10         | 18         | 142        | 255        | 255        |
# +--------+------------+------------+------------+------------+------------+
# | 100    | 8          | 11         | 49         | 143        | 255        |
# +--------+------------+------------+------------+------------+------------+

Note 1: 上表是通过运行以下命令得到的:

redis-benchmark -n 1000000 incr foo
redis-cli object freq foo

NOTE 2: 计数器的初始值为 5,以便让新对象有机会积累访问次数。计数器衰减时间(lfu-decay-time)是指经过多少分钟,键的计数器值会减半(如果计数器值小于或等于 10,则减 1)。

lfu-decay-time 的默认值为 1。一个特殊值 0 表示每次扫描到该键时都进行衰减。

ACTIVE DEFRAGMENTATION

activedefrag

@引入版本: 6.0.x

@配置语法

# activedefrag no

@官方参考

什么是主动碎片整理(Active Defragmentation)?

主动(在线)碎片整理功能允许 Redis 服务器压缩内存中因数据的小规模分配和释放而产生的空隙,从而回收可用内存。

碎片化是一个自然发生的过程,在各种内存分配器(幸运的是,Jemalloc 中这种情况较少)和特定工作负载下都可能出现。通常,需要重启服务器,或至少清空并重新创建所有数据,才能降低碎片化程度。然而,得益于 Oran Agra 为 Redis 4.0 实现的这一功能,该过程可以在服务器运行时以“热”方式动态进行。

基本原理是:当碎片化程度超过某个阈值时(见下方配置选项),Redis 会利用 Jemalloc 的某些特定功能,创建新的、连续内存区域中的值副本(用于判断某次分配是否导致碎片化,并将其重新分配到更合适的位置),同时释放旧的数据副本。这个过程对所有键逐步重复执行,最终使碎片化程度恢复到正常水平。

需要理解的重要事项:

  • 此功能默认是禁用的,且仅在你使用 Redis 源码附带的 Jemalloc 版本编译 Redis 时才有效。在 Linux 系统上构建时,这通常是默认情况。
  • 如果你没有遇到碎片化问题,则完全不需要启用此功能。
  • 一旦遇到碎片化问题,可以通过命令 "CONFIG SET activedefrag yes" 在需要时启用此功能。

配置参数可用于精细调整碎片整理过程的行为。如果你不确定它们的含义,最好保持默认值不变。

启用主动碎片整理:

# activedefrag no

active-defrag-ignore-bytes

@引入版本: 4..x

@配置语法

# active-defrag-ignore-bytes 100mb

@官方参考

启动主动碎片整理所需的最小碎片浪费空间。

active-defrag-threshold-lower

@引入版本: 4.0.x

@配置语法

# active-defrag-threshold-lower 10

@官方参考

启动主动碎片整理所需的最小碎片化百分比。

active-defrag-threshold-upper

@引入版本: 4.0.x

@配置语法

# active-defrag-threshold-upper 100

@官方参考

我们使用最大努力进行碎片整理时的最高碎片化百分比。

active-defrag-cycle-min

@引入版本: 4.0.x

@配置语法

# active-defrag-cycle-min 1

@官方参考

当达到最低阈值时,碎片整理所使用的最小 CPU 百分比(即最低努力程度)。

active-defrag-cycle-max

@引入版本: 4.0.x

@配置语法

# active-defrag-cycle-max 25

@官方参考

当达到最高阈值时,碎片整理所使用的最大 CPU 百分比(即最高努力程度)。

active-defrag-max-scan-fields

@引入版本: 5.0.x

@配置语法

# active-defrag-max-scan-fields 1000

@官方参考

在主字典扫描过程中,将被处理的集合(set)、哈希(hash)、有序集合(zset)、列表(list)字段的最大数量。

jemalloc-bg-thread

@引入版本: 6.2.x

@配置语法

jemalloc-bg-thread yes

@官方参考

Jemalloc 用于清理的后台线程将默认启用。

server_cpulist

@引入版本: 6.2.x

@配置语法

# server_cpulist 0-7:2

@官方参考

可以将 Redis 的不同线程和进程绑定到系统中的特定 CPU,以最大化服务器性能。这不仅有助于将不同的 Redis 线程固定到不同的 CPU 上,还能确保在同一主机上运行的多个 Redis 实例分别绑定到不同的 CPU。

通常,你可以使用 taskset 命令来实现此目的,但也可以直接通过 Redis 配置在 Linux 和 FreeBSD 系统上完成。

你可以为 Redis 服务器/IO 线程、bio 线程、AOF 重写子进程以及 BGSAVE 子进程设置 CPU 亲和性。指定 CPU 列表的语法与 taskset 命令相同:

将 Redis 服务器/IO 线程绑定到 CPU 0、2、4、6:

# server_cpulist 0-7:2

bio_cpulist

@引入版本: 6.2.x

@配置语法

# bio_cpulist 1,3

@官方参考

将 bio 线程绑定到 CPU 1、3:

# bio_cpulist 1,3

aof_rewrite_cpulist

@引入版本: 6.2.x

@配置语法

# aof_rewrite_cpulist 8-11

@官方参考

将 AOF 重写子进程绑定到 CPU 8、9、10、11:

# aof_rewrite_cpulist 8-11

bgsave_cpulist

@引入版本: 6.2.x

@配置语法

# bgsave_cpulist 1,10-11

@官方参考

将 BGSAVE 子进程绑定到 CPU 1、10、11。

# bgsave_cpulist 1,10-11

ignore-warnings

@引入版本: 6.2.x

@配置语法

# ignore-warnings ARM64-COW-BUG

@官方参考

在某些情况下,如果 Redis 检测到系统处于不良状态,会发出警告甚至拒绝启动。可以通过设置以下配置项来抑制这些警告,该配置项接受一个以空格分隔的警告类型列表,指定需要屏蔽的警告。