Redis优化
Redis优化

Redis优化

启动前的可选项优化

(未做优化时启动,会出现三个告警信息)

Tcp backlog

WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128

Tcp backlog 是指TCP的第三次握手服务器端收到客户端 ack确认号之后到服务器用Accept函数处理请求前的队列长度,即全连接队列

三次握手完成后,到第四次开始进行数据交换之间的等待时的队列,这里没有做优化的话可能导致并发效果不理想.

优化方式
#vim /etc/sysctl.conf
net.core.somaxconn = 1024
#sysctl -p

overcommit_memory

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

内核参数overcommit_memory 实现内存分配策略,可选值有三个:0、1、2
0 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则内存申请失败,并把错误返回给应用进程
1 表示内核允许分配所有的物理内存,而不管当前的内存状态如何
2 表示内核允许分配超过所有物理内存和交换空间总和的内存

优化方案
#vim /etc/sysctl.conf
vm.overcommit_memory = 1
#sysctl -p

transparent hugepage

WARNING you have Transparent Huge Pages (THP) support enabled in your kernel.
This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
警告:您在内核中启用了透明大页面(THP,不同于一般4k内存页,而为2M)支持。 这将在Redis中造成延迟和内存使用问题。 要解决此问题,请以root 用户身份运行命令“echo never> /sys/kernel/mm/transparent_hugepage/enabled”,并将其添加到您的/etc/rc.local中,以便在重启后保留设置。禁用THP后,必须重新启动Redis。

优化方案
#echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
永久修改需要通过开机配置/etc/rc.d/rc.local

Redis的键值设计

Key的结构

Redis的Key在自定义时,最好遵循以下规则:
·基本格式:[业务名称]:[数据名]:[id]
·长度不超过44字节
·不包含特殊字符

优点:
·可读性强
·避免key冲突
·方便管理(使用可视化工具显示的是 层级结构 清晰明了)
·更节省内存

BigKey的优化

BigKey定义:BigKey通常以key的大小和key中成员的数量来综合判定
·key本身的数据量过大:一个string类型的key,它的值为5MB
·key中成员数过多:一个ZSET(sortedset)类型的key,它的成员数量为10000个
·key中成员的数据量过大:比如一个Hash类型的key,它的成员数量可能不多,但是每个成员的value数据量大
推荐值:
·单个key的value小于10KB
·对于集合类型的key,建议元素数量小于1000

定位BigKey

方法一:命令

redis-cli -a 密码 --bigkeys

[root@rocky8 ~]#redis-cli -a 123456 --bigkeys
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type.  You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest string found so far 'key44' with 79 bytes
[93.00%] Biggest string found so far 'key100' with 80 bytes

-------- summary -------

Sampled 100 keys in the keyspace!
Total key length in bytes is 492 (avg len 4.92)

Biggest string found 'key100' has 80 bytes

