前言
本文来自http://cs-cjl.com/中的redis配置系列,基于Redis 5.0的配置说明,非常详细。
配置文件redis.conf说明
include /path/to/local.conf
Redis 支持通过 include 选项来载入其他配置文件
loadmodule /path/to/my_module.so loadmodule /path/to/other_module.so
Redis 可以通过 loadmodule 选项在启动时加载模块,若服务端无法加载模块,服务端会停止。 可以通过多个 loadmodule 选项加载多个模块。
bind 127.0.0.1
bind 选项用于设置监听的 network interface,不设置这个选项相当于 bind 0.0.0.0,可以通过这个选项监听多个 network interface, 如:
bind 192.168.1.100 10.0.0.1
当设置多个 bind 地址后,Redis 内部会维护多个 Socket,每个 Socket 用于一个 network interface。
protected-mode yes
此选项默认开启,开启此选项后, 当 Redis 服务端未使用 bind 选项显式指定要监听的 network interface,并且未设置密码, Redis 服务端只会接受来自 127.0.0.1 和 ::1 的客户端以及 Unix 域的 Socket 进行连接。
port 6379
port 选项用于设置 Redis 监听的 TCP 端口,默认为 6379,设置为 0 表示不监听 TCP 端口
tcp-backlog 511
tcp-backlog 用于设置 TCP 连接的排队队列长度,最终就是影响到 listen 接口的 backlog 参数。
unixsocket /var/run/redis/redis.sock unixsocketperm 700
unixsocket 和 unixsocketperm 用于设置 Unix 域套接字,默认不开启。
timeout 0
当客户端空闲 timeout 秒后,Redis 服务端主动关闭此连接, 0 表示不启用此功能。
tcp-keepalive 300
将此值设置为非 0 值表示启用协议层的心跳检测功能,此功能是通过 setsockopt 的 SO_KEEPALIVE 选项开启的。
daemonize yes
设置 daemonize 选项为 yes 会使 Redis 以守护进程模式启动,在此模式下,Redis 默认会将 pid 写入 /var/run/redis.pid。 可以通过 pidfile 选项修改写入的文件,如:
pidfile /var/run/redis/redis-server.pid
supervised no
当你通过 upstart 或者 systemd 运行 Redis 时,Redis 可以和你的 supervision tree 进行交互,可选的选项为:
no 无交互 upstart 通过向 Redis 发送 SIGSTOP 信号来通知 upstart systemd 通过向 $NOTIFY_SOCKET 写入 READY=1 来通知 systemd auto 通过是否设置了 UPSTART_JOB 或者 NOTIFY_SOCKET 环境变量来决定选项为 upstart 或者 systemd
loglevel notice
日志级别,可以设置为: debug、verbose、notice、warning 中的一个。
logfile /var/log/redis/redis-server.log
logfile 选项用于设置日志输出的路径,若没有设置此路径,则 Redis 会将日志输出到标准输出,若以守护进程模式启动则输出到 /dev/null。
# To enable logging to the system logger, just set 'syslog-enabled' to yes, # and optionally update the other syslog parameters to suit your needs. # syslog-enabled no # Specify the syslog identity. # syslog-ident redis # Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. # syslog-facility local0
以上三个选项用于设置是否将日志输出到 syslog,syslog-ident 和 syslog-facility 对应了系统接口 openlog 的 ident 和 facility 选项。
databases 16
Redis 的数据库个数,当你连接到 Redis 服务器时,默认会选中 0 号数据库,可以通过 SELECT num 命令,选择要使用的数据库(num 表示 0 到 此选项的值减 1 的数据库)。
always-show-logo yes
默认情况下,Redis 只会在交互模式才显示 ASCII 版本的 logo,可以通过设置此选项为 yes,使 Redis 在任何情况下都显示 logo,使得 Redis 的此行为和 4.0 之前的版本行为保持一致。
save 900 1 save 300 10 save 60 10000
save 选项用于设置 Redis 将数据库持久化到硬盘的时间,可以有多个 save 选项。 save 后面的第一个数字表示多少秒进行一次检查,第二个数字表示此时间内有多少个 key 被改变会将数据库持久化到硬盘。 比如上面的三个选项表示,每 900 秒内,如果有多于 1 个 key 被改变(包括增加,修改,删除)则将其持久化到硬盘, 每 300 秒内,如果有多于 10 个 key 被改变则将其持久化到硬盘,每 60 秒内,如果有多于 10000 个 key 被改变则将其持久化到硬盘。
stop-writes-on-bgsave-error yes
当最近一次的持久化操作失败后,Redis 会拒绝客户端的写入操作,通过这种行为客户端会知道服务端的不正常现象。 若持久化操作可以正常工作后,服务端会自动允许客户端的写入操作。 如果你自己有 Redis 服务端的监控方案,或者你希望即使持久化失败 Redis 也可以正常工作,则可以将此选项设置为 no。
rdbcompression yes
设置为 yes 表示使用 LZO 算法压缩持久化到硬盘的 string 对象。
rdbchecksum yes
RDB 文件是否开启校验和。
dbfilename dump.rdb
RDB 文件的文件名。
dir /var/lib/redis
Redis 的工作目录,RDB 和 AOF (后面会说)文件会保存到此目录。
replicaof <masterip> <masterport>
通过 replicaof (即以前的 slaveof)选项可以将 Redis 实例设置为其他 Redis 服务端的副本。
关于 Redis 的复制,有以下几点需要注意:
Redis 复制是异步的,但是你可以设置 master 节点,使得 master 节点至少要和指定数量的 replicas 节点连接才提供写服务
当 Redis replicas 节点和 master 节点短暂断开后,replicas 节点可以向 master 节点要求进行部分数据的重传
复制是自动的,不需要用户干预,当发生网络分区后,replicas 节点会自动尝试和 master 节点重连以及进行数据同步
masterauth <master-password>
当 master 节点使用了 “requirepass” 选项后,replicas 节点需要配置此选项。
replica-serve-stale-data yes
此选项为以前的 slave-serve-stale-data,replicas 节点和 master 节点断开连接后,replicas 节点根据 replica-serve-stale-data 选项的配置可能有以下行为:
- 选项设置为 yes(默认值),replicas 节点会继续向客户端提供服务,此时返回给客户端的数据很可能是过期的
- 选项设置为 no,除了 INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST, HOST, 和 LATENCY 命令外的其他命令,replicas 节点都会返回 "SYNC with master in progress" 给客户端
replica-read-only yes
设置 replicas 节点是否只读,从 Redis 2.6 开始此选项的默认值为 yes。 需要注意的是只读的 replicas 节点并没有设计为会暴露给网络上不受信任的客户端使用的。 你需要对其进行保护以防实例被滥用。并且只读的 replicas 节点导出了所有如 CONFIG,DEBUG,等管理命令。 你可以使用 'rename-command' 将所有管理/危险 命令进行映射以提高安全性。
repl-diskless-sync no
DISKLESS REPLICATION 目前是实验性功能
当一个不能续传或者新的 replicas 需要进行“全量同步”时。一个 RDB 文件需要由 master 传送到 replicas。 根据 repl-diskless-sync 选项的不同,RDB 文件有以下两种传输方式:
- Disk-backed:Redis master 节点创建一个新的进程并且将 RDB 文件写入磁盘。然后文件通过父进程传输给 replicas 节点
- Diskless:Redis master 节点一个新的进程并且直接将 RDB 文件写入到 replica 的 socket 中,不写到磁盘
当进行 disk-backed 复制时,当 RDB 文件生成完毕,多个 replicas 通过排队来同步 RDB 文件。 当进行 diskless 复制时,master 节点会等待一段时间再传输以期望会有多个 replicas 连接进来,这样 master 节点就可以同时同步到多个 replicas 节点。
repl-diskless-sync-delay 5
当启用 diskless 复制后,可以通过此选项设置 master 节点创建子进程前等待的时间,单位为秒。
repl-ping-replica-period 10
Replicas 发送 PING 到 master 的间隔,默认值为 10 秒。
repl-timeout 60
此选项用于设置以下情形的 timeout 判断:
- 从 replica 节点的角度来看的 SYNC 过程中的 I/O 传输
- 从 replica 节点的角度来看的 master 的 timeout(如 data,pings)
- 从 master 节点角度来看的 replica 的 timeout(如 REPLCONF ACK pings)
需要注意的是,此选项必须大于 repl-ping-replica-period,否则在低业务量的情况下会经常发生 timeout。
repl-disable-tcp-nodelay no
master 和 replicas 节点的连接是否关掉 TCP_NODELAY 选项。 这个实际影响的是 TCP 层的选项,里面会用 setsockopt 设置,默认为 no,表示 TCP 层会禁用 Nagle 算法,尽快将数据发出, 设置为 yes 表示 TCP 层启用 Nagle 算法,数据累积到一定程度,或者经过一定时间 TCP 层才会将其发出。
repl-backlog-size 1mb
设置复制的 backlog 缓冲大小。当 replicas 节点断开重连后,如果断点发生时的数据还在 backlog 缓冲中, 则不需要全量同步,只需要部分同步。 更大的 backlog 缓冲大小,意味着 replicas 断开重连后,依然可以进行续传的时间越长(支持断开更长时间)。 backlog 缓冲只有在至少一个 replicas 节点连过来的时候 master 节点才需要创建。
repl-backlog-ttl 3600
当 replicas 节点断开连接后,master 节点会在一段时间后释放 backlog 缓冲区。 这个选项设置的是当最后一个 replicas 断开链接后,master 需要等待多少秒再释放缓冲区。
需要注意的是 replicas 节点永远都不会释放这个缓冲区,因为它有可能再次连接到 master 节点, 然后尝试进行 “增量同步”。
replica-priority 100
这是 replicas 节点通过 INFO 接口给出的信息,默认值为 100。 当 master 节点无法正常工作后 Redis Sentinel 通过这个值来决定将哪个 replicas 节点提升为 master 节点。
这个数值越小表示越优先进行提升。如有三个 replicas 节点其 priority 值分别为 10,100,25, Sentinel 会选择 priority 为 10 的节点进行提升。
这个值为 0 表示 replica 节点永远不能被提升为 master 节点。
min-replicas-to-write 3 min-replicas-max-lag 10
以上选项用于设置至少有 N 个 replicas 节点延迟少于 M 秒时,master 节点才能进行写操作, 如上面的例子表示至少有 3 个 replicas 节点延迟少于 M 秒时,master 节点才能进行写操作。 将上面参数的任意一个设置为 0 表示不启用此功能,min-replicas-to-write 的默认值为 0,min-replicas-max-lag 的默认值为 10。
replica-announce-ip 5.5.5.5 replica-announce-port 1234
Redis master 可以通过不同方式列出连接上来的 replicas 节点的地址和端口。 如 Redis Sentinel 等会使用 “INFO replication” 命令来获取 replica 实例信息。 master 的 “ROLE“ 命令也会提供此信息。
这个信息一般来说是通过 replica 节点通过以下方式获取然后报告上来的:
- IP:通过自动识别连接到 Socket 的信息自动获取
- Port:一般来说这个值就是 replicas 节点用来接受客户端的连接的监听端口
但是,若启用了端口转发或者 NAT,可能需要其他地址和端口才能连接到 replicas 节点。 这种情况下,需要设置这两个选项,这样 replicas 就会用这两个选项设置的值覆盖默认行为获取的值,然后报告给 master 节点。 根据实际情况,你可以只设置其中某个选项,而不用两个选项都设置。
requirepass foobared
设置此选项后,客户端需要使用 AUTH
警告:由于 Redis 非常快,外部用户若进行暴力破解,每秒能尝试超过 150k 个密码。因此你需要使用强度非常高的密码才能保证密码不容易被暴力破解掉。
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
在共享环境下,可以通过 rename-command 命令将一些危险的命令进行重命名。 如上所示将 CONFIG 命令重命名为难以猜测的命令。
可以通过将命令重命名为空字符串从而将其完全 ”kill“ 掉,如:
rename-command CONFIG ""
注意:rename-command 命令会被记录到日志和 AOF 文件中或者传输到 replicas 节点,而这可能会是一个安全问题。
maxclients 10000
设置同时连接进来的最大客户端数,默认值为 10000。需要注意的是同时连接进来的客户端数量还受限于 Redis 进程所能创建的最大的文件句柄的数量减去 32(Redis 会保留部分句柄用于内部使用)。当超过限制后 Redis 会向所有新进来的连接发送错误信息 ”max number of clients reached“ 然后关闭连接。
maxmemory <bytes>
设置 Redis 能使用的最大内存数,以字节为单位。根据你选择的过期策略(查看下面的 maxmemory-policy 选项), 当 Redis 使用的内存达到限制时,Redis 会尝试删除过期的键。
若 Redis 没有能删除的键,Redis 会拒绝那些如 SET,LPUSH 等会使用更多内存的命令,并且会正常相应那些如 GET 等只读命令。
这个选项通常用于将 Redis 作为 LRU 或者 LFU cache 使用的情况。
当你的 Redis 实例设置了 maxmemory 并且有 replicas 连接上来的情况,你需要留出一部分内存给 replica 缓冲区。
maxmemory-policy noeviction
当内存使用值到达 maxmemory 时使用的删除策略,默认值为 noeviction。
- volatile-lru -> 对过期键使用 LRU(Least Recently Used) 近似算法
- allkeys-lru -> 对所有键使用 LRU 近似算法
- volatile-lfu -> 对过期键使用 LFU(Least Frequently Used)近似算法
- allkeys-lfu -> 对所有键使用 LFU 近似算法
- volatile-random -> 对过期键使用随机算法
- allkeys-random -> 对所有键使用随机算法
- volatile-ttl -> 删除最近过期的键(minimal TTL)
- noeviction -> 对写请求返回错误,不删除键
注意:在内存到达限值,并且没有合适的键被删除的情况下,无论选择的是什么过期策略,Redis 都会返回出错。
maxmemory-samples 5
上面的 LRU,LFU 和 minimal TTL 算法都是近似算法,你可以通过改变这个选项来让算法更快还是更精确。 默认值是 5,也就是说 Redis 随机挑出 5 个键,然后选出一个最符合条件的。
对 LRU 来说 5 是比较合适的。10 已经很接近于真正的 LRU,但会消耗更多的 CPU。3 会更快但没有那么精确。
replica-ignore-maxmemory yes
从 Redis 5 开始,默认情况下,replica 节点会忽略 maxmemory 设置(除非在发生 failover 后,此节点被提升为 master 节点)。 这意味着只有 master 才会执行过期删除策略,并且 master 在删除键之后会对 replica 发送 DEL 命令。
这个行为保证了 master 和 replicas 的一致性,并且这通常也是你需要的,但是若你的 replica 节点是可写的, 或者你希望 replica 节点有不同的内存配置,并且你确保所有到 replica 写操作都幂等的,那么你可以修改这个默认的行为 (请确保你明白你在做什么)。
注意::默认情况下 replica 节点不会执行过期策略,它有可能使用了超过 maxmemory 设定的值的内存。 因此你需要监控 replicas 节点所在的机器并且确保在 master 节点到达配置的 maxmemory 大小时, replicas 节点不会超过物理内存的大小。
lazyfree-lazy-eviction no lazyfree-lazy-expire no lazyfree-lazy-server-del no replica-lazy-flush no
Redis 有两种方式删除键。一种是使用如 DEL 这样的命令进行的同步删除。 同步删除意味着删除过程中服务端会停止处理新进来的命令。 若要删除的 key 关联了一个小的 object 删除耗时会很短。 若要删除的 key 管理了一个很大的 object,比如此对象有上百万个元素,服务端会阻塞相同长一段时间(甚至超过一秒)。
由于以上原因,Redis 同时提供了一种非阻塞的方式用于删除,比如 UNLINK(非阻塞的 DEL)以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 选项,这些命令能在后台回收内存。 这些命令能在常数时间内执行完毕。其他线程会在后台尽快回收内存。
DEL,UNLINK 以及用于 FLUSHALL 和 FLUSHDB 的 ASYNC 选项是用户可以控制的。 根据应用的设计,用户可以选择使用阻塞或者非阻塞的方式。 但是作为某些命令的副作用 Redis 服务端有时会删除某些 object 或者 flush 整个数据库。 特别是以下独立于用户操作的情形:
- 由于 maxmemory 和 maxmemory policy 配置导致的内存回收动作
- 由于过期,当一个 key 过期后(可以查看 EXPIRE 命令获取相关信息),必须回收其内存
- 由于某些命令的副作用,比如 STORE 命令,执行 STORE 命令可能需要删除已有的键。SET 命令需要删除已有的旧内容。
- 在复制过程中,当一个 replica 节点执行一个全量同步时,replica 需要删除整个数据库的内容以加载传输过来的 RDB 文件。
在上述所有情形中,删除 object 的默认行为都是以阻塞方式删除。当然你可以配置上述四个选项来改变这种默认行为。
appendonly no
默认情况下,Redis 会以异步形式将备份集 dump 到硬盘中。 对于很多应用来说,这种行为足够了,但是对于 Redis 进程崩溃或者断电的情况会导致最近数分钟的数据丢失(取决于 save 选项的设置)。
Append Only File 是 Redis 提供的另一种更好的持久化方式。 比如使用默认的数据同步策略(后面会讲),Redis 在断电等意外情况只会丢失最多一秒的写入数据, 在系统正常而 Redis 进程出错(如崩溃)的情况下只会丢掉最近一次写操作。
AOF 和 RDB 同步策略可以同时启用。当 AOF 启用后,Redis 在启动阶段会加载 AOF 文件, 这是因为相比 RDB,AOF 提供更好的持久性。 可以通过查看 http://redis.io/topics/persistence 获取更多信息。
appendfilename "appendonly.aof"
append only file 的名称,默认为 appendonly.aof。
appendfsync everysec
fsync() 调用用于告诉操作系统将数据写入硬盘而不是放入输出缓冲区中。 某些系统会马上将数据 flush 到硬盘中,而某些系统只是尽快尝试写入。 Redis 支持以下三种模式:
- no 不调用 fsync,让操作系统决定什么时候真正写到硬盘
- always 每次写入都对 append only file 进行 fsync 操作。最慢,也是最安全的选项。
- everysec 每秒进行一次 fsync 操作,折中的做法。
默认选项为 "everysec",对安全性和速度进行了折中。 更多信息可以通过查看 http://antirez.com/post/redis-persistence-demystified.html 获取。
当 AOF fsync 策略设置为 always 或者 everysec 并且后台保存进程(bgsave 或者 AOF 日志重写)正在进行大量 I/O 操作, 某些 Linux 配置下,Redis 会阻塞太长时间在 fsync() 调用。目前,没有方法可以避免这种状况, 即使是在其他线程执行 fsync 操作也一样会阻塞我们的同步写 write(2) 操作。
no-appendfsync-on-rewrite no
为了缓和这种情况,可以在进行 BGSAVE 或者 BGREWRITEAOF 时禁止 fsync() 操作。 这意味着,当有子进程在保存的时候 Redis 的持久性相当于 "appendfsync none"。
当你的 Redis 延迟过大时可以将 no-appendfsync-on-rewrite 设置为 "yes", 否则将其保持在 "no" 以保证持久性。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
自动重写 append only file 选项。 当 AOF 文件增长到一定比例后,Redis 可以自动通过隐式调用 BGREWRITEAOF 命令来重写 AOF 文件。
Redis 会记录上一次 rewrite 的 AOF 文件大小(若从未进行 rewrite,Redis 会使用启动时的 AOF 文件大小)作为基准大小。
Redis 会比较当前大小和基准大小,若当前大小大于一定比例则触发 rewrite。 为了防止增长比例到了但是总数据量还是非常小的情况就触发 rewrite,你还需要指定一个 AOF rewritten 的最小大小。
通过将 auto-aof-rewrite-percentage 设置为 0 可以禁用此功能。
aof-load-truncated yes
当 Redis 启动时可能会发现 AOF 文件被截断了(不完整),这可能是由于系统崩溃了, 特别是 ext4 没有以 data=ordered 选项挂载的情况(在 Redis 崩溃而系统正常的情况下不会发生截断)。
当这种情况发生时,Redis 可以选择终止进程,或者加载 AOF 文件上尽可能多的数据(目前的默认行为)。
当 aof-load-truncated 设置为 yes, Redis 服务端在启动的时候发现加载的 AOF 文件是被截断的会发送一条日志来通知客户。 若 aof-load-truncated 设置为 no,服务端会以错误形式终止进程并拒绝启动。 这是需要用户在重启服务前使用 "redis-check-aof" 工具来修复 AOF 文件。
注意:当 Redis 服务端发现 AOF 文件已经被损坏的情况下,服务端无论如何都会以错误终止进程。 这个选项只会在 Redis 尝试读取更多数据但是发现已经读到 AOF 文件的末尾时才会生效。
aof-use-rdb-preamble yes
当重写 AOF 文件时,Redis 可以使用 RDB 文件作为 AOF 文件的前导,这样可以更快地进行重写和恢复。 当启用这个功能时 AOF 文件由两部分组成:
[RDB file][AOF tail]
当加载 AOF 文件时,Redis 通过以 “REDIS” 字符串开头的 AOF 文件识别出此文件是由 RDB 和 AOF 组合而成的, Redis 会先加载 RDB 部分,然后再加载 AOF 部分。
lua-time-limit 5000
此选项用于控制 Lua 脚本的最长执行时间,单位为毫秒。
当 Lua 脚本的执行时间超出限制后,Redis 会在写入相关日志,并且向客户端返回出错。
当一个长时间运行的脚本超过超大限制后,只有 SCRIPT KILL 和 SHUTDOWN NOSAVE 命令是有效的。 前者可以用于停止尚未进行写操作的脚本。后者用于停掉服务, 当脚本已经开始进行写操作并用户于不想等脚本自然结束,这是唯一的方法。
将这个值设为 0 或者负数表示不限制最大运行时间。
cluster-enabled yes
只有那些以集群的模式启动的节点才能成为 Redis 集群的一部分,普通的 Redis 实例不能成为 Redis 集群的一部分。 为了让 Redis 实例成为集群的节点,需要将 cluster-enabled 设置为 yes。
cluster-config-file nodes-6379.conf
每个集群节点都有一个集群配置文件,这个文件不能手动修改,只能由 Redis 节点创建和更新。 每个 Redis 集群节点需要不同的集群配置文件,需要确保同一个系统运行的不同 Redis 实例使用了不同的名称的集群配置文件。
cluster-node-timeout 15000
集群节点的超时时间,以毫秒为单位,当一个节点无法连接超过此选项配置的时间后, 就可以认为此节点处于失败状态。
其他的内部时间限制是此配置值的整数倍。
cluster-replica-validity-factor 10
当一个 master 处于失败状态,而它的 replica 节点数据太旧的情况下不会进行 failover。
没有一个简单的方法判断 replica 节点的 "data age",因此需要以下方法来检查:
- 如果有多个可用于 failover 的 replicas 节点,他们之间会交换消息以尝试选出具有最好的 replication offset(处理了最多的数据)的节点。 Replicas 会根据 offset 获取 rank,并且它开始进行 failover 的延时与 rank 成正比。
- 每个 replica 节点计算最后一次与 master 交互的时间。这个交互可以是 ping 或者是收到命令(如果 master 节点依然是 “connected” 状态), 获取是与 master 连接丢失以来经过的时间(如果复制连接断开)。 如果上一个交互的时间太旧,则 replica 不会尝试 failover。
第二点可以由用户进行调整。当 replicas 节点最后一个与 master 节点交互的时间超过以下时间时,replicas 不会进行 failover。
(node-timeout * replica-validity-factor) + repl-ping-replica-period
比如 node-timeout 为 30 秒,而 replica-validity-factor 为 10,并且假设 repl-ping-replica-period 为 10 秒, 当 replica 最后与 master 交互的时间超过 310 秒时,replica 不会尝试 failover。
replica-validity-factor 设置的过大会导致拥有陈旧数据的 replicas 通过 failover 成为 master, 当这个值太小则会阻止集群选出一个 replica。
为了最大的可用性,可以将 replica-validity-factor 设置为 0, 表示 replicas 总是尝试 failover 成为 master 而不管最后一次与 master 交互的时间。
0 是保证所有集群的所有分区总是能痊愈并且继续提供服务的唯一选择。
cluster-migration-barrier 1
集群的 replicas 节点可以迁移到裸奔的 master 节点(就是没有 replicas 节点的 master 节点)。 当裸奔的 master 节点发生故障后不能进行 failover,因此这个功能提高了整个集群的抗故障能力。
replicas 节点只有在迁移到裸奔的 master 节点后,旧的 master 依然有给定数量的 replicas 节点才能进行迁移。 这个给定数量就是 "migration barrier",由 cluster-migration-barrier 设置。 cluster-migration-barrier 为 1 表示 replicas 只有在迁移后旧的 master 节点至少还有一个可工作的 replicas 节点才进行迁移。 这个值一般设定为你希望每个 master 需要多少个 replicas 节点。
这个选项的默认为 1。如果你想要禁止迁移只需要将这个选项的值设置为一个很大的数即可。 设置为 0 只有在调试的时候才有用,在生产环境使用这个值是很危险的。
cluster-require-full-coverage yes
默认情况下 Redis 集群只要发现有一个 hash slot 未被覆盖(没有可用的节点为其提供服务)则会停止提供查询服务。 因此当集群发生部分故障(比如部分的 hash slot 未被覆盖),则会导致整个集群都无法工作。 当所有的 slots 再次被覆盖后,集群会自动恢复到可用状态。
如果你希望在集群发生故障时可用的部分依然可以提供查询服务,可以将 cluster-require-full-coverage 的值设置为 no。
cluster-replica-no-failover no
这个选项用于控制 master 发生故障时是否自动进行 failover。
当设置为 yes 后 master 发生故障时不会自动进行 failover,这时你可以进行手动的 failover 操作。
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380
在某些部署环境下,Redis 集群的节点地址不能被自动发现,这是因为这些节点是部署在 NAT 网络或者端口是转发的 (典型的情况就是使用了 Docker 或者其他容器)。
为了能让 Redis 集群工作在这种环境下,我们需要进行相关配置让各个节点知道相互之间的外部地址, 这可以通过设置以下选项做到:
- cluster-announce-ip
- cluster-announce-port
- cluster-announce-bus-port
cluster-announce-ip 表示节点的外部地址,cluster-announce-port 表示节点的客户端口, cluster-announce-bus-port 表示集群消息总线端口。
若以上选项未配置,则将会启用正常的 Redis 集群自动检测机制。 若 bus port 未设置,则会将其设置为 port + 10000。
slowlog-log-slower-than 10000 slowlog-max-len 128
慢查询日志表示当一个查询的运行时间超过设置的时间时,系统会将其记录在慢查询日志中。 这个运行时间只包括执行命令需要的时间(只有这个阶段线程是处于阻塞状态并且无法为其他请求提供服务), 不包括 I/O 操作,比如和客户端通讯,发送响应请求等。
你可以设置慢查询日志的两个参数:一个是以微秒为单位的执行时间,超过这个时间的命令将会被记录下来, 另一个选项是慢查询日志的大小(就是一共会保存多少条慢查询日志)。 当一个新的命令需要被记录到慢查询日志并且当前慢查询日志的条数已经到达限制时,会先将最旧的慢查询日志移出队列。
slowlog-log-slower-than 为负数时表示禁用慢查询日志,0 表示记录所有的命令。
slowlog-max-len 没有上限,因此需要注意设置此值的大小,以免消耗过多的内存。
可以通过 SLOWLOG RESET 回收慢查询日志所消耗的内存。
latency-monitor-threshold 0
Redis 延迟监视子系统收集的阀值,单位为毫秒,默认值为 0。 Redis 延迟监视子系统在运行时对不同的操作进行采样,以便收集与 Redis 实例延迟相关的数据。
用户可以通过 LATENCY 命令以图表和报告的形式获取延迟相关信息。
系统只会记录时间大于等于 latency-monitor-threshold 的操作。 当 latency-monitor-threshold 设置为 0 表示关闭 Redis 延迟监视子系统。
默认情况下 Redis 延迟监视子系统是处于关闭状态的,当你的系统没有延迟问题,数据收集工作反而会造成性能冲击。 可以通过以下命令在运行的 Redis 系统中启用Redis 延迟监视子系统:
CONFIG SET latency-monitor-threshold <milliseconds>
notify-keyspace-events ""
Redis 通过 Pub/Sub 机制向客户通知 keyspace 中发生的事件。 这个特性的更多信息可以查看文档: http://redis.io/topics/notifications
举例来说,如果 keyspace 事件通知是启用的,并且有一个客户在数据库 0 执行了如下命令:
DEL foo
这时 Redis 会通过 Pub/Sub 机制发送如下两条消息:
PUBLISH __keyspace@0__:foo del
PUBLISH __keyevent@0__:del foo
可以通过配置 "notify-keyspace-events" 选项来让 Redis 选择发送哪些事件:
- K Keyspace 事件, 以 __keyspace@
__ 为前缀发布 - E Keyevent 事件, 以 __keyevent@
__ 为前缀发布 - g 通用命令 (不是针对特定类型的命令) 比如 DEL, EXPIRE, RENAME 等
- $ String 命令
- l List 命令
- s Set 命令
- h Hash 命令
- z Sorted set 命令
- x Expired 事件 (当一个 key 过期的时候生成)
- e Evicted 事件 (当一个 key 由于 maxmemory 被回收生成)
- A 表示 g$lshzxe 的别名,因此 "AKE" 表示所有事件
notify-keyspace-events 的值由上面的 0 到 N 个字符组成。空字符串表示禁止发送通知, 这是 notify-keyspace-events 的默认值。
举个例子:
notify-keyspace-events Elg
表示启用 list 命令和通用命令相关的事件通知。
notify-keyspace-events Ex
表示启用过期事件通知。
需要注意的是如果要启用事件通知至少要包含 K 或者 E,否则不会有事件发布。
hash-max-ziplist-entries 512 hash-max-ziplist-value 64
当哈希表的项不超过 hash-max-ziplist-entries,并且每一项的长度不超过 hash-max-ziplist-value 使用 ziplist 保存数据。
list-max-ziplist-size -2
Redis 的 List 内部是通过 quicklist 实现的(Redis 3.2 开始使用),quicklist 是一个双向链表。 quicklist 的每个节点都是一个 ziplist。list-max-ziplist-size 就是用于配置 quicklist 中的每个节点的 ziplist 的大小。 当这个值配置为正数时表示 quicklist 每个节点的 ziplist 所包含的元素个数是一个确定的数量。 当 list-max-ziplist-size 为负数时表示限制每个 ziplist 的大小,具体有以下含义:
- -5:最大 64 kb <--- 正常环境不推荐
- -4:最大 32 kb <--- 不推荐
- -3:最大 16 kb <--- 可能不推荐
- -2:最大 8 kb <--- 不错
- -1:最大 4kb <--- 不错
默认值为 -2,也是官方最推荐的值,当然你可以根据自己的实际情况进行修改。
list-compress-depth 0
quicklist 中的 ziplist 节点会被压缩。为了 push/pop 操作的高效性,quicklist 的头和尾节点永远都不会被压缩。 list-compress-depth 选项用于控制 quicklist 中压缩的节点的深度,下面的示例中加了中括号的节点表示未压缩。
- 0 表示不对节点进行压缩,这是默认的值
- 1 表示对头和尾节点外的其他节点进行压缩, [head]->node->node->...->node->[tail]
- 2 [head]->[next]->node->node->...->node->[prev]->[tail]
- 3 [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
- 依次类推
set-max-intset-entries 512
当 Redis 的集合类型保存的数据均为数字,并且元素个数不超过 set-max-intset-entries 的时候。 Redis 将使用特殊的 intset 结构来保存这个集合。
zset-max-ziplist-entries 128 zset-max-ziplist-value 64
类似哈希表和列表,当排序集合的元素个数不超过 zset-max-ziplist-entries 并且每个元素的长度不超过 zset-max-ziplist-value 时,Redis 将使用 ziplist 保存这个排序集合。
hll-sparse-max-bytes 3000
HyperLogLog 稀疏模式的字节限制,包括了 16 字节的头,默认值为 3000。 当超出这个限制后 HyperLogLog 将有稀疏模式转为稠密模式。
将这个值设置为超过 16000 是没必要的,因为这时使用稠密模式更省空间。
stream-node-max-bytes 4096 stream-node-max-entries 100
用于设定 Streams 单个节点的最大大小和最多能保存多个个元素。
activerehashing yes
默认值为 yes。
当启用这个功能后,Redis 对哈希表的 rehash 操作会在每 100 毫秒 CPU 时间中的 1 毫秒进行。 Redis 的哈希表实现的 rehash 策略是一个惰性策略:就是说你对这个哈希表进行越多操作,你将有更多的 rehash 机会, 若你的服务器处于空闲状态则不会有机会完成 rehash 操作,这时哈希表会占用更多内存。
默认情况下会在每一秒中用 10 毫秒来对主哈希表进行 rehash。
如果在你的环境中需要有严格的延迟要求,则需要使用将 activerehashing 配置为 no,比如说需要在 2 毫秒内相应查询操作。 否则你应该将这个选项设置诶 yes,这样可以更及时地释放空闲的内存。
client-output-buffer-limit normal 0 0 0 client-output-buffer-limit replica 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60
客户端输出缓冲区限制可用于强制断开从服务器读取数据的速度不够快的客户端 (一个常见的原因是 Pub/Sub 客户端处理发布者的消息不够快)。
可以为每种客户端设置不同的限制:
- normal -> 普通客户端,包括 MONITOR 客户端
- replica -> 复制客户端
- pubsub -> 订阅了至少一个频道的客户端
client-output-buffer-limit 选项的语法为:
client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
当一个客户端到达 hard limit 后会马上被断开,或者在到达 soft limit 并持续 soft seconds 秒后会被断开。
默认情况下,普通客户端不会有限制,因为除非主动请求否则他们不会收到信息, 只有异步的客户端才可能发生发送请求的速度比读取响应的速度快的情况。
默认情况下 pubsub 和 replica 客户端会有默认的限制,因为这些客户端是以 Redis 服务端 push 的方式接收数据的。
soft limit 或者 hard limit 都可以设置为 0,这表示不启用此限制。
client-query-buffer-limit 1gb
客户端查询缓冲区会累加新的命令。 默认情况下,他们会限制在一个固定的数量避免协议同步失效(比如客户端的 bug)导致查询缓冲区出现未绑定的内存。
但是,如果有类似于巨大的 multi/exec 请求的时候可以修改这个值以满足你的特殊需求。
proto-max-bulk-len 512mb
在 Redis 协议中,批量请求通常限制在 512 mb 内,可以通过修改 proto-max-bulk-len 选项改变这个限制。
hz 10
默认值是 10,范围是 1 到 500,超过 100 一般都不是一个好主意。 Redis 会通过调用内部函数来完成很多后台任务,比如关闭超时的客户端的连接,清除过期的 key,等等。
Redis 通过 hz 设置的值来决定执行这些任务的频繁程度。
hz 的默认值是 10,可以通过提高这个值来使得 CPU 在空闲的时候使用更多的 CPU 时间来处理后台任务。 但同时这会使得当有很多 key 在同一时间过期时,过期处理会更精确。
很多客户只有在一些需要很低延迟的环境中才会将这个值从 10 提升到 100。
dynamic-hz yes
通常来说根据连接上来的客户端数量对 HZ 的值按比例进行调整是有用的。 这很有用,例如,为了避免每次后台任务处理太多的客户端,从而避免高延迟峰值。
默认情况下 HZ 的值为 10,启用 dynamic-hz 后,当有大量客户端连接进来时 HZ 的值会临时性地调高。
启用 dynamic-hz 后,HZ 的配置值将作为基线,当有大量的客户端连接进来时,Redis 会将 HZ 的实际值设置为 HZ 的配置值的整数倍。 通过这种方式,空闲的 Redis 实例只会占用非常小的 CPU 时间,当实例变得繁忙时 Redis 能更快地进行响应(相对未启用 dynamic-hz 的情况)。
aof-rewrite-incremental-fsync yes
当子进程进行 AOF 的重写时,如果启用了 aof-rewrite-incremental-fsync, 子进程会每生成 32 MB 数据就进行一次 fsync 操作。 通过这种方式将数据分批提交到硬盘可以避免高延迟峰值。
rdb-save-incremental-fsync yes
当 Redis 保存 RDB 文件时,如果启用了 rdb-save-incremental-fsync 功能, Redis 会每生成 32 MB 数据就执行一次 fsync 操作。 通过这种方式将数据分批提交到硬盘可以避免高延迟峰值。
# lfu-log-factor 10 # lfu-decay-time 1
Redis LFU 回收策略(忘了的话可以回顾下 maxmemory 选项)是可以调整的。 在开始的时候使用默认值并且只有在经过对如何提升性能和 key LFU 随时间如何改变进行调查查后才对其更改是一个好的主意。 这可以通过 OBJECT FREQ 命令进行检查。
Redis 的 LFU 实现目前有两个可调整的参数:计数器对数因子(couter logarithm factor) 和 计数器衰退时间(counter decay time)。 在修改这两个参数之前理解这两个参数是很重要的。
每个 key 的 LFU 计数器只有 8 bits,也就是说最大值为 255,因此 Redis 通过对数行为来对计数进行概率性的增加。 当一个 key 被访问后,计数器通过如下方式进行增加(假设计数器的旧值为 old_value):
- 取出一个 0 到 1 之间的随机数 R
- 通过如下方式算出概率 P: 1 / (old_value * lfu_log_factor + 1)
- 只有当 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 |
注意:上表是通过如下命令获得的: redis-benchmark -n 1000000 incr foo redis-cli object freq foo;计数器的初始值为 5
计数器衰减时间是 key 计数器除以 2 (如果值小于 <= 10,则递减)所必须经过的时间,单位为分钟。 lfu-decay-time 的默认值为 1。 0 表示每次都对计数器进行衰减。
活动碎片整理允许 Redis 服务器压缩内存中由于申请和释放数据块导致的碎片,从而回收内存。 碎片是每次申请内存(幸运的是 Jemalloc 出现碎片的几率小很多)的时候会自然发生的。 通常来说,为了降低碎片化程度需要重启服务,或者至少需要清除所有的数据然后重新创建。 得益于 Oran Agra 在 Redis 4.0 实现的这个特性,进程可以在服务运行时以 “热” 方式完成这些目的。
通常来说当碎片化达到一定程度(查看下面的配置)Redis 会使用 Jemalloc 的特性创建连续的内存空间, 并在此内存空间对现有的值进行拷贝,拷贝完成后会释放掉旧的数据。 这个过程会对所有的导致碎片化的 key 以增量的形式进行。
需要重点理解的是:
- 这个特性默认是关闭的,并且只有在编译 Redis 时使用我们代码中的 Jemalloc 版本才生效。(这是 Linux 下的默认行为)
- 如果没有碎片问题,你永远不需要启用这项特性
- 如果你需要试验这项特性,可以通过命令 CONFIG SET activefrag yes 来启用
相关的配置参数可以很好的调整碎片整理过程。如果你不知道这些选项的作用最好使用默认值。
activedefrag yes
启用碎片整理。
active-defrag-ignore-bytes 100mb
有至少多少碎片时才开始碎片整理。
active-defrag-threshold-lower 10
有至少多少比例的碎片时才开始碎片整理。
active-defrag-threshold-upper 100
有多少比例的碎片时才开始以最大努力进行碎片整理。
active-defrag-cycle-min 5
进行碎片整理时至少使用多少比例的 CPU 时间。
active-defrag-cycle-max 75
最大努力进行碎片整理时使用多少 CPU 时间。
active-defrag-max-scan-fields 1000
进行主字典扫描时处理的 set/hash/zset/list 字段的最大数量(就是说在进行主字典扫描时 set/hash/zset/list 的长度小于这个值才会处理,大于这个值的会放在一个列表中延迟处理)。