Redis——配置文件万字解读

870 阅读23分钟

前言

  最近,我们在对接口进行压测优化,发现有些接口的TPS太不正常了,这里面多数接口都是直接从redis里面取数据的,针对反常的压测结果,我们决定从接口和redis集群两方面进行优化。针对于redis集群优化方面,主要是根据当前业务情况,适当调整一些配置参数,如果有必要的话,还需要进行集群扩容等。其中,关于配置文件,我在网上搜索了很多答案,有csdn、博客园等很多文章,发现都大同小异~也就阿里云的redis配置手册要专业很多。因此,想借助本次机会,自己把redis的配置文件好好的梳理解读一遍,一方面是加深自己的理解,另一方面是将汇成本篇1万2千多字纯手打的记录总结,供大家参考讨论。如有不对之处,请不吝赐教!

Redis的配置文件

  在redis中,配置文件主要有普通配置文件、sentinel配置文件和cluster-node配置文件。我们重点关注普通配置文件。

普通配置文件

配置模块 说明
INCLUDES 主要用于引入额外的配置文件
NETWORK 网络连接相关的配置模块
GENERAL 通用的配置模块
SNAPSHOTTING rdb持久化配置模块
REPLICATION 主从配置模块
SECURITY 安全配置模块
LIMITS 内存限制等配置模块
APPEND ONLY MODE aof持久化配置模块
LUA SCRIPTING lua脚本配置模块
REDIS CLUSTER cluster集群模式配置模块
SLOW LOG 慢日志配置模块
LATENCY MONITOR 延迟监控配置模块
ADVANCED CONFIG 高级配置模块

INCLUDES

配置名称:include
作用:引入额外的配置文件。
使用示例:include \etc\redis\conf\shared.conf
说明:如果在一台服务器上有多台redis实例,则可以将一些公共的配置抽取出来,在具体的redis实例的配置文件是使用include引入即可让这些配置生效。
注意:redis支持配置更新,比如在client端通过CONFIG REWRITE或者sentinel模式下来修改配置。但是无论用哪一种方式都无法对include配置进行覆盖。比如在client端执行:config rewrite include .\new_shared.conf,server端会抛出异常提示。

NETWORK

配置名称:bind
作用:绑定指定IP来访问redis server。默认值:bind 127.0.0.1
说明:通过bind配置,能够确保redis server在没有任何保护措施的情况下,避免外网的恶意连接。

配置名称:protected-mode
作用:保护模式是redis的一个安全策略。默认为yes,即开启保护模式。
说明:在开启的情况下,对于内网而言,此配置没有任何影响。对于外网而言,如果外网想要连接redis server,则必须通过bind 绑定该外网ip或者通过访问密码才能连接。

配置名称:port
作用:redis server的监听端口,默认为6379
说明:如果port设置为0,则redis server将不会监听任何字端口。

配置名称:tcp-backlog
作用:设置TCP的已连接队列大小,默认为511.
说明:Linux内核为每个TCP服务程序维护了两条backlog,1条是TCP层的未连接队列,1条是应用层的已连接队列。分别对应net.ipv4.tcp_max_syn_backlog和net.core.somaxconn两个内核参数。
1个客户端连接在完成TCP 3次握手之前首先会进入到未连接队列,完成握手正式建立连接之后会进入到已连接队列,交付给应用程序处理。应用程序调用accept()函数从已连接队列中获取连接进行处理。应用层在调用listen()函数时指定的backlog参数就是已连接队列的大小。如果大于somaxconn,则取somaxconn的值。
已连接队列满了的话,会导致未连接队列中的连接经过3次握手之后无法进入到已连接队列,如果情况不容乐观的话,最终也会导致未连接队列堆满。对于客户端而言,客户端连接将会一直处于SYNC_SENT状态,最终导致连接超时。
对于redis而言,如果在超高并发或者长阻塞连接较多的场景下,很可能会因为已连接队列满导致connection timeout,遇到这种情况,可以适当调大该值。