0 lists with 0 items (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
100 strings with 7892 bytes (100.00% of keys, avg size 78.92)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
[root@rocky8 ~]#redis-cli -a 123456 get key100
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"value100123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg"

方法二:利用scan

利用scan扫描Redis中的所有key,利用strlen、hlen等命令判断key的长度

127.0.0.1:6379> help scan

  SCAN cursor [MATCH pattern] [COUNT count]
  summary: Incrementally iterate the keys space
  since: 2.8.0
  group: generic

可以配合代码,对16384个槽位分批查询加快定位效率,避免全库扫描造成的堵塞.

方法三:第三方工具

利用第三方工具,如Redis-Rdb-Tools分析RDB快照文件,全面分析内存使用情况

[root@rocky8 ~]#yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel
[root@rocky8 ~]#wget -P /tmp https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz
[root@rocky8 ~]#mkdir -p /opt/python3 
[root@rocky8 ~]#tar -zxvf /tmp/Python-3.7.3.tgz -C /opt/python3
[root@rocky8 ~]#mkdir /usr/local/python3 
[root@rocky8 ~]#cd /opt/python3/Python-3.7.3 
[root@rocky8 ~]#./configure --prefix=/usr/local/python3
[root@rocky8 ~]#make && make install
[root@rocky8 Python-3.7.3]#ln -s /usr/local/python3/bin/python3.7 /usr/bin/python3
[root@rocky8 Python-3.7.3]#ln -s /usr/local/python3/bin/pip3.7 /usr/bin/pip3

[root@rocky8 Python-3.7.3]#python3 -V
Python 3.6.8
[root@rocky8 Python-3.7.3]#sudo yum install python3-devel
[root@rocky8 Python-3.7.3]#sudo pip3 install python-lzf
[root@rocky8 Python-3.7.3]#sudo pip3 install rdbtools

[root@rocky8 data]#rdb -c memory /apps/redis/data/dump.rdb >  /apps/redis/data/dump.csv
[root@rocky8 data]#rdb -c json /apps/redis/data/dump.rdb >  /apps/redis/data/dump.json

rdb -c memory导出后的格式
database:数据库编号
type:数据类型
key:键
size_in_bytes:使用的内存:包括键,值和任何其他开销
encoding:RDB编码类型
num_elements:key中的value的个数
len_largest_element:key中的value的长度
expiry:过期值

#导出以“a”为开头的hash类型且位于数据库ID为0的key
[root@rocky8 data]#rdb --command json -n 0 --type hash --key "user.*"  dump.rdb
[{
"user1":{"name":"shuhong","age":"28"}}]

#查找特定键使用的内存
[root@rocky8 data]#redis-memory-for-key -s  10.0.0.156  -a'123456' -p 6379 user1
Key				user1
Bytes				82
Type				hash
Encoding			ziplist
Number of Elements		2
Length of Largest Element	8

#查看指定数据库中的key:value  
[root@rocky8 data]#rdb -c justkeyvals dump.rdb -n 0

#rdb --command justkeyvals --key ".*key*" dump.rdb 
[root@rocky8 data]#rdb --command justkeyvals --key ".*key11*" dump.rdb
key11 value11123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key15 value15123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key1 value1123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key12 value12123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key16 value16123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key10 value10123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key17 value17123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key18 value18123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key13 value13123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key14 value14123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg,
key19 value19123457909dhfjkasoinawieuhalieuiweunvlaciwmlaiwuehlaiwxlaiwuhlairwghalirg

#导出内存字节排名前3的keys:
[root@rocky8 data]#rdb --command memory --largest 3 dump.rdb
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
0,string,key99,144,string,79,79,
0,string,key97,144,string,79,79,
0,string,key98,144,string,79,79,

#导出字节大于144的key:
[root@rocky8 data]#rdb --command memory --bytes 145 dump.rdb

#只导出key值
rdb -c justkeys dump.rdb|uniq
#只导出vlaue
rdb -c justkeyvals dump.rdb
#取反
rdb -c memory  -o "a.*" dump.rdb

方法四:监控redis网络资源消耗

自定义工具,监控Redis的网络数据,超出预警值时主动告警 (但这个只能知道可能有bigkey存在了,但具体定位还是需要用到上面的方法)

清理BigKey

unlink

127.0.0.1:6379> unlink key100

避免BigKey产生

例如:一个对象存储方式

1.存在一个string中
key:1   {"name":"shuhong","age":"28"}

[root@rocky8 ~]#redis-cli -a 123456 set key"user1" value'{"name":"shuhong","age":"28"}'
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
[root@rocky8 ~]#redis-cli -a 123456 get key"user1" 
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"value{\"name\":\"shuhong\",\"age\":\"28\"}"


2.字段打散了存储
key:1:name    shuhong
key:1:age     28 
[root@rocky8 ~]#redis-cli -a 123456 set key"name1" value"shuhong"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
[root@rocky8 ~]#redis-cli -a 123456 set key"age1" value"28"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
OK
[root@rocky8 ~]#redis-cli -a 123456 get key"name1"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"valueshuhong"
[root@rocky8 ~]#redis-cli -a 123456 get key"age1"
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
"value28"

3.hash方式存储
key:1  name      age   
       shuhong   28   
 [root@rocky8 ~]#redis-cli -a 123456 HSET user1 name shuhong age 28
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
(integer) 2
[root@rocky8 ~]#redis-cli -a 123456 HGETall user1
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
1) "name"
2) "shuhong"
3) "age"
4) "28"

