redis版本: 6.0.16
Units
- 配置数据单位换算关系
################## 该部分用于指定存储单位的大小换算关系,不区分大小写,只支持bytes,不支持bits # 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.
包含其它配置文件的信息 include path
对于公共部分配置,可以按以下方式配置引入
# include /path/to/local.conf # include /path/to/other.conf
Network 网络相关
- bind IP1 [IP2 …]
这项配置绑定的IP并不是远程访问的客户端的IP地址,而是本机的IP地址。
# bind 192.168.1.100 10.0.0.1 # bind 127.0.0.1 ::1 bind 127.0.0.1
本机的IP地址是和网卡(network interfaces)绑定在一起的,配置这项后,Redis只会接收来自指定网卡的数据包。比如我的主机有以下网卡:
root@VM-4-5-ubuntu:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.4.5 netmask 255.255.252.0 broadcast 10.0.7.255 inet6 fe80::5054:ff:fe0b:843 prefixlen 64 scopeid 0x20<link> ether 52:54:00:0b:08:43 txqueuelen 1000 (Ethernet) RX packets 283943 bytes 28027507 (28.0 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 280878 bytes 43033240 (43.0 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 35168 bytes 2582220 (2.5 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 35168 bytes 2582220 (2.5 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
如果我想要让Redis可以远程连接的话,就需要让Redis监听eht0这块网卡,也就是要加上配置bind 127.0.0.1 10.0.4.5,这样既可以本地访问,也能够远程访问。(主要bind只能有一行配置,如果有多个网卡要监听,就配置多个ip,用空格隔开,否者只有配置的最后一个bind生效)。
- 保护模式 protected-mode
从注释信息就可以看到,如果protected-mode
是yes
的话,如果没有指定bind
或者没有指定密码,那么只能本地访问。
protected-mode yes
- 端口号 port
配置Redis监听的端口号,默认6379。
# Accept connections on the specified port, default is 6379 (IANA #815344). # If port 0 is specified Redis will not listen on a TCP socket. port 6379
- TCP半连接队列长度配置 tcp-backlog
在进行TCP/IP连接时,内核会维护两个队列
syns queue
用于保存已收到sync
但没有接收到ack
的TCP半连接请求。由/proc/sys/net/ipv4/tcp_max_syn_backlog
指定,我的系统(Ubuntu20.04)上是1024。accept queue
,用于保存已经建立的连接,也就是全连接。由/proc/sys/net/core/somaxconn
指定。
根据配置里的注释,需要同时提高somaxconn
和tcp_max_syn_backlog
的值来确保生效。
tcp-backlog 511
- 是否超时无操作关闭连接 timeout
客户端经过多少时间(单位秒)没有操作就关闭连接,0代表永不关闭。
timeout 0
- TCP连接保活策略 tcp-keepalive
TCP连接保活策略,可以通过tcp-keepalive配置项来进行设置,单位为秒,假如设置为60秒,则server端会每60秒向连接空闲的客户端发起一次ACK请求,以检查客户端是否已经挂掉,对于无响应的客户端则会关闭其连接。如果设置为0,则不会进行保活检测。
tcp-keepalive 300
GENERAL 通用配置
- 启动方式 daemonize
是否以守护(后台)进程的方式启动,默认no。
daemonize yes
- 进程pid文件 pidfile
redis启动后会把pid写入到pidfile指定的文件中。
pidfile /var/run/redis_6379.pid
- 进程pid文件 pidfile
redis启动后会把pid写入到pidfile指定的文件中。
pidfile /var/run/redis_6379.pid
- 日志相关 loglevel logfile
loglevel
用于配置日志打印机别,默认notice
:
debug
:能设置的最高的日志级别,打印所有信息,包括debug信息。verbose
:打印除了debug
日志之外的所有日志。notice
:打印除了debug
和verbose
级别的所有日志。warning
:仅打印非常重要的信息。
loglevel notice logfile ""
- 指定数据库的数量 databse
redis默认有16个数据库,编号从0开始。
databases 16
- 启动是否显示logo
always-show-logo yes
SNAPSHOTTING 快照相关
SECURITY 安全相关
################################## SECURITY ################################### # Warning: since Redis is pretty fast, an outside user can try up to # 1 million passwords per second against a modern box. This means that you # should use very strong passwords, otherwise they will be very easy to break. # Note that because the password is really a shared secret between the client # and the server, and should not be memorized by any human, the password # can be easily a long string from /dev/urandom or whatever, so by using a # long and unguessable password no brute force attack will be possible.
大致意思就是redis很快,所以被破解密码时,性能也很好,如果你的密码太渣渣了,那么可能很快就被破解了,因此尽量使用长且不容易被猜到的密码作为redis的访问密码。
配置ACL
ACL
:访问控制列表。
有两种方法配置ACL:
- 在命令行通过ACL命令进行配置
- 在Redis配置文件中开始,可以直接在
redis.conf
中配置,也可以通过外部aclfile
配置。aclfile path
。
配置语法:user ... acl rules ...
,例如 user worker +@list +@connection ~jobs:* on >ffa9203c493aa99
redis默认有一个default
用户。如果default
具有nopass
规则(就是说没有配置密码),那么新连接将立即作为default
用户登录,无需通过AUTH
命令提供任何密码。否则,连接会在未验证状态下启动,并需要AUTH
验证才能开始工作。
描述用户可以做的操作的ACL规则如下:
- 启用或禁用用户(已经建立的连接不会生效)
on
启用用户,该用户可以验证身份登陆。off
禁用用户,该用户不允许验证身份登陆。
- 允许/禁止用户执行某些命令
+
允许用户执行command
指示的命令✅-
禁止用户执行command
指示的命令🈲+@
允许用户执行category
分类中的所有命令✅-@
禁止用户执行category
分类中的所有命令🈲+|subcommand
允许执行某个被禁止的command
的子命令subcommand
。没有对应的-
规则。✅allcommands
+@all
的别名,允许执行所有命令。✅nocommands
-@all
的别名,禁止执行所有命令。🈲
- 允许/禁止用户访问某些Key
~
添加用户可以访问的Key,比如~*
代表用户可以访问所有key,~K*
代表用户可访问以K
开头的key。✅allkeys
等价于~*
✅resetkeys ~
刷新允许模式的列表,会覆盖之前设置的模式。例如user test ~* resetkeys ~K*
,则只允许访问匹配K*
的键,~*
失效。✅
- 为用户配置有效密码
>
将密码添加到用户的有效密码列表中。例如user test >mypass on
,则用户test可以使用mypass
验证。<
将密码从用户的有效密码列表中删除,即不可以使用该密码验证。nopass
使用任意密码都可以成功验证。resetpass
清除用户可用密码列表的数据,并清除 nopass 状态。之后该用户不能登陆。直到重新设置密码/设置nopass
。reset
重置用户到初始状态。该命令会执行以下操作:resetpass
,resetkeys
,off
,-@all
。
- ACL日志配置
设置ACL日志最大长度,默认128个记录。这个日志是存在内存里的。
acllog-max-len 128
- 外部ACL文件配置
默认位置etc/redis/users.acl
,我们可以在这个文件中定义所有用户的ACL
控制信息。
aclfile /etc/redis/users.acl
- 配置默认用户default的密码
该配置只对默认用户default
生效。
requirepass yourpass
CLIENTS 客户端配置
- 设置最大同时客户端连接数
设置可以同时连接客户端的最大数量。默认该项设置为 10000 个客户端。达到限制值后的连接会被拒绝并会返回错误信息。
maxclients 10000
MEMORY MANAGEMENT 内存管理
- 最大内存限制
指定Redis最大内存限制。达到内存限制时,Redis将尝试删除已到期或即将到期的Key。
maxmemory <bytes>
- 达到最大内存限制时的策略
配置达到最大内存限制后,Redis进行何种操作。默认noeviction
maxmemory-policy noeviction
总共有8种策略可供选择。
volatile-lru
只对设置了过期时间的Key进行淘汰,淘汰算法近似的LRU。allkeys-lru
对所有Key进行淘汰,LRU。volatile-lfu
只对设置了过期时间的Key进行淘汰,淘汰算法近似的LFU。allkeys-lfu
对所有Key进行淘汰,LFU。volatile-random
只对设置了过期时间的Key进行淘汰,淘汰算法为随机淘汰。allkeys-random
对所有Key进行淘汰,随机淘汰。volatile-ttl
只对设置了过期时间的Key进行淘汰,删除即将过期的即ttl最小的。noeviction
永不删除key,达到最大内存再进行数据装入时会返回错误。
对于可以通过删除key来释放内存的策略,如果没有key可以删除了,那么也会报错。
- 使用LRU/LFU/TTL算法时采样率
Redis使用的是近似的LRU/LFU/minimal TTL算法。主要是为了节约内存以及提升性能。Redis配置文件有maxmemory-samples
选项,可以配置每次取样的数量。Redis每次会选择配置数量的key,然后根据算法从中淘汰最差的key。
maxmemory-samples 5
可以通过修改这个配置来获取更高的淘汰精度或者更好的性能。默认值5就可以获得很好的结果。选择10可以非常接近真是的LRU算法,但是会耗费更多的CPU资源。3的话更快但是淘汰结果不是特别准确。
- 从库不淘汰数据
配置Redis主从复制时,从库超过maxmemory
也不淘汰数据。这个配置主要是为了保证主从库的一致性,因为Redis的淘汰策略是随机的,如果允许从库自己淘汰key,那么会导致主从不一致的现象出现(master节点删除key的命令会同步给slave节点)。
replica-ignore-maxmemory yes
- 过期keys驻留在内存中的比例
设置过期keys仍然驻留在内存中的比重,默认是为1,表示最多只能有10%的过期key驻留在内存中,该值设置的越小,那么在一个淘汰周期内,消耗的CPU资源也更多,因为需要实时删除更多的过期key。
active-expire-effort 1
LAZY FREEING 懒惰删除
# Redis has two primitives to delete keys. One is called DEL and is a blocking # deletion of the object. It means that the server stops processing new commands # in order to reclaim all the memory associated with an object in a synchronous # way. If the key deleted is associated with a small object, the time needed # in order to execute the DEL command is very small and comparable to most other # O(1) or O(log_N) commands in Redis. However if the key is associated with an # aggregated value containing millions of elements, the server can block for # a long time (even seconds) in order to complete the operation. # # For the above reasons Redis also offers non blocking deletion primitives # such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and # FLUSHDB commands, in order to reclaim memory in background. Those commands # are executed in constant time. Another thread will incrementally free the # object in the background as fast as possible. # DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. # It's up to the design of the application to understand when it is a good # idea to use one or the other. However the Redis server sometimes has to # delete keys or flush the whole database as a side effect of other operations. # Specifically Redis deletes objects independently of a user call in the # following scenarios: # # 1) On eviction, because of the maxmemory and maxmemory policy configurations, # in order to make room for new data, without going over the specified # memory limit. # 2) Because of expire: when a key with an associated time to live (see the # EXPIRE command) must be deleted from memory. # 3) Because of a side effect of a command that stores data on a key that may # already exist. For example the RENAME command may delete the old key # content when it is replaced with another one. Similarly SUNIONSTORE # or SORT with STORE option may delete existing keys. The SET command # itself removes any old content of the specified key in order to replace # it with the specified string. # 4) During replication, when a replica performs a full resynchronization with # its master, the content of the whole database is removed in order to # load the RDB file just transferred. # # In all the above cases the default is to delete objects in a blocking way, # like if DEL was called. However you can configure each case specifically # in order to instead release memory in a non-blocking way like if UNLINK # was called, using the following configuration directives.
翻译上面的话就是:
Redis有两个删除keys的原语。一个是DEL
并且它是一个阻塞的删除对象的操作。意味着server会停止处理新的command
以便以同步的方式回收与对象关联的所有内存。如果被删除的key关联的是一个小对象,那么执行DEL
命令所需要的时间非常短,与Redis中其它O(1)
或O(log_N)
的命令时间开销几乎一样。然鹅,如果key与包含了数百万个元素的大对象相关联,那么服务器为了完成删除命令会阻塞很长时间(甚至几秒钟)。
出于以上原因,Redis提供了非阻塞的删除原语,例如UNLINK
(非阻塞式的DEL
)和FLUSHALL
、FLUSHDB
命令的ASYNC
选项,以便在后台回收内存。这些命令会在常量(固定的)时间内执行。另外一个线程会在后台尽可能快的以渐进式的方式释放对象。
使用DEL
,UNLINK
以及FLUSHALL
和FLUSHDB
的ASYNC
选项是由用户来控制的。这应该由应用程序的设计来决定使用其中的哪一个。 然鹅,作为其它操作的副作用,Redis server有时不得不去删除keys或者刷新整个数据库。具体来说,Redis在以下情况下会独立于用户调用而删除对象:
1) 由于maxmemory
和maxmemory policy
的设置,为了在不超出指定的内存限制而为新对象腾出空间而逐出旧对象;
2) 因为过期:当一个key设置了过期时间且必须从内存中删除时;
3) 由于在已经存在的key上存储对象的命令的副作用。例如,RENAME
命令可能会删除旧的key的内容,当该key的内容被其它内容代替时。类似的,SUNIONSTORE
或者带STORE
选项的SORT
命令可能会删除已经存在的keys。SET
命令会删除指定键的任何旧内容,以便使用指定字符串替换。
4)在复制过程中,当副库与主库执行完全重新同步时,整个数据库的内容将被删除,以便加载刚刚传输的RDB文件。
在上述所有情况下,默认情况是以阻塞方式删除对象,就像调用DEL一样。但是,你可以使用以下配置指令专门配置每种情况,以非阻塞的方式释放内存,就像调用UNLINK
一样。
相关的配置:
# 内存达到设置的maxmemory时,是否使用惰性删除,对应上面 1) lazyfree-lazy-eviction no # 过期keys是否惰性删除,对应上面 2) lazyfree-lazy-expire no # 内部删除选项,对应上面选项 3)的情况是否惰性删除 lazyfree-lazy-server-del no # slave接收完RDB文件后清空数据是否是惰性的,对应上面情况 4) replica-lazy-flush no # It is also possible, for the case when to replace the user code DEL calls # with UNLINK calls is not easy, to modify the default behavior of the DEL # command to act exactly like UNLINK, using the following configuration # directive: # 是否将DEL调用替换为UNLINK,注释里写的从user code里替换DEL调用为UNLINK调用可能并不是一件 # 容易的事,因此可以使用以下选项,将DEL的行为替换为UNLINK lazyfree-lazy-user-del no
THREADED I/O
Redis大体上是单线程的,但是也有一些场景使用额外的线程去做的,比如UNLINK
、slow I/O accesses
。
现在还可以在不同的I/O线程中处理Redis客户端socket读写。(只是网络IO这块儿成了多线程,执行命令的那个家伙,还是单线程!)特别是因为写操作很慢,通常Redis的用户使用pipeline来提升每个核心下的Redis性能,并且运行多个Redis实例来实现扩展。使用多线程I/O,不需要使用pipeline和实例切分,就可以轻松的提升两倍的性能。
默认情况下,多线程是禁用的,我们建议只在至少有4个或更多内核的机器中启用多线程,至少保留一个备用内核。使用超过8个线程不太可能有多大帮助。我们还建议仅当您确实存在性能问题时才使用线程化I/O,因为除非Redis实例能够占用相当大的CPU时间,否则使用此功能没有意义。
redis.conf相关配置翻译
- 配置IO线程数
如果你的机器是4核的,可以配置2个或者3个线程。如果你有8核,可以配置6个线程。通过下面这个参数来配置线程数:
io-threads 4
将io-threads
设置为1将只使用主线程。当启用I/O线程时,我们只使用多线程进行写操作,也就是说,执行write(2)
系统调用并将Client缓冲区传输到套接字。但是,也可以通过将以下配置指令设置为yes
来启用读取线程和协议解析:
io-threads-do-reads no
通常情况下多线程的read并没有什么卵用。
需要注意的两点是:
- 这两个配置不能运行时通过
CONFIG SET
来改变,而且开启SSL功能时,多线程I/O同样不会生效。 - 如果你想用benchmark脚本测试多线程下的性能提升,确保benchmark也是多线程模式,在后面加上
--threads
参数,来匹配Redis的线程数。不然看不到什么性能提升。
KERNEL OOMCONTROL 设置OOM时终止哪些进程
在Linux上,可以提示内核OOM killer在OOM发生时应该首先终止哪些进程。
启用此功能可使Redis根据其角色主动控制其所有进程的oom_score_adj值。默认分数将尝试在所有其他进程之前杀死背景子进程,并在主进程之前杀死从节点进程。
Redis支持三个选项:
no
:对oom-score-adj
不做任何修改(默认值)yes
:relative
的别名absolute
:oom-score-adj-values
配置的值将写入内核relative
:当服务器启动时,使用相对于oom_score_adj
初始值的值,然后将其限制在-1000到1000的范围内。因为初始值通常为0,所以它们通常与绝对值匹配。
oom-score-adj no
当使用oom-score-adj
选项(不为no
)时,该指令控制用于主、从和后台子进程的特定值。数值范围为-2000到2000(越高意味着死亡的可能性越大)。
非特权进程(不是根进程,也没有CAP_SYS_RESOURCE功能)可以自由地增加它们的价值,但不能将其降低到初始设置以下。这意味着将oom score adj设置为“相对”,并将oom score adj值设置为正值将始终成功
# 分别控制主进程、从进程和后台子进程的值 oom-score-adj-values 0 200 800
APPEND ONLY MODE AOF持久化配置
- 开始/关闭aof
appendonly no
- aof文件名称
appendfilename "appendonly.aof"
- 执行fsync()系统调用刷盘的频率
appendfsync everysec
everysec
:每秒执行,可能会丢失最后一秒的数据。always
:每次写操作执行,数据最安全,但是对性能有影响。no
:不强制刷盘,由内核决定什么时候刷盘,数据最不安全,性能最好。- 当有后台保存任务时,关闭appendfsync
当后台在执行save任务或者aof文件的rewrite时,会对磁盘造成大量I/O操作,在某些Linux配置中,Redis可能会在fsync()
系统调用上阻塞很长时间。需要注意的是,目前还没有很好的解决方法,因为即使是在不同的线程中执行fsync()
调用也会阻塞write(2)
调用。
为了缓解上述问题,可以使用以下选项,防止在进行BGSAVE
或者BGREWRITEAOF
时在主进程中调用fsync()
。
这意味这如果有其它子进程在执行saving任务时,Redis的行为相当于配置了appendfsync none
。实际上,这意味着在最坏的情况下(使用Linux默认设置),可能丢失最多30s的日志。
如果您有延迟的问题(性能问题),将此设置为“yes”,否则,设置为“no”。从持久化的角度看,这是最安全的选择。
no-appendfsync-on-rewrite no
- 自动重写aof文件
在AOF文件大小增长到了指定的百分比(相对于上次AOF文件大小的增长量)或者最小体积时,自动调用BGREWRITEAOF
命令重写AOF文件。
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
- AOF文件末尾被截断
在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-load-truncated yes
- 开启混合持久化
当重写AOF文件时,Redis能够在AOF文件中使用RDB前导,以更快地重写和恢复。启用此选项后,重写的AOF文件由两个不同的节组成:
[RDB file][AOF tail]
加载时,Redis识别出AOF文件以“Redis”字符串开头,并加载带前缀的RDB文件,然后继续加载AOF尾部。
aof-use-rdb-preamble yes
【Redis】Redis配置文件详解(二)https://developer.aliyun.com/article/1393283