Redis配置文件详解及持久化
Redis:
一、概念及使用场景:
Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
基于内存运行,性能高效
支持分布式,理论上可以无限扩展
key-value存储系统
开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
特点:
redis是开源的,BSD许可,key-value存储系统
内存型数据库
多种数据类型
支持持久化
支持多语言
高可用、分布式
功能丰富(发布订阅、事务、lua脚本)
单线程
redis和memcached的区别:
redis可以做内存数据库存储(storage),memcached是用来做内存缓存(cache),主要是因为redis有持久化功能
redis有多种数据结构包括字符串,hash,list,集合,有序集合,memcached只有字符串
超过100k数据,memcached性能更改,memcached最大value为1M,redis为512M
redis可以做模糊查询,交集并集操作
redis的使用场景:
redis的应用场景包括:缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、排行榜、社交网络和实时系统
redis支持的六大数据类型:
string、hash、list、set、zset、stream(redis5.0新增)
二、配置文件详解:
<1.>INCLUDES
include /path/to/local.conf
额外载入配置文件,如果有需要的话,可以开启此配置
<2>.NETWORK
bind 127.0.0.1
绑定redis服务器网卡IP,默认为127.0.0.1,即本地回环地址。这样的话,访问redis服务只能通过本机的客户端连接,而无法通过远程连接。如果bind选项为空的话,那会接受所有来自于可用网络接口的连接。如上配置,绑定一个127.0.0.1的本机地址和192.168.1.100的外网地址。
protected-mode yes
保护模式,默认是开启状态,只允许本地客户端连接, 可以设置密码或添加bind来连接
port 6379
监听端口号,默认为6379,如果设为0,redis将不在socket 上监听任何客户端连接
tcp-backlog 511
TCP监听的最大容纳数量,在高并发的环境下,你需要把这个值调高以避免客户端连接缓慢的问题。Linux 内核会把这个值缩小成 /proc/sys/net/core/somaxconn对应的值,要提升并发量需要修改这两个值才能达到目的
unixsocket /tmp/redis.sock
unixsocketperm 700
指定redis监听的unix socket路径,默认不启用,unixsocketper指定文件的权限
timeout 0
指定在一个 client 空闲多少秒之后关闭连接(0表示永不关闭)
tcp-keepalive 300
单位是秒,表示将周期性的使用SO_KEEPALIVE检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是300s,如果设置为0,则不会周期性的检测
<3>.GENERAL
daemonize yes
默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes。当redis作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面
supervised no
可以通过upstart和systemd管理Redis守护进程
选项:
supervised no - 没有监督互动
supervised upstart - 通过将Redis置于SIGSTOP模式来启动信号
supervised systemd - signal systemd将READY = 1写入$ NOTIFY_SOCKET
supervised auto - 检测upstart或systemd方法基于 UPSTART_JOB或NOTIFY_SOCKET环境变量
pidfile /var/redis/run/redis_6379.pid
配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面
loglevel notice
定义日志级别。可以是下面的这些值:
debug(记录大量日志信息,适用于开发、测试阶段)
verbose(较多日志信息)
notice(适量日志信息,使用于生产环境)
warning(仅有部分重要、关键信息才会被记录)
logfile /var/redis/log/redis_6379.log
日志文件的位置,当指定为空字符串时,为标准输出,如果redis已守护进程模式运行,那么日志将会输出到/dev/null
syslog-enabled no
要想把日志记录到系统日志,就把它改成 yes,也可以可选择性的更新其他的syslog 参数以达到你的要求
syslog-ident redis
设置系统日志的ID
syslog-facility local0
指定系统日志设置,必须是 USER 或者是 LOCAL0-LOCAL7 之间的值
databases 16
设置数据库的数目。默认的数据库是DB 0 ,可以在每个连接上使用select <dbid> 命令选择一个不同的数据库,dbid是一个介于0到databases - 1 之间的数值。
<4>.SNAPSHOTTING
save 900 1
save 300 10
save 60 10000
存 DB 到磁盘:
格式:save <间隔时间(秒)> <写入次数>
根据给定的时间间隔和写入次数将数据保存到磁盘,上面的例子的意思是:
900 秒内如果至少有 1 个 key 的值变化,则保存
300 秒内如果至少有 10 个 key 的值变化,则保存
60 秒内如果至少有 10000 个 key 的值变化,则保存
注意:你可以注释掉所有的 save 行来停用保存功能。也可以直接一个空字符串来实现停用:
save ""
stop-writes-on-bgsave-error yes
如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求。这样做的好处在于可以让用户很明确的知道内存中的数据和磁盘上的数据已经存在不一致了。如果redis不顾这种不一致,一意孤行的继续接收写请求,就可能会引起一些灾难性的后果。如果下一次RDB持久化成功,redis会自动恢复接受写请求。如果不在乎这种数据不一致或者有其他的手段发现和控制这种不一致的话,可以关闭这个功能,以便在快照写入失败时,也能确保redis继续接受新的写请求。
rdbcompression yes
对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。
rdbchecksum yes
在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
dbfilename dump.rdb
设置快照的文件名
dir /var/redis/6379
设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名
<5>.REPLICATION
slaveof <masterip> <masterport>
主从复制,使用 slaveof 来让一个 redis 实例成为另一个reids 实例的副本,默认关闭
注意:这个只需要在 slave 上配置
masterauth <master-password>
如果 master 需要密码认证,就在这里设置,默认不设置
slave-serve-stale-data yes
当一个 slave 与 master 失去联系,或者复制正在进行的时候,slave 可能会有两种表现:
如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,或者数据可能是空的在第一次同步的时候
如果为 no ,在你执行除了 info he salveof 之外的其他命令时,slave 都将返回一个 "SYNC with master in progress" 的错误
slave-read-only yes
你可以配置一个 slave 实体是否接受写入操作。通过写入操作来存储一些短暂的数据对于一个 slave 实例来说可能是有用的,因为相对从 master 重新同步数而言,据数据写入到 slave 会更容易被删除。但是如果客户端因为一个错误的配置写入,也可能会导致一些问题。从redis 2.6 版起,默认 slaves 都是只读的。
repl-diskless-sync no
主从数据复制是否使用无硬盘复制功能。no表示不使用无盘复制,需要将RDB文件保存到磁盘中在发送给slave。新的从站和重连后不能继续备份的从站,需要做所谓的“完全备份”,即将一个RDB文件从主站传送到从站。
这个传送有以下两种方式:
1)硬盘备份:redis主站创建一个新的进程,用于把RDB文件写到硬盘上。过一会儿,其父进程递增地将文件传送给从站。
2)无硬盘备份:redis主站创建一个新的进程,子进程直接把RDB文件写到从站的套接字,不需要用到硬盘。
在硬盘备份的情况下,主站的子进程生成RDB文件。一旦生成,多个从站可以立即排成队列使用主站的RDB文件。
在无硬盘备份的情况下,一次RDB传送开始,新的从站到达后,需要等待现在的传送结束,才能开启新的传送。
如果使用无硬盘备份,主站会在开始传送之间等待一段时间(可配置,以秒为单位),希望等待多个子站到达后并行传送。在硬盘低速而网络高速(高带宽)情况下,无硬盘备份更好。
repl-diskless-sync-delay 5
当启用无硬盘备份,服务器等待一段时间后才会通过套接字向从站传送RDB文件,这个等待时间是可配置的。
这一点很重要,因为一旦传送开始,就不可能再为一个新到达的从站服务。从站则要排队等待下一次RDB传送。因此服务器等待一段时间以期更多的从站到达。延迟时间以秒为单位,默认为5秒。要关掉这一功能,只需将它设置为0秒,传送会立即启动。
repl-ping-slave-period 10
从redis会周期性的向主redis发出PING包,你可以通过repl_ping_slave_period指令来控制其周期,默认是10秒。
repl-timeout 60
接下来的选项为以下内容设置备份的超时时间:
1)从从站的角度,同步期间的批量传输的I/O
2)从站角度认为的主站超时(数据,ping)
3)主站角度认为的从站超时(REPLCONF ACK pings)
确认这些值比定义的repl-ping-slave-period要大,否则每次主站和从站之间通信低速时都会被检测为超时。
repl-disable-tcp-nodelay no
同步之后是否禁用从站上的TCP_NODELAY。如果你选择yes,redis会使用较少量的TCP包和带宽向从站发送数据。但这会导致在从站增加一点数据的延时。Linux内核默认配置情况下最多40毫秒的延时。如果选择no,从站的数据延时不会那么多,但备份需要的带宽相对较多。
默认情况下我们将潜在因素优化,但在高负载情况下或者在主从站都跳的情况下,把它切换为yes是个好主意。
repl-backlog-size 1mb
复制缓冲区大小,只有在 slave 连接之后才分配内存。
repl-backlog-ttl 3600
多长时间master没有slave连接,就清空backlog 缓冲区。值为0表示不释放。
slave-priority 100
当master不可用,Sentinel 会根据slave的优先级选举一个 master。最低的优先级的 slave,当选 master。而配置成0,永远不会被选举。默认优先级是100。
min-slaves-to-write 3
min-slaves-max-lag 10
主站可以停止接受写请求,当与它连接的从站少于N个,滞后少于M秒,N个从站必须是在线状态。延迟的秒数必须<=所定义的值,延迟秒数是从最后一次收到的来自从站的ping开始计算。ping通常是每秒一次。这一选项并不保证N个备份都会接受写请求,但是会限制在指定秒数内由于从站数量不够导致的写操作丢失的情况。
如果想要至少3个从站且延迟少于10秒,如上配置即可
slave-announce-ip 5.5.5.5
slave-announce-port 1234
redis master能够以不同的方式列出所连接slave的地址和端口。例如,“INFO replication”部分提供此信息,除了其他工具之外,Redis Sentinel还使用该信息来发现slave实例。此信息可用的另一个地方在masterser的“ROLE”命令的输出中。
通常由slave报告的列出的IP和地址,通过以下方式获得:
IP:通过检查slave与master连接使用的套接字的对等体地址自动检测地址。
端口:端口在复制握手期间由slavet通信,并且通常是slave正在使用列出连接的端口。
然而,当使用端口转发或网络地址转换(NAT)时,slave实际上可以通过(不同的IP和端口对)来到达。 slave可以使用以下两个选项,以便向master报告一组特定的IP和端口,以便INFO和ROLE将报告这些值。如果你需要仅覆盖端口或IP地址,则没必要使用这两个选项。
<6>.SECURITY
requirepass foobared
设置redis连接密码
rename-command CONFIG ""
将命令重命名,为了安全考虑,可以将某些重要的、危险的命令重命名。当你把某个命令重命名成空字符串的时候就等于取消了这个命令。
<7>.CLIENTS
maxclients 10000
设置客户端最大并发连接数,默认无限制,Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件,描述符数-32(redis server自身会使用一些),如果设置 maxclients为0表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息
<8>.MEMORY MANAGEMENT
maxmemory <bytes>
指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区。
maxmemory-policy noeviction
当内存使用达到最大值时,redis使用的清楚策略。有以下几种可以选择:
1)volatile-lru 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
2)allkeys-lru 利用LRU算法移除任何key
3)volatile-random 移除设置过过期时间的随机key
4)allkeys-random 移除随机ke
5)volatile-ttl 移除即将过期的key(minor TTL)
6)noeviction noeviction 不移除任何key,只是返回一个写错误 ,默认选项
maxmemory-samples 5
LRU 和 minimal TTL 算法都不是精准的算法,但是相对精确的算法(为了节省内存),随意你可以选择样本大小进行检,redis默认选择3个样本进行检测,你可以通过maxmemory-samples进行设置样本数
<9>.LAZY FREEING
lazyfree-lazy-eviction no (4.0新增)
lazyfree-lazy-expire no(4.0新增)
lazyfree-lazy-server-del no(4.0新增)
slave-lazy-flush no(4.0新增)
<10>.APPEND ONLY MODE
appendonly no
默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入appendonly.aof文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendfilename "appendonly.aof"
aof文件名
appendfsync always|everysec|no
aof持久化策略的配置:
no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。
always表示每次写入都执行fsync,以保证数据同步到磁盘。
everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。
no-appendfsync-on-rewrite no
在aof rewrite期间,是否对aof新记录的append暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。默认为no,表示"不暂缓",新的 aof 记录仍然会被立即同步,Linux 的默认fsync策略是 30 秒,如果为yes可能丢失30秒数据,但由于yes性能较好而且会避免出现阻塞因此比较推荐。
在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。
设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据。
auto-aof-rewrite-percentage 100
当aof log增长超过指定百分比例时,重写log file, 设置为0表示不自动重写Aof日志,重写是为了使aof体积保持最小,而确保保存最完整的数据。
aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。
auto-aof-rewrite-min-size 64mb
设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
aof-load-truncated yes
aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象,redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。
如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。
如果是no,用户必须手动redis-check-aof修复AOF文件才可以。
aof-use-rdb-preamble no (4.0新增)
yes则表示开启,no表示禁用,默认是禁用的,可通过config set修改。RDB-AOF 混合持久化格式,在开启了这个功能之后, AOF 重写产生的文件将同时包含RDB格式的内容和AOF格式的内容,其中RDB 格式的内容用于记录已有的数据,而AOF格式的内存则用于记录最近发生了变化的数据,这样Redis就可以同时兼有 RDB 持久化和AOF 持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据)。
<11>.LUA SCRIPTING
lua-time-limit 5000
如果达到最大时间限制(毫秒),redis会记个log,然后返回error。当一个脚本超过了最大时限。只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一个可以杀没有调write命令的东西。要是已经调用了write,只能用第二个命令杀
<12>.REDIS CLUSTER
cluster-enabled yes
集群开关,默认是不开启集群模式
cluster-config-file nodes-6379.conf
集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
cluster-node-timeout 15000
节点互连超时的阀值,集群节点超时毫秒数
cluster-slave-validity-factor 10
在进行故障转移的时候,全部slave都会请求申请为master,但是有些slave可能与master断开连接一段时间了,导致数据过于陈旧,这样的slave不应该被提升为master。该参数就是用来判断slave节点与master断线的时间是否过长。
判断方法是:
比较slave断开连接的时间和(node-timeout * slave-validity-factor) + repl-ping-slave-period,如果节点超时时间为三十秒, 并且slave-validity-factor为10,假设默认的repl-ping-slave-period是10秒,即如果超过310秒slave将不会尝试进行故障转移
cluster-migration-barrier 1
master的slave数量大于该值,slave才能迁移到其他孤立master上,如这个参数若被设为2,那么只有当一个主节点拥有2个可工作的从节点时,它的一个从节点会尝试迁移。
cluster-require-full-coverage yes
默认情况下,集群全部的slot有节点负责,集群状态才为ok,才能提供服务。设置为no,可以在slot没有全部分配的时候提供服务。不建议打开该配置,这样会造成分区的时候,小分区的master一直在接受写请求,而造成很长时间数据不一致
<13>.CLUSTER DOCKER/NAT support(适用于docker环境)
默认情况下,Redis会自动检测自己的IP和从配置中获取绑定的PORT,告诉客户端或者是其他节点。而在Docker环境中,如果使用的不是host网络模式,在容器内部的IP和PORT都是隔离的,那么客户端和其他节点无法通过节点公布的IP和PORT建立连接
如果开启以下配置,Redis节点会将配置中的这些IP和PORT告知客户端或其他节点。而这些IP和PORT是通过Docker转发到容器内的临时IP和PORT的。
cluster-announce-ip 10.1.1.5 (4.0新增)
cluster-announce-port 6379 (4.0新增)
cluster-announce-bus-port 6380 (4.0新增)
<14>SLOW LOG
slowlog-log-slower-than 10000
slog log是用来记录redis运行中执行比较慢的命令耗时。当命令的执行超过了指定时间,就记录在slow log中,slog log保存在内存中,所以没有IO操作。执行时间比slowlog-log-slower-than大的请求记录到slowlog里面,单位是微秒,所以1000000就是1秒。
注意:负数时间会禁用慢查询日志,而0则会强制记录所有命令。
slowlog-max-len 128
慢查询日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉,这个长度没有限制。只要有足够的内存就行,你可以通过SLOWLOG RESET来释放内存
<15>.LATENCY MONITOR
latency-monitor-threshold 0
延迟监控功能是用来监控redis中执行比较缓慢的一些操作,用LATENCY打印redis实例在跑命令时的耗时图表。只记录大于等于下边设置的值的操作,0的话,就是关闭监视。默认延迟监控功能是关闭的,如果你需要打开,也可以通过CONFIG SET命令动态设置。
<16.>EVENT NOTIFICATION
notify-keyspace-events ""
键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件。因为开启键空间通知功能需要消耗一些 CPU ,所以在默认配置下,该功能处于关闭状态。
notify-keyspace-events 的参数可以是以下字符的任意组合,它指定了服务器该发送哪些类型的通知:
K 键空间通知,所有通知以 keyspace@ 为前缀
E 键事件通知,所有通知以 keyevent@ 为前缀
g DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
$ 字符串命令的通知
l 列表命令的通知
s 集合命令的通知
h 哈希命令的通知
z 有序集合命令的通知
x 过期事件:每当有过期键被删除时发送
e 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
A 参数 g$lshzxe 的别名
输入的参数中至少要有一个 K 或者 E,否则的话,不管其余的参数是什么,都不会有任何 通知被分发。
<17>.ADVANCED CONFIG
hash-max-ziplist-entries 512
hash类型的数据结构在编码上可以使用ziplist和hashtable。ziplist的特点就是文件存储(以及内存存储)所需的空间较小,在内容较小时,性能和hashtable几乎一样。因此redis对hash类型默认采取ziplist。如果hash中条目的条目个数或者value长度达到阀值,将会被重构为hashtable。这个参数指的是ziplist中允许存储的最大条目个数,,默认为512,建议为128
hash-max-ziplist-value 64
ziplist中允许条目value值最大字节数,默认为64,建议为1024
list-max-ziplist-size -2
当取正值的时候,表示按照数据项个数来限定每个quicklist节点上的ziplist长度。比如,当这个参数配置成5的时候,表示每个quicklist节点的ziplist最多包含5个数据项。
当取负值的时候,表示按照占用字节数来限定每个quicklist节点上的ziplist长度。这时,它只能取-1到-5这五个值,每个值含义如下:
-5: 每个quicklist节点上的ziplist大小不能超过64 Kb。(注:1kb => 1024 bytes)
-4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
-3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
-2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(-2是Redis给出的默认值)
-1: 每个quicklist节点上的ziplist大小不能超过4 Kb。
list-compress-depth 0
这个参数表示一个quicklist两端不被压缩的节点个数。
注:这里的节点个数是指quicklist双向链表的节点个数,而不是指ziplist里面的数据项个数。实际上,一个quicklist节点上的ziplist,如果被压缩,就是整体被压缩的。
参数list-compress-depth的取值含义如下:
0: 是个特殊值,表示都不压缩。这是Redis的默认值。
1: 表示quicklist两端各有1个节点不压缩,中间的节点压缩。
2: 表示quicklist两端各有2个节点不压缩,中间的节点压缩。
3: 表示quicklist两端各有3个节点不压缩,中间的节点压缩。
依此类推…
由于0是个特殊值,很容易看出quicklist的头节点和尾节点总是不被压缩的,以便于在表的两端进行快速存取。
set-max-intset-entries 512
数据量小于等于set-max-intset-entries用intset,大于set-max-intset-entries用set
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
数据量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset
hll-sparse-max-bytes 3000
value大小小于等于hll-sparse-max-bytes使用稀疏数据结构(sparse),大于hll-sparse-max-bytes使用稠密的数据结构(dense),一个比16000大的value是几乎没用的,建议的value大概为3000。如果对CPU要求不高,对空间要求较高的,建议设置到10000左右
activerehashing yes
redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。
如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
client-output-buffer-limit normal 0 0 0
对客户端输出缓冲进行限制可以强迫那些不从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端。对于normal client,第一个0表示取消hard limit,第二个0和第三个0表示取消soft limit,normal client默认取消限制,因为如果没有寻问,他们是不会接收数据的
client-output-buffer-limit slave 256mb 64mb 60
对于slave client和MONITER client,如果client-output-buffer一旦超过256mb,又或者超过64mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit pubsub 32mb 8mb 60
对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。
hz 10
redis执行任务的频率为1s除以hz
aof-rewrite-incremental-fsync yes
在aof重写的时候,如果打开了aof-rewrite-incremental-fsync开关,系统会每32MB执行一次fsync。这对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值
三、Redis持久化:
Redis虽然是一个内存级别的缓存程序,也就是redis是使用内存进行数据的缓存的,但是其可以将内存的数据按照一定的策略保存到硬盘上,从而实现数据持久化的目的,目前redis支持两种不同方式的数据持久化机制,分别是RDB和AOF
只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。
RDB 持久化方式能够在指定的时间间隔能对你的数据进行快照存储。
AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾。Redis 还能对 AOF 文件进行后台重写,使得 AOF 文件的体积不至于过大。
RDB模式:
RDB(Redis DataBase):基于时间的快照,其默认只保留当前最新的一次快照,特点是执行速度比较快,缺点是可能会丢失从上次快照到当前时间的之间未做快照的数据。
RDB实现的具体过程Redis从主进程fork出一个子进程,使用写时复制(copy-on-write),子进程将内存的数据保存为一个临时文件,比如dump.rdb.temp,但数据保存完成后再将上一次保存的rdb文件替换掉,然后关闭子进程,这样可以保存每一次做RDB快照的时候保存的数据都是完整的,因为直接替换RDB文件的时候可能会出现突然断电等问题而导致RDB文件还没保存完整就突然关机停止从而导致数据丢失的情况,可以手动将每次生产的RDB文件进行备份,这样最大化保存历史数据。
RDB的三种实现方式:
对于RDB来说,提供了三种实现机制:save、bgsave、自动化。我们分别来看一下
(1)save触发方式
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止,执行完成后如果存在老的RDB文件,就把新的替代掉旧的。
如果我们的数据量较大而我们的客户端可能有几万或者是几十万,这样就会造成严重的阻塞,显然这种方式不可取。
(2)bgsave触发方式
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。
具体操作是Redis会调用fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上Redis内部所有的RDB操作都是采用bgsave命令。
(3)自动触发
自动触发是由我们的配置文件来完成的。在redis.conf配置文件中,里面有如下配置,我们可以去设置:
RDB核心规则配置 save <指定时间间隔> <执行指定次数更新操作>,满足条件就将内存中的数据同步到硬盘中。官方出厂配置默认是 900秒内有1个更改,300秒内有10个更改以及60秒内有10000个更改,则将内存中的数据快照写入磁盘。若不想用RDB方案,可以把 save "" 的注释打开,下面三个注释
# save ""
save 900 1
save 300 10
save 60 10000
当RDB持久化出现错误后,是否依然进行继续进行工作,yes:不能进行工作,no:可以继续进行工作,可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误
stop-writes-on-bgsave-error yes
配置存储至本地数据库时是否压缩数据,默认为yes。Redis采用LZF压缩方式,但占用了一点CPU的时间。若关闭该选项,但会导致数据库文件变的巨大。建议开启。
rdbcompression yes
是否校验rdb文件;从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和。这跟有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置
rdbchecksum yes
指定本地数据库文件名,一般采用默认的 dump.rdb
dbfilename dump.rdb
数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
dir /usr/local/redis/var
优势:
1.RDB快照保存了某个时间点的数据,可以通过脚本执行bgsave(非阻塞)或者save(阻塞)命令自定义时间点备份,可以保留多个备份,当出现问题可以恢复到不同时间点的版本。
2.生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
3.RDB 在恢复大数据集时的速度比AOF的恢复速度要快。
劣势:
1.不能实时的保存数据,会丢失自上一次执行RDB备份到当前的内存数据(即无法实现实时或者秒级持久化)
2.数据量非常大的时候,从父进程fork的时候需要一点时间,可能是毫秒或者秒或者分钟,取决于磁盘的io性能。
3.RDB 文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的 RDB 版本,存在老版本 Redis 服务无法兼容新版 RDB 格式的问题(版本不兼容)
AOF模式:
AOF:按照操作顺序依次将操作命令添加到日志文件中,通俗的讲就是日志记录。特点是数据安全性比较高,缺点是即使有些操作是重复的也会全部记录。
AOF和RDB一样使用了写时复制机制,AOF默认为每秒钟fsync一次,即将执行的命令保存到AOF当中,这样即使redis服务器发生故障的话顶多也就丢失1秒钟之内的数据,也可以设置不同的fsync策略,或者设置每次执行命令的时候执行fsync,fsync会在后台执行线程,所以主线程可以继续处理用户的正常请求而不受写入AOF文件的io影响。
三种触发机制:
always:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
everysec:异步操作,每秒记录 如果一秒内宕机,有数据丢失
no:从不同步
文件重写原理:
我们知道Redis是单线程工作,如果重写AOF需要比较长的时间,那么在重写AOF期间,Redis将长时间无法处理其他的命令,这显然是不能忍受的。Redis为了克服这个问题,解决办法是将 AOF 重写程序放到子程序中进行,这样有两个好处:
1.子进程进行 AOF 重写期间,服务器进程(父进程)可以继续处理其他命令。
2.子进程带有父进程的数据副本,使用子进程而不是线程,可以在避免使用锁的情况下,保证数据的安全性。
使用子进程解决了上面的问题,但是新问题也产生了:因为子进程在进行AOF重写期间,服务器进程依然在处理其它命令,这新的命令有可能也对数据库进行了修改操作,使得当前数据库状态和重写后的 AOF 文件状态不一致。
为了解决这个数据状态不一致的问题,Redis服务器设置了一个AOF重写缓冲区,这个缓冲区是在创建子进程后开始使用,当Redis服务器执行一个写命令之后,就会将这个写命令也发送到AOF重写缓冲区。当子进程完成AOF重写之后,就会给父进程发送一个信号,父进程接收此信号后,就会调用函数将AOF重写缓冲区的内容都写到新的AOF文件中。 这样将 AOF 重写对服务器造成的影响降到了最低。
AOF相关的配置:
Redis默认不开启。它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。若开启rdb则将no改为yes
appendonly no
指定本地数据库文件名,默认值为 appendonly.aof
appendfilename "appendonly.aof"
aof持久化策略的配置
appendfsync everysec
no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快
always表示每次写入都执行fsync,以保证数据同步到磁盘
everysec表示每秒执行一次fsync,可能会导致丢失这1s数据
在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。Linux的默认fsync策略是30秒。可能丢失30秒数据
no-appendfsync-on-rewrite no
aof自动重写配置。当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程
auto-aof-rewrite-percentage 100
设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
auto-aof-rewrite-min-size 64mb
aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项(redis宕机或者异常终止不会造成尾部不完整现象。)出现这种现象,可以选择让redis退出,或者导入尽可能多的数据。如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。如果是no,用户必须手动redis-check-aof修复AOF文件才可以
aof-load-truncated yes
加载redis时,可以识别AOF文件以“redis”开头。字符串并加载带前缀的RDB文件,然后继续加载AOF尾巴
aof-use-rdb-preamble yes
优点:
1.AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。
2.AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件不容易破损。
3.AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。
4.AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据
缺点:
1.数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF文件通常比RDB文件大。
2.AOF开启后,由于频繁地将命令同步到文件中,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的
3.相对RDB方式,AOF速度慢于RDB,并且在数据量大时候,恢复速度AOF速度也是慢于RDB。
RDB-AOF混合持久化:
在Redis4.0之后又新增了RDB-AOF混合持久化方式。
aof-use-rdb-preamble:设置为 yes 表示开启,设置为 no 表示禁用。
当开启混合持久化时,主进程先 fork 出子进程将现有内存副本全量以 RDB 方式写入 aof 文件中,然后将缓冲区中的增量命令以 AOF 方式写入 aof 文件中,写入完成后通知主进程更新相关信息,并将新的含有 RDB 和 AOF 两种格式的aof文件替换旧的 aof 文件。简单来说:混合持久化方式产生的文件一部分是 RDB 格式,一部分是 AOF 格式。
这种方式优点我们很好理解,缺点就是不能兼容 Redis4.0 之前版本的备份文件了。
总结:
同时开启两种持久化方式,在这种情况下,当 redis 重启的时候会优先载入 AOF 文件来恢复原始的数据,因为在通常情况下 AOF 文件保存的数据集要比 RDB 文件保存的数据集要完整,RDB 的数据不实时,同时使用两者时服务器重启也只会找 AOF 文件。那要不要只使用AOF呢?作者建议不要,因为 RDB 更适合用于备份数据库(AOF 在不断变化不好备份),快速重启,而且不会有 AOF 可能潜在的 bug,留着作为一个万一的手段。
性能建议:
因为 RDB 文件只用作后备用途,建议只在 Slave上持久化RDB 文件,而且只要15分钟备份一次就够了,只保留 save 900 1 这条规则。如果 Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只 load 自己的 AOF 文件就可以了。代价一是带来了持续的 IO,二是 AOF rewrite 的最后将rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少 AOF rewrite 的频率,AOF 重写的基础大小默认值64M太小了,可以设到 5G以上。默认超过原大小100%大小时重写可以改到适当的数值。
如果不 Enable AOF ,仅靠 Master-Slave Replication 实现高可用性也可以。能省掉一大笔 IO 也减少了 rewrite 时带来的系统波动。代价是如果 Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB 文件,载入较新的那个。新浪微博就选用了这种架构。
五、延伸:
bind 127.0.0.1 192.168.177.139 监听地址,可以写多个,中间以空格隔开
protected-mode yes 3.2之后版本加入的,没有设置监听IP和密码的话,只允许本地访问
port 6379 端口号
tcp-backlog 511 三次握手的时候,server端收到client,ack确认号之后的队列值
timeout 0 客户端和Redis的连接超时时间,默认永不超时
tcp-keepalive 300 3.2.1之后版本新添加的,tcp会话保持时间,探测中断报文
daemonize no 默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成yes,当 redis 作为守护进程运行的时候,
它会写一个 pid 到 /var/run/redis.pid 文件里面
supervised no 和操作系统相关参数, 可以设置通过 upstart 和 systemd 管理 Redis 守护进程, centos 7以后都使用 systemd
pidfile /apps/redis/run/redis_6379.pid pid 文件路径
loglevel notice 日志级别
logfile "/apps/redis/logs/redis_6379.log" 保存redis运行时的日志路径
databases 16 #设置 db 库数量,默认 16 个库
always-show-logo yes #在启动 redis 时是否显示 logo
save 900 1 #在 900 秒内有一个键内容发生更改就出就快照机制
save 300 10 #在 300 秒内有10个键内容发生更改就出就快照机制
save 60 10000 #在 60 秒内有1000个键内容发生更改就出就快照机制
stop-writes-on-bgsave-error no #快照出错时是否禁止 redis 写入操作,一定要关闭,要收集日志,多看看
rdbcompression yes #持久化到 RDB 文件时,是否压缩, "yes"为压缩, "no"则反之,要打开
rdbchecksum yes #是否开启 RC64 校验,默认是开启,要打开
dbfilename dump_6379.rdb #快照文件名
dir /apps/redis/data #快照文件保存路径
slave-serve-stale-data yes #当从库同主库失去连接或者复制正在进行,从机库有两种运行方式: 1) 如果 slave-serve-stale-data 设置为 yes
(默认设置),从库会继续响应客户端的读请求。 2) 如果 slave-serve-stale-data 设置为 no,除去指定的命令之外
的任何请求都会返回一个错误"SYNC with master inprogress"。一般设置为yes
slave-read-only yes #是否设置从库只读,默认yes
repl-diskless-sync no #是否使用 socket 方式复制数据, 目前 redis 复制提供两种方式, disk 和 socket, 如果新的 slave 连上来或者重连的
slave无法部分同步,就会执行全量同步,master 会生成 rdb 文件, 有2 种方式: disk 方式是 master 创建一个新的进程把 rdb 文件保存到磁盘,再把磁盘上的 rdb 文件传递给 slave, socket 是 master 创建一个新的进程,直接把 rdb 文件
以 socket 的方式发给 slave, disk 方式的时候,当一个 rdb 保存的过程中,多个 slave 都能共享这个 rdb 文件 ,socket 的方式就是一个个 slave顺序复制, 只有在磁盘速度缓慢但是网络相对较快的情况下才使用 socket 方式, 否则使用默认的 disk方式
repl-diskless-sync-delay 5 #diskless 复制的延迟时间, 设置 0 为关闭,一旦复制开始还没有结束之前,master节点不会再接收新 slave 的复制请求, 直到下一次开始
repl-ping-slave-period 10 #slave 根据 master 指定的时间进行周期性的 PING 监测
repl-timeout 60 #复制链接超时时间,需要大于 repl-ping-slave-period, 否则会经常报超时
repl-disable-tcp-nodelay no #在 socket 模式下是否在 slave 套接字发送 SYNC 之后禁用 TCP_NODELAY,如果你选择“yes”Redis 将使用更少的 TCP 包和带宽来向 slaves 发送数据。但是这将使数据传输到 slave上有延迟, Linux 内核的默认配置会达到 40 毫秒,如果你选择了 "no" 数据传输到 salve 的延迟将会减少但要使用更多的带宽
repl-backlog-size 1mb #复制缓冲区大小, 只有在 slave 连接之后才分配内存。
repl-backlog-ttl 3600 #多次时间 master 没有 slave 连接,就清空 backlog 缓冲区。
replica-priority 100 #当 master 不可用, Sentinel 会根据 slave 的优先级选举一个 master。最低的优先级的 slave,当选 master。而配置成 0,永远不会被选举。
requirepass foobared #设置 redis 连接密码
rename-command #重命名一些高危命令
maxclients 10000 #最大连接客户端
maxmemory #最大内存, 单位为 bytes 字节,8G内存的计算方式 8(G)*1024(MB)*1024(KB)*1024(Kbyte),需要注意的是slave的输出缓冲区是不计算在 maxmemory 内。不超过物理内存的一半
appendonly no #是否开启 AOF 日志记录, 默认 redis 使用的是 rdb 方式持久化,这种方式在许多应用中已经足够用了。但是 redis 如果中途宕机,
会导致可能有几分钟的数据丢失,根据 save 来策略进行持久化,Append Only File 是另一种持久化方式,可以提供更好的持久化特性。
Redis 会把每次写入的数据在接收后都写入 appendonly.aof 文件,每次启动时 Redis 都会先把这个文件的数据读入内存里,
#先忽略 RDB 文件。
appendfilename "appendonly_6379.aof" #AOF 文件名
appendfsync everysec #aof 持久化策略的配置,no 表示不执行 fsync,由操作系统保证数据同步到磁盘,always 表示每次写入都执行 fsync,以保证
#数据同步到磁盘,everysec 表示每秒执行一次 fsync,可能会导致丢失这 1s 数据。
no-appendfsync-on-rewrite no #在aof rewrite期间,是否对 aof 新记录的 append 暂缓使用文件同步策略,主要考虑磁盘IO开支和请求阻塞时间。
#默认为 no,表示"不暂缓",新的 aof 记录仍然会被立即同步,Linux 的默认 fsync 策略是 30 秒,
#如果为 yes 可能丢失 30 秒数据, 但由于 yes 性能较好而且会避免出现阻塞因此比较推荐。
auto-aof-rewrite-percentage 100 #当Aof log增长超过指定百分比例时,重写log file, 设置为0表示不自动重写Aof日志,重写是为了
#使aof体积保持最小,而确保保存最完整的数据。
auto-aof-rewrite-min-size 64mb #触发 aof rewrite 的最小文件大小
aof-load-truncated yes #是否加载由于其他原因导致的末尾异常的 AOF 文件(主进程被 kill/断电等)
aof-use-rdb-preamble yes #redis4.0 新增 RDB-AOF 混合持久化格式,在开启了这个功能之后, AOF 重写产生的文件将同时包含 RDB 格式的内容和
#AOF 格式的内容,其中 RDB 格式的内容用于记录已有的数据,而 AOF 格式的内存则用于记录最近发生了变化的数据,
#这样 Redis 就可以同时兼有 RDB 持久化和AOF 持久化的优点(既能够快速地生成重写文件,也能够在出现问题时,快速地载入数据)。
lua-time-limit 5000 #lua 脚本的最大执行时间, 单位为毫秒
cluster-enabled yes #是否开启集群模式,默认是单机模式
cluster-config-file nodes-6379.conf #由 node 节点自动生成的集群配置文件
cluster-node-timeout 15000 #集群中 node 节点连接超时时间
cluster-replica-validity-factor 10 #在执行故障转移的时候可能有些节点和 master 断开一段时间数据比较旧, 这些节点就不适用于选举为 master,
#超过这个时间的就不会被进行故障转移
cluster-migration-barrier 1 #一个主节点拥有的至少正常工作的从节点, 即如果主节点的slave节点故障后会将多余的从节点分配到当前主节点成为其新的从节点。
cluster-require-full-coverage no #集群槽位覆盖, 如果一个主库宕机且没有备库就会出现集群槽位不全, 那么yes情况下redis集群槽位验证不全就不再对外提供服务,而 no 则可以继续使用但是会出现查询数据查不到的情况(因为有数据丢失)。
slowlog-max-len 128 #记录多少条慢日志保存在队列,超出后会删除最早的, 以此滚动删除
#Slow log 是 Redis 用来记录查询执行时间的日志系统, slow log 保存在内存里面,读写速度非常快,因此你可以放心地使用它,不必担心因为开启 slow log 而损害 Redis 的速度。slowlog-log-slower-than 10000 #以微秒为单位的慢日志记录, 为负数会禁用慢日志, 为 0 会记录每个命令操作。