由上可知,当存储User对象这类数据时,最好选择hash结构进行存储,空间占用小,且可以灵活访问对象的任意字段(hash结构存储注意数据类型转化)

当使用hash方式的时候,假如hash类型的key,有100万对field和value,这个key会产生的问题,以及对应的解决方法

存在的问题:
hash的entry数量超过500时,会使用哈希表而不是ZipList,内存占用多
可以通过hash-max-ziplist-entries配置entry上限。但是如果entry过多就会导致BigKey问题

解决方法:
1.拆成string类型(缺点较多,不建议)
2.拆成多个小的hash存储(例如:通过对id进行分组,限制每个hash的数量)

批处理优化

Pipeline优化

1.批处理的优势
单个命令的执行流程
一次命令的响应时间 = 1次往返的网络传输耗时+1次Redis执行命令耗时

应用-----发送命令----> redis
      redis执行命令(mset,mget)
应用<----返回结果----> redis

网络传输耗时: ms毫秒级别 Redis执行命令耗时:us微秒级别
如果执行N条命令,那么N次网络传输往返的耗时将被扩大N倍,而执行命令的耗时可以忽略不记,此时执行N条命令耗时很长,会影响Redis的性能

如果一次网络传输就执行N次命令,那么就可以解决批量数据操作耗时长问题,提高了效率

Redis提供了很多批处理命令,可以实现批量插入数据,例如:
mset
hmset
注: 不要在一次批处理中传输太多命令,否则单次命令占用带宽过多,会导致网络阻塞

由于mset只能对string类型的数据进行批处理,而hmset只能对hash类型的数据进行操作,如果对复杂数据类型处理可以使用 Pipeline

Pipeline类似于一个管道,将命令放入管道中进行传输。
Pipeline的多个命令之间不具备原子性,可能会出现多线程插队等待耗时问题。

集群模式下的批处理

如 mset 或Pipeline这样的批处理需要在一次请求中携带多条命令,而此时如果Redis是一个集群,那批处理命令的多个key必须落在一个插槽中,否则就会导致执行失败。

解决方案

由于hash_tag容易出现数据倾斜,在集群模式下数据倾斜可能会造成单点问题,因此常用并行slot方式实现集群下批处理。在spring整合的redis包中 stringRedisTemplate 有封装好的用法,底层实现时异步的管道传输模式。
例如:stringRedisTemplate.opsForValue().multiSet();

串行slot并行slothash_tag
计算每个key的slot,将slot一致的分为一组,每组都利用pipeline批处理,串行执行各组命令计算每个key的slot,将slot一致的分为一组,每组都利用pipeline批处理,并行执行各组命令将所有key设置一样的hash_tag,所有key的slot会一样
耗时短耗时非常短耗时非常短,实现简单
实现复杂,slot越多,耗时越久实现复杂会造成数据倾斜

服务端优化

部署模式选择

1.哨兵模式(HA)

使用场景:并发量不高的场景,单个主节点就能应付数据写入,使用起来较为简单.


2.集群模式(HA)

使用场景:适用于高并发的场景,多个主节点可以负载大量的数据写入,使用起来比较复杂.

持久化配置

RDB:快照方式