配置名称:timeout
作用:客户端空闲N秒后连接将变成空闲连接,0表示禁用此配置。
说明:timeout仅是server端判断客户端是否变成空闲连接,而不是直接断开该连接。我们可以通过 client list来查看server端的连接信息,其中的idle值就表示空闲时长。

配置名称:tcp-keepalive
作用:server端每N秒判断连接列表中是否存在空闲连接,如果存在,则server端主动关闭这个连接。可以看到,该配置和timeout配置是有一定的依赖关系。默认为0,即不判断,redis官方建议设置为60s。
说明:当server端主动断开连接之后,客户端会收到该通知。此时,客户端会依据自己的连接池策略来做出相应的处理。以spring-redis为例,当监听到连接断开事件时,触发策略。我们假设min-idel-conn=1,如果server端将所有空闲连接都断开了,而client端又要求必须最少有一个空闲连接,那么此时client端就会重新创建一个新的连接。
在实际项目中,至少要保证server端和client端有一方设置里连接管理策略,通常我们更倾向于将在client端设置。如果两端都没有配置的话,那么通过连接激增之后,server端会拥有大量的连接,这里面有很多连接实际上已经无用了,如果不及时清除,会导致客户端无法创建新的连接从而导致客户端连接异常。

GENERAL

配置名称:loglevel
作用:配置redis server端的日志级别。有debug/verbose/notice/warning四个级别。默认为notice
说明:如果想要获取更详细的信息,可以将其设置为debug或者verbose。但是在生产环境中,选择默认级别或者warning即可。

配置名称:logfile
作用:redis server的日志文件,如果没有配置的话,则是控制台输出。默认没有配置。

配置名称:syslog-enabled 作用:是否将日志记录到系统日志中,如需要,则设置为yes,默认为no 说明:无论是记录到logfile还是syslog中,都受到loglevel的控制。

配置名称:syslog-ident
作用:设置redis在syslog中的identity,默认值为redis。

配置名称:databases
作用:redis中数据库的数量,默认为16. db0~db15。 说明:注意,redis默认使用db0数据库,如果要切换数据库,则可以使用select [db_number]进行切换。另外,只有在单机版中才能切换数据库,如果在集群模式下,则只能使用db0.

SNAPSHOTTING [快照]

SNAPSHOTTING模块的配置主要针对redis rdb持久化方式的设置。

配置名称:save 作用:save [seconds] [changes],即配置rdb生成快照的条件。比如:【save 1 10】则为,在1s以内,如果更新操作超过了10次,则触发生成rdb快照文件。
说明:save可以配置多个,每个配置都会生效。如果想关闭rdb快照功能,则配置为【save ""】 即可。

配置名称:stop-writes-on-bgsave-error
作用:当bgsave执行失败时,是否禁止增删改操作,默认为yes。
说明:redis通过bgsave来fork一个子进程生成快照,这样可以不阻塞主线程,主线程依然可以接收增删改查等命令。当bgsave失败时,将依据此配置来决定主线程是否能继续接收增删改命令。通常bgsave失败的情况有:文件没有读写权限、内存空间不够(rdb持久化时,内存消耗几乎翻倍)。

配置名称:rdbcompression
作用:是否启动rdb文件压缩,默认值是yes。
说明:启动压缩会节省空间,但是在生成快照期间会消耗更多的CPU。

配置名称:dbfilename
作用:rdb持久化存储的文件名。默认为dump.rdb

配置名称:dir 作用:工作目录,默认为redis的安装目录。
说明:当配置了dir之后,如果其他和路径相关的配置不是绝对路径的话,则默认路径为dir,比如dbfilename配置为dump.rdb,则绝对路径就为dir/dump.rdb

REPLICATION

REPLICATION模块是集群模式下,master-slave主从复制相关的配置。

配置名称:slaveof
作用:slaveof [master_ip] [master_port]。 即当前节点复制master_ip:master:port所在的节点,理所当然地当前节点就作为从节点。

配置名称:masterauth
作用:配置master节点的server密码,即在master配置文件中的requirepass配置。
说明:如果master配置了auth,则从节点必须配置masterauth,否则master将拒绝slave服务器的请求。

配置名称:slave-serve-stale-data
作用:当slave失去了与master的连接或者slave正在同步数据时,slave将根据此配置决定如何回应client端。如果是【yes】,则slave仍然可以正常响应client的请求,但此时client端获取的数据有可能是脏数据(毕竟断开了连接无法同步数据或者同步数据未完成)。如果是【no】则slave会回复一个异常信息给客户端。默认配置为【no】

配置名称:slave-read-only
作用:slave服务器是否只读。如果为yes,则只读,如果为no,则接受写命令。默认值为yes。
说明:在master-slave模式下,建议开启此配置,以尽可能保障数据一致性。

配置名称:repl-diskless-sync
作用:master和slave同步数据是否借助磁盘。如果为yes则借助磁盘,如果为no,则直接通过socket传输。默认值为no。
说明:如果借助磁盘,master会将rdb文件先写到磁盘,再传给slave;如果不借助磁盘,则master会直接在内存中生成rdb文件然后通过socket传输给slave,这种方式适用于磁盘读写速度慢且网络带宽高的情况。目前,diskless-sync尚处于试验阶段,因此默认值为yes。

配置名称:repl-diskless-sync-delay
作用:如果开启了diskless-sync配置的话,那么master在同步之前先等待延迟指定时间,默认为5s
说明:这一点很有用。因为master一旦启动了socket传输,将不能再为这之后而来的slave传输数据,必须等到下一次了。如果开启等待延迟的话,那么master会延迟N秒,目的是尽可能的汇集更多的slave同步请求

配置名称:repl-ping-slave-period
作用:slave给master发送ping的时间间隔,默认为 10s
说明:可以理解为alave和master之间的心跳检测间隔时长。

配置名称:repl-timeout
作用:slave与master之间的超时时间。 默认为60s
说明:slave会每隔repl-ping-slave-period配置的时间ping一次master,如果连续在repl-timeout时间内都没有ping通master,slave将认为master挂了。repl-timeout的值建议要设置的比repl-ping-slave-period值大,否则只要有1次没有ping通就认为master挂了。

配置名称:repl-disable-tcp-nodelay
作用:在slave与master同步(sync/psync)之后,后续的同步是否开启tcp-nodelay? 默认值为 no
说明:如果开启,则master会合并小的tcp包从而节省宽带,但是会增加同步延迟。对于redis而言,内存和宽带是最主要的资源。所以如果宽带确实吃紧并能够接受一定的同步延迟,则可以开启此配置。

配置名称:repl-backlog-size
作用:积压缓冲区大小,默认为1mb
说明:当slave重连之后,为了保证数据一致性,需要重新复制master的rdb文件。redis采用积压缓冲区的方式在一定程度上避免全量复制rdb:在失联期间,master将失联时产生的增量数据写入到挤压缓冲区,待salve重连之后,只需要将挤压缓冲区的数据同步给salve即可。如果数据量超过了积压缓冲区,则还是需要全量复制。

配置名称:repl-backlog-ttl
作用:积压缓冲区有效时长,默认为3600s
说明:当salve与master断开连接之后,master会将增量数据写入到积压缓冲区,但是如果失联时间超过了repl-backlog-ttl的话,那么master会清除缓冲区的数据,如果salve在这之后重新连接上,则仍然需要全量复制。

配置名称:slave-priority
作用:slave的优先级,值越低,优先级越高。默认值为100
说明:在sentinel或者cluster模式下,如果master挂掉了,则需要在从节点中选举一个master出来。优先级高的将优先被选中。需要注意的是并不是优先级越高就越有可能被选中,具体能否选中还要看其他的一些条件,比如要看slave的数据是否最新等等。另外,slave-priority如果配置为0的话,则此slave将永远不会被选为master,这一点需要注意。