RDB(Redis DataBase):是基于某个时间点的快照,注意RDB只保留当前最新版本的一个快照
RDB 持久化功能所生成的 RDB 文件是一个经过压缩的二进制文件,通过该文件可以还原生成该 RDB 文件时数据库的状态。因为 RDB 文件是保存在磁盘中的,所以即便 Redis 服务进程甚至服务器宕机,只要磁盘中 RDB 文件存在,就能将数据恢复

latest_fork_usec(info信息里看以看到fork进程拷贝内存页消耗的时间,单位微秒)

注意:RDB文件只会保留一个版本,如果需要多版本保留,需要手动实现

实现方式

save: 同步,不推荐使用,使用主进程完成快照,因此会阻赛其它命令执行
bgsave: 异步后台执行,不影响其它命令的执行,会开启独立的子进程,因此不会阻赛其它命令执行,配置文件实现自动保存: 在配置文件中制定规则,自动执行bgsave

AOF:日志方式

在第一次启用AOF功能时,会做一次完全备份,后续将执行增量性备份,相当于完全数据备份+增量变化
如果同时启用RDB和AOF,进行恢复时,默认AOF文件优先级高于RDB文件,即会使用AOF文件进行恢复
在第一次开启AOF功能时,会自动备份所有数据到AOF文件中,后续只会记录数据的更新指令
注意: AOF 模式默认是关闭的,第一次开启AOF后,并重启服务生效后,会因为AOF的优先级高于RDB,而AOF默认没有数据文件存在,从而导致所有数据丢失

#[root@rocky8 redis]#vim etc/redis.conf 
appendonly yes
[root@rocky8 redis]#systemctl restart redis
[root@rocky8 redis]#redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379> 
127.0.0.1:6379> exit
[root@rocky8 redis]#redis-cli -a 123456
127.0.0.1:6379> CONFIG get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> CONFIG set appendonly yes
OK

#[root@rocky8 redis]#vim etc/redis.conf 
appendonly yes

[root@rocky8 redis]#systemctl restart redis

如果主要充当缓存功能,或者可以承受较长时间,比如数分钟数据的丢失, 通常生产环境一般只需启用RDB即可,此也是默认值
如果一点数据都不能丢失,可以选择同时开启RDB和AOF

慢查询

在Redis执行时耗时超过某个阈值的命令,称为慢查询。
由于Redis是单线程执行命令,所以执行一个命令会放入队列中,排队等待执行,此时若一个慢查询耗时较久,队列中等待的命令可能因等待超时出错

默认值10000微妙,建议值1000

慢日志记录的长度默认值128,建议值1000

#获取慢查询日志长度
127.0.0.1:6379> SLOWLOG len

#读取n条慢日志
127.0.0.1:6379> SLOWLOG get [n]

#清空慢日志
127.0.0.1:6379> SLOWLOG reset

内存碎片优化

内存碎片率计算方式:mem_fragmentation_ratio = used_memory_rss / used_memory

如果 mem_fragmentation_ratio > 1.5,说明内存碎片率已经超过了 50%,这时我们就需要采取一些措施来降低内存碎片了

1)如果你使用的是 Redis 4.0 以下版本,只能通过重启实例来解决

2)如果你使用的是 Redis 4.0 版本,它正好提供了自动碎片整理的功能,可以通过配置开启碎片自动整理。

但是,开启内存碎片整理,它也有可能会导致 Redis 性能下降。

原因在于,Redis 的碎片整理工作是也在主线程中执行的,当其进行碎片整理时,必然会消耗 CPU 资源,产生更多的耗时,从而影响到客户端的请求。

所以,当你需要开启这个功能时,最好提前测试评估它对 Redis 的影响。

Redis 碎片整理的参数配置如下:

# 开启自动内存碎片整理(总开关)
activedefrag yes
 
# 内存使用 100MB 以下,不进行碎片整理
active-defrag-ignore-bytes 100mb
 
# 内存碎片率超过 10%,开始碎片整理
active-defrag-threshold-lower 10
# 内存碎片率超过 100%,尽最大努力碎片整理
active-defrag-threshold-upper 100
 
# 内存碎片整理占用 CPU 资源最小百分比
active-defrag-cycle-min 1
# 内存碎片整理占用 CPU 资源最大百分比
active-defrag-cycle-max 25
 
# 碎片整理期间,对于 List/Set/Hash/ZSet 类型元素一次 Scan 的数量
active-defrag-max-scan-fields 1000

Redis 配置文件说明

bind 0.0.0.0 #指定监听地址,支持用空格隔开的多个监听IP

protected-mode yes #redis3.2之后加入的新特性,在没有设置bind IP和密码的时候,redis只允许访问127.0.0.1:6379,可以远程连接,但当访问将提示警告信息并拒绝远程访问

port 6379 #监听端口,默认6379/tcp

tcp-backlog 511 #三次握手的时候server端收到client ack确认号之后的队列值,即全连接队列长度

timeout 0 #客户端和Redis服务端的连接超时时间,默认是0,表示永不超时

tcp-keepalive 300 #tcp 会话保持时间300s

daemonize no #默认no,即直接运行redis-server程序时,不作为守护进程运行,而是以前台方式运行,如果想在后台运行需改成yes,当redis作为守护进程运行的时候,它会写一个 pid 到/var/run/redis.pid 文件

supervised no #和OS相关参数,可设置通过upstart和systemd管理Redis守护进程,centos7后都使用systemd

pidfile /var/run/redis_6379.pid #pid文件路径,可以修改为/apps/redis/run/redis_6379.pid

loglevel notice #日志级别

logfile "/path/redis.log" #日志路径,示例:logfile "/apps/redis/log/redis_6379.log"

databases 16 #设置数据库数量,默认:0-15,共16个库

always-show-logo yes #在启动redis时是否显示或在日志中记录记录redis的logo

save 900 1 #在900秒内有1个key内容发生更改,就执行快照机制
save 300 10 #在300秒内有10个key内容发生更改,就执行快照机制
save 60 10000 #60秒内如果有10000个key以上的变化,就自动快照备份

stop-writes-on-bgsave-error yes #默认为yes时,可能会因空间满等原因快照无法保存出错时,会禁止redis写入操作,生产建议为no #此项只针对配置文件中的自动save有效

rdbcompression yes #持久化到RDB文件时,是否压缩,"yes"为压缩,"no"则反之
rdbchecksum yes #是否对备份文件开启RC64校验,默认是开启
dbfilename dump.rdb #快照文件名
dir ./ #快照文件保存路径,示例:dir "/apps/redis/data"

#主从复制相关
# replicaof <masterip> <masterport> #指定复制的master主机地址和端口,5.0版之前的指令为slaveof
# masterauth <master-password> #指定复制的master主机的密码

replica-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从库有两种运行方式:
1、设置为yes(默认设置),从库会继续响应客户端的读请求,此为建议值
2、设置为no,除去特定命令外的任何请求都会返回一个错误"SYNC with master in progress"。

replica-read-only yes #是否设置从库只读,建议值为yes,否则主库同步从库时可能会覆盖数据,造成数据丢失
repl-diskless-sync no #是否使用socket方式复制数据(无盘同步),新slave第一次连接master时需要做数据的全量同步,redis server就要从内存dump出新的RDB文件,然后从master传到slave,有两种方式把RDB文件传输给客户端:
1、基于硬盘(disk-backed):为no时,master创建一个新进程dump生成RDB磁盘文件,RDB完成之后由父进程(即主进程)将RDB文件发送给slaves,此为默认值
2、基于socket(diskless):master创建一个新进程直接dump RDB至slave的网络socket,不经过主进程和硬盘
#推荐使用基于硬盘(为no),是因为RDB文件创建后,可以同时传输给更多的slave,但是基于socket(为yes), 新slave连接到master之后得逐个同步数据。只有当磁盘I/O较慢且网络较快时,可用diskless(yes),否则一般建议使用磁盘(no)