配置名称:min-slaves-to-writemin-slaves-max-lag
作用:对于master而言,如果slave数量小于min-slaves-to-write 或者 任意一个slave的延迟大于min-slaves-max-lag的话,master都将不接收写操作。二者分别的默认值为:3 和 10
说明:在实际项目中,如果在意高可用,则可以将min-slaves-to-write设置为0,min-slaves-max-lag尽量设置大,如果更追求一致性,则相反。

SECURITY

配置名称:requirepass
作用:redis server的密码,在连接时需要进行验证。
说明:通常情况下,bind、requirepass、protected-mode这三个配置虽然作用不同,但都对于rediser server的安全性很重要。

配置名称:rename-command
作用:对命令进行更名,比如 rename-command CONFIG "dfadfdasgdsfas" 说明:在生产环境中,将一些敏感的、危险的命令进行重新命名,以防止被误执行,同时一定程度上提升了rediser server的安全性。

LIMITS

配置名称:maxclients
作用:redis server能够接受的client连接数最大值,默认为10000

配置名称:persistence-available
作用:开启或者关闭持久化功能,默认[yes]即开启,如果要关闭持久化则配置成 [no]。
说明:如果存在slave,则就算关闭了持久化功能,依然会生成rdb文件并同步给salve。这一点要注意区别。

配置名称:maxmemory
作用:redis所管理的最大内存值。默认没有配置。
说明:如果配置了该值,那么当内存满了后,将根据对应的内存淘汰策略进行处理。

配置名称:maxmemory-policy
作用:内存淘汰策略,默认为noevication
说明:目前redis的内存淘汰策略有以下几种:

名称 解释
noevication 不接受任何写命令,能接受get等读命令以及del命令,该策略是默认策略
volatile-lru 在设置了过期时间的key中,删除最近最少使用的key
volatile-ttl 在设置了过期时间的key中,删除最接近过期时间的key
vaolatile-random 在设置了过期时间的,随机删除key
allkeys-lru 在所有key中,删除最近最少使用的key
allkeys-random 在所有key中,随机删除key

配置名称:maxmemory-samples
作用:当使用的淘汰策略是基于lru或者ttl时,redis将随机选出指定的key出来作为一组数据判断。默认值为5.
说明:基于lru或者ttl时,redis并不是在所有符合条件的key中的执行淘汰策略,而是随机选出一批数据出来基于lru或者ttl策略进行淘汰。redis之所以没有使用真正的lru或者ttl算法来执行,是为了节省内存使用,在效果上他们几乎是等价的。这个值配置的越大,那么内存淘汰的精度就越高,但是会更消耗内存和CPU,这个值配置的越小,那么速度就越快,相应的会牺牲一定的精度。

APPEND ONLY MODE

配置名称:appendonly
作用:是否开启aof持久化 默认为yes
说明:redis目前同时支持rdb和aof这两种持久化方式,并且这二者是可以并存的。当二者并存的时候,redis重启时会优先使用aof文件,因为一般情况下aof文件比rdb文件的数据更精准。并且在redis4.0之后,redis持久化策略支持aof和rdb混合模式。

配置名称:appendfilename
作用:aof文件名,默认为appendonly.aof

配置名称:appendfsync
作用:aof持久化策略。有三种模式可选。always:每执行一次写操作,redis就执行1次fsync;everysec:每秒执行一次;no:redis不主动执行,有系统本身决定。默认值为everysec
说明:always最安全,但开销最大;no开销最小,但最不安全。everysec是折中方案。

配置名称:no-appendfsync-on-rewrite
作用:bgrewriteaof和fsync同时执行时,appendfsync的策略是否相当于no?默认的配置为no,即appendfsync策略不变。
说明:之所以有这个配置,是因为bgrewriteaof 和fsync都要操作磁盘,但bgrewriteaof相比fsync而言,会更大量的进行磁盘IO,因此势必会阻塞主进程的fsync,从而阻塞整个主进程,这个时候no-appendfsync-on-rewrite配置就登场了。当该配置为yes时,就是说在进行bgrewriteaof时,fsync的策略临时为no,即临时由系统本身决定什么时候执行fsync。