repl-diskless-sync-delay 5 #diskless时复制的服务器等待的延迟时间,设置0为关闭,在延迟时间内到达的客户端,会一起通过diskless方式同步数据,但是一旦复制开始,master节点不会再接收新slave的复制请求,直到下一次同步开始才再接收新请求。即无法为延迟时间后到达的新副本提供服务,新副本将排队等待下一次RDB传输,因此服务器会等待一段时间才能让更多副本到达。推荐值:30-60

repl-ping-replica-period 10 #slave根据master指定的时间进行周期性的PING master,用于监测master状态,默认10s
repl-timeout 60 #复制连接的超时时间,需要大于repl-ping-slave-period,否则会经常报超时

repl-disable-tcp-nodelay no #是否在slave套接字发送SYNC之后禁用 TCP_NODELAY,如果选择"yes",Redis将合并多个报文为一个大的报文,从而使用更少数量的包向slaves发送数据,但是将使数据传输到slave上有延迟,Linux内核的默认配置会达到40毫秒,如果 "no" ,数据传输到slave的延迟将会减少,但要使用更多的带宽

repl-backlog-size 512mb #复制缓冲区内存大小,当slave断开连接一段时间后,该缓冲区会累积复制副本数据,因此当slave 重新连接时,通常不需要完全重新同步,只需传递在副本中的断开连接后没有同步的部分数据即可。只有在至少有一个slave连接之后才分配此内存空间,建议建立主从时此值要调大一些或在低峰期配置,否则会导致同步到slave失败
repl-backlog-ttl 3600 #多长时间内master没有slave连接,就清空backlog缓冲区
replica-priority 100 #当master不可用,哨兵Sentinel会根据slave的优先级选举一个master,此值最低的slave会优先当选master,而配置成0,永远不会被选举,一般多个slave都设为一样的值,让其自动选择

#min-replicas-to-write 3 #至少有3个可连接的slave,mater才接受写操作
#min-replicas-max-lag 10 #和上面至少3个slave的ping延迟不能超过10秒,否则master也将停止写操作

requirepass foobared #设置redis连接密码,之后需要AUTH pass,如果有特殊符号,用" "引起来,生产建议设置
rename-command #重命名一些高危命令,示例:rename-command FLUSHALL "" 禁用命令

maxclients 10000 #Redis最大连接客户端
maxmemory <bytes> #redis使用的最大内存,单位为bytes字节,0为不限制,建议设为物理内存一半,8G内存的计算方式8(G)*1024(MB)1024(KB)*1024(Kbyte),需要注意的是缓冲区是不计算在maxmemory内,生产中如果不设置此项,可能会导致OOM

#maxmemory-policy noeviction 此为默认值
# MAXMEMORY POLICY:当达到最大内存时,Redis 将如何选择要删除的内容。您可以从以下行为中选择一种:
#
# volatile-lru -> Evict 使用近似 LRU,只有设置了过期时间的键。
# allkeys-lru -> 使用近似 LRU 驱逐任何键。
# volatile-lfu -> 使用近似 LFU 驱逐,只有设置了过期时间的键。
# allkeys-lfu -> 使用近似 LFU 驱逐任何键。
# volatile-random -> 删除设置了过期时间的随机密钥。
# allkeys-random -> 删除一个随机密钥,任何密钥。
# volatile-ttl -> 删除过期时间最近的key(次TTL)
# noeviction -> 不要驱逐任何东西,只是在写操作时返回一个错误。
#
# LRU 表示最近最少使用
# LFU 表示最不常用
#
# LRU、LFU 和 volatile-ttl 都是使用近似随机算法实现的。
#
# 注意:使用上述任何一种策略,当没有合适的键用于驱逐时,Redis 将在需要更多内存的写操作时返回错误。

appendonly no #是否开启AOF日志记录,默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了,但是redis如果中途宕机,会导致可能有几分钟的数据丢失(取决于dump数据的间隔时间),根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。默认不启用此功能

appendfilename "appendonly.aof" #文本文件AOF的文件名,存放在dir指令指定的目录中

appendfsync everysec #aof持久化策略的配置
#no表示由操作系统保证数据同步到磁盘,Linux的默认fsync策略是30秒,最多会丢失30s的数据
#always表示每次写入都执行fsync,以保证数据同步到磁盘,安全性高,性能较差
#everysec表示每秒执行一次fsync,可能会导致丢失这1s数据,此为默认值,也生产建议值

#同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,以下参数实现控制
no-appendfsync-on-rewrite no #在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。
#默认为no,表示"不暂缓",新的aof记录仍然会被立即同步到磁盘,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题
#为yes,相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?Linux的默认fsync策略是30秒,最多会丢失30s的数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐

#rewrite 即对aof文件进行整理,将空闲空间回收,从而可以减少恢复数据时间
auto-aof-rewrite-percentage 100 #当Aof log增长超过指定百分比例时,重写AOF文件,设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,但是还可以确保保存最完整的数据
auto-aof-rewrite-min-size 64mb #触发aof rewrite的最小文件大小
aof-load-truncated yes #是否加载由于某些原因导致的末尾异常的AOF文件(主进程被kill/断电等),建议yes
aof-use-rdb-preamble no #redis4.0新增RDB-AOF混合持久化格式,在开启了这个功能之后,AOF重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB格式的内容用于记录已有的数据,而AOF格式的内容则用于记录最近发生了变化的数据,这样Redis就可以同时兼有RDB持久化和AOF持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据),默认为no,即不启用此功能

lua-time-limit 5000 #lua脚本的最大执行时间,单位为毫秒

cluster-enabled yes #是否开启集群模式,默认不开启,即单机模式
cluster-config-file nodes-6379.conf #由node节点自动生成的集群配置文件名称
cluster-node-timeout 15000 #集群中node节点连接超时时间,单位ms,超过此时间,会踢出集群
cluster-replica-validity-factor 10 #单位为次,在执行故障转移的时候可能有些节点和master断开一段时间导致数据比较旧,这些节点就不适用于选举为master,超过这个时间的就不会被进行故障转移,不能当选master,计算公式:(node-timeout * replica-validity-factor) + repl-ping-replica-period

cluster-migration-barrier 1 #集群迁移屏障,一个主节点至少拥有1个正常工作的从节点,即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。

cluster-require-full-coverage yes #集群请求槽位全部覆盖,如果一个主库宕机且没有备库就会出现集群槽位不全,那么yes时redis集群槽位验证不全,就不再对外提供服务(对key赋值时,会出现CLUSTERDOWN The cluster is down的提示,cluster_state:fail,但ping 仍PONG),而no则可以继续使用,但是会出现查询数据查不到的情况(因为有数据丢失)。生产建议为no

cluster-replica-no-failover no #如果为yes,此选项阻止在主服务器发生故障时尝试对其主服务器进行故障转移。 但是,主服务器仍然可以执行手动强制故障转移,一般为no

#Slow log 是 Redis 用来记录超过指定执行时间的日志系统,执行时间不包括与客户端交谈,发送回复等I/O操作,而是实际执行命令所需的时间(在该阶段线程被阻塞并且不能同时为其它请求提供服务),由于slow log 保存在内存里面,读写速度非常快,因此可放心地使用,不必担心因为开启 slow log 而影响Redis 的速度

slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录,为负数会禁用慢日志,为0会记录每个命令操作。默认值为10ms,一般一条命令执行都在微秒级,生产建议设为1ms-10ms之间

slowlog-max-len 128 #最多记录多少条慢日志的保存队列长度,达到此长度后,记录新命令会将最旧的命令从命令队列中删除,以此滚动删除,即,先进先出,队列固定长度,默认128,值偏小,生产建议设为1000以上