配置名称:auto-aof-rewrite-percentageauto-aof-rewrite-min-size
作用:redis会自动执行bgrewriteaof命令,但条件是必须同时满足上面两个条件:auto-aof-rewrite-percentage:当前aof文件大小超过刚启动时aof大小的百分比,默认值100%;auto-aof-rewrite-min-size:当前aof文件要大于该配置的值,该配置的值默认为64mb。

配置名称:aof-load-truncated
作用:redis加载aof文件报错时的策略。加载时发现aof文件尾部不正确时,如果为yes:会向客户端写入错误log,并继续执行;如果为no:停止加载。

LUA SCRIPTING

配置名称:lua-time-limit
作用:lua脚本执行时长配置。默认为5000ms。
说明:如果lua脚本执行的时间超过了此配置。那么lua脚本本身会继续执行,但是其他客户端在执行命令时,redis server会响应一个错误:“Busy Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.”。此时如果要停止lua脚本的话,可以使用script kill命令来关闭正在执行的lua脚本(注意,此命令会关闭所有正在执行的脚本),另外,如果脚本已经执行过写操作了,则会无视script kill命令,继续执行。如果非要关闭lua脚本,则只有关闭redis server了。可见,lua脚本要合理使用!

REDIS CLUSTER

配置名称:cluster-enabled
作用:开启cluster模式。默认为no
说明:一个普通的redis server无法成为cluster集群的一部分,如果要让一个节点成为cluster一部分的话,则需要开启此节点。

配置名称**:cluster-config-file**
作用:集群配置文件名称。默认为nodes-6379.conf
说明:集群中每个节点都有一个集群配置文件,这个文件不需要人为编辑,它有redis自己维护,我们只需要指定其配置文件名称即可。

配置名称:cluster-node-timeout
作用:在集群中,节点故障判断时长,默认为15000ms。
说明:如果node节点在指定时间内联系不上,则认为该节点故障。

配置名称:cluster-slave-validity-factor
作用:从节点有效因子。默认为10.
说明:redis集群在进行故障转移时,除了会衡量从节点的优先级(slave-priority配置)之外会衡量从节点的数据“老旧”程度,如果某个从节点的数据太老,则它也不会被升级为主节点。判断从节点的数据老旧程度从两方面来判断:1.判断增量数据的复制偏移量,根据增量数据偏移量得出从节点的数据新旧程度。2.判断最近连接时间,如果从节点和主节点的交互太旧,则该从节点也不会参与故障转移。第1点有redis集群决定,用户无法干预;第2点则可以根据配置来进行干预。
具体干预如下:如果从节点自上次交互以来的时间 > cluster-node-timeout * cluster-slave-validity-factor + repl-ping-slave-period.那么该从节点是不会参与故障转移(即不会被选举为master的)。

配置名称:cluster-migration-barrier 作用:集群分配从节点时的“移民障碍”, 默认为1,即要保证master至少有1个slave节点。
说明:在集群中,为了尽量让从节点分配均匀,采用了“移民障碍”的方式,即只要保证master有指定个数的从节点,在满足这个条件的前提下,如果master有多余的从节点,则可以根据需要被分配到其他master下。

配置名称:cluster-require-full-coverage
作用:是否需要覆盖全slot,集群才可用。默认为yes
说明:cluster集群中总共有16384个slot,如果该配置为yes,则分片要覆盖所有的slot,否则整个集群不可用。

SLOW LOG

配置名称:slowlog-log-slower-than
作用:命令执行时长阈值,如果超过该配置,则记录到慢日志。改配置的单位为微秒,默认值为10000微秒。

配置名称:slowlog-max-len
作用:慢日志记录条数,当超过该配置时,采用FIFO的方式移除旧记录。默认值为128

ADVANCED CONFIG

配置名称:hash-max-ziplist-entrieshash-max-ziplist-value 作用:针对hash底层数据结构的转换。满足任意条件时,hash底层的数据结构将由ziplist将转换为dict。hash-max-ziplist-entries:ziplist最大entry个数,默认为512;hash-max-ziplist-value:entry长度的阈值,默认为64.

配置名称:list-max-ziplist-size
作用:list数据结构中ziplist的分配。默认值为-2
说明:redis的list数据类型的底层结构是quicklist,quicklist实际上是一个双向链表 + ziplist,这是一种空间和时间上的折中方案。该参数表示一个quicklist节点包含的ziplist的个数或者大小。如果该配置 > 0,则表示一个quicklist包含的ziplist的个数;如果该值 < 0,则表示ziplist的大小,取值为-1~-5,分别对应2^2 ~ 2^6 byte。

配置名称:list-compress-depth
作用:list数据结构的压缩策略。默认为0,即不压缩。
说明:在列表很长的情况下且列表两端访问频率高,中间访问频率低的情况下,可根据实际情况配置,来压缩中间的数据以进一步节省空间。加入配置为2,则quicklist头尾各2个节点不压缩,中间的开始压缩。以此类推。

配置名称:set-max-intset-entries
作用:当set数据结构保存的都是整型数据时,redis会选择intset作为set的底层数据结构。当元素个数超过该配置的值时,将会有intset转换为dict。默认值为512

配置名称:zset-max-ziplist-entrieszset-max-ziplist-value
作用:针对sorted set底层数据结构的转换。满足任意条件时,sorted set底层数据结构将有ziplist转换为skiplist。zset-max-ziplist-entries:ziplist的entry数量阈值,默认为512;zset-max-ziplist-value:ziplist任一entry大小阈值,默认为64

配置名称:hll-sparse-max-bytes
作用:HyperLogLog的存储策略。如果hll的基数大于该配置,则采用稠密矩阵来存放(此时一个key占用12kb),否则采用稀疏矩阵存放(此时一个key比12kb小)。默认值为3000。
说明:如果我们更在意内存资源的话,则可以将该值适当设置大一点,官方建议10000;另外,如果超过了16000,则几乎没有任何效果。因此很少有基数达到16000时redis还依然能够采用稀疏矩阵存放。

配置名称:activerehashing
作用:redis自动渐进式rehash配置。默认为yes。 说明:如果开启该配置,则redis会每100ms使用1ms的时间对hash表进行rehash(渐进式)。由于redis的hash扩容机制对内存不是特别友好,因此需要时不时的rehash来降低内存的消耗。如果一次性rehash的话,延迟会比较明显,从而造成阻塞,特别是当map entry特别多时;因此redis采用“小步快跑”的方式完成rehash,这样的话,延迟就不会特别明显了(但仍然会有延迟的,只要有rehash就有延迟)。如果我们完全不接受任何延迟的话,则可以将该选项配置为no,但这样对于系统不太友好(尤其是内存),因此作者也建议保持默认配置。

配置名称:client-output-buffer-limit
作用:对于redis而言,可以基于客户端输出缓冲区限制来断开连接。client-output-buffer-limit [class] [hard limit] [soft limit] [soft seconds]
说明:这里的客户端有且只有3种。normal:普通客户端;slave:从节点;pubsub:发布订阅模式中的订阅者。硬限制:即只要客户端输出缓冲区超过该值,立马断开连接;软限制:如果在soft seconds时间内,持续超过soft limit,则立马断开连接。

配置名称:hz
作用:redis执行后台的任务(清除过期key,检查空闲连接等)的频率。默认为10hz,即执行频率 = 1s/10 = 100ms,意思就是没100ms就执行一次后台任务。
说明:改配置值越大,执行频率越高,redis的响应也就越快,但是会消耗更多资源。该值的有效值范围为1~500,但通常超过100就不是好主意了。作者建议采用默认值即可。

配置名称:aof-rewrite-incremental-fsync
作用:在aof文件重写的时候,如果该配置为yes,则系统会每32mb执行一次fsync。默认配置为yes

总结

  这次配置文件总结梳理,让我对redis的使用心得和优化又有了新的认识,尤其是redis cluster这块。学无止境,继续加油!