4.5 spring boot 工程集成cluster集群
把单机的spring.redis.host
和spring.redis.port
配置改成以下
##### redis配置 spring.redis.cluster.nodes=192.168.28.130:7001,192.168.28.130:7002,192.168.28.130:7003,192.168.28.130:7004,192.168.28.130:7005,192.168.28.130:7006
5. 持久化方案
5.1 RDB持久化
RDB
持久化方式是通过快照(snapshotting
)完成的,当符合一定条件时,redis
会自动将内存中所有数据以二进制方式生成一份副本并存储在硬盘上。当redis
重启时,并且AOF
持久化未开启时,redis
会读取RDB
持久化生成的二进制文件(默认名称dump.rdb
,可通过设置dbfilename
修改)进行数据恢复,对于持久化信息可以用过命令“info Persistence
”查看。
快照文件位置:RDB快照文件存储文件位置由dir配置参数指明,文件名由dbfilename指定
快照触发条件:RDB生成快照可自动促发,也可以使用命令手动触发,以下是redis触发执行快照条件,后续会对每个条件详细说明:
- 客户端执行命令save和bgsave会生成快照;
- 根据配置文件save m n规则进行自动快照;
- 主从复制时,从库全量复制同步主库数据,此时主库会执行bgsave命令进行快照;
- 客户端执行数据库清空命令FLUSHALL时候,触发快照;
- 客户端执行shutdown关闭redis时,触发快照;
RDB持久化配置:
#配置快照(rdb)促发规则,格式:save <seconds> <changes> #save 900 1 900秒内至少有1个key被改变则做一次快照 #save 300 10 300秒内至少有300个key被改变则做一次快照 #save 60 10000 60秒内至少有10000个key被改变则做一次快照 #关闭该规则使用save "" save m n #rdb持久化存储数据库文件名,默认为dump.rdb dbfilename dump.rdb #yes代表当使用bgsave命令持久化出错时候停止写RDB快照文件,no表明忽略错误继续写文件。 stop-write-on-bgsave-error yes #在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏,如果在启动是检查发现损坏,则停止启动。 rdbchecksum yes #数据文件存放目录,rdb快照文件和aof文件都会存放至该目录,请确保有写权限 dir "/etc/redis" #是否开启RDB文件压缩,该功能可以节约磁盘空间 rdbcompression yes
5.2 AOF持久化
当redis
存储非临时数据时,为了降低redis
故障而引起的数据丢失,redis
提供了AOF(Append Only File)
持久化,从单词意思讲,将命令追加到文件。AOF
可以将Redis
执行的每一条写命令追加到磁盘文件(appendonly.aof
)中,在redis
启动时候优先选择从AOF
文件恢复数据。由于每一次的写操作,redis
都会记录到文件中,所以开启AOF
持久化会对性能有一定的影响,但是大部分情况下这个影响是可以接受的,我们可以使用读写速率高的硬盘提高AOF
性能。与RDB
持久化相比,AOF
持久化数据丢失更少,其消耗内存更少(RDB
方式执行bgsve
会有内存拷贝)。
默认情况下,redis是关闭了AOF持久化,开启AOF通过配置appendonly为yes开启
5.2.1 AOF持久化过程
Redis AOF
持久化过程可分为以下阶段:
1. 追加写入:
- redis将每一条写命令以redis通讯协议添加至缓冲区aof_buf,这样的好处在于在大量写请求情况下,采用缓冲区暂存一部分命令随后根据策略一次性写入磁盘,这样可以减少磁盘的I/O次数,提高性能。
2. 同步命令到硬盘:当写命令写入aof_buf缓冲区后,redis会将缓冲区的命令写入到文件,redis提供了三种同步策略,由配置参数appendfsync决定,下面是每个策略所对应的含义:
- no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据丢失严重。
- always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低。
- everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。
3. 文件重写(bgrewriteaof)
当开启的AOF时,随着时间推移,AOF文件会越来越大,当然redis也对AOF文件进行了优化,即触发AOF文件重写条件(后续会说明)时候,redis将使用bgrewriteaof对AOF文件进行重写。这样的好处在于减少AOF文件大小,同时有利于数据的恢复。
为什么重写?比如先后执行了“set foo bar1 set foo bar2 set foo bar3” 此时AOF文件会记录三条命令,这显然不合理,因为文件中应只保留“set foo bar3”这个最后设置的值,前面的set命令都是多余的,下面是一些重写时候策略:
- 重复或无效的命令不写入文件
- 过期的数据不再写入文件
- 多条命令合并写入(当多个命令能合并一条命令时候会对其优化合并作为一个命令写入,例如“RPUSH list1 a RPUSH list1 b" 合并为“RPUSH list1 a b” )
5.2.2 AOF实现本质
AOF实现本质是基于redis通讯协议,将命令以纯文本的方式写入到文件中。
redis协议:首先Redis是以行来划分,每行以\r\n行结束。每一行都有一个消息头,消息头共分为5种分别如下:
(+)
表示一个正确的状态信息,具体信息是当前行+后面的字符。(-)
表示一个错误信息,具体信息是当前行-后面的字符。(*)
表示消息体总共有多少行,不包括当前行,*后面是具体的行数。($)
表示下一行数据长度,不包括换行符长度\r\n,$后面则是对应的长度的数据。(:)
表示返回一个数值,:后面是相应的数字节符。
AOF文件中的格式,如下图:
AOF配置参数:
#AOF文件最小重写大小,只有当AOF文件大小大于该值时候才可能重写,4.0默认配置64mb。 auto-aof-rewrite-min-size 64mb #当前AOF文件大小和最后一次重写后的大小之间的比率等于或者等于指定的增长百分比,如100代表当前AOF文件是上次重写的两倍时候才重写。 auto-aof-rewrite-percentage 100 #no:不使用fsync方法同步,而是交给操作系统write函数去执行同步操作,在linux操作系统中大约每30秒刷一次缓冲。这种情况下,缓冲区数据同步不可控,并且在大量的写操作下,aof_buf缓冲区会堆积会越来越严重,一旦redis出现故障,数据 #always:表示每次有写操作都调用fsync方法强制内核将数据写入到aof文件。这种情况下由于每次写命令都写到了文件中, 虽然数据比较安全,但是因为每次写操作都会同步到AOF文件中,所以在性能上会有影响,同时由于频繁的IO操作,硬盘的使用寿命会降低。 #everysec:数据将使用调用操作系统write写入文件,并使用fsync每秒一次从内核刷新到磁盘。 这是折中的方案,兼顾性能和数据安全,所以redis默认推荐使用该配置。 appendfsync everysec #当redis突然运行崩溃时,会出现aof文件被截断的情况,Redis可以在发生这种情况时退出并加载错误,以下选项控制此行为。 #如果aof-load-truncated设置为yes,则加载截断的AOF文件,Redis服务器启动发出日志以通知用户该事件。 #如果该选项设置为no,则服务将中止并显示错误并停止启动。当该选项设置为no时,用户需要在重启之前使用“redis-check-aof”实用程序修复AOF文件在进行启动。 aof-load-truncated yes #yes开启AOF,no关闭AOF appendonly no #指定AOF文件名,4.0无法通过config set 设置,只能通过修改配置文件设置。 appendfilename appendonly.aof #RDB文件和AOF文件存放目录 dir /etc/redis
5.3 RDB-AOF混合持久化
redis4.0相对与3.X版本其中一个比较大的变化是4.0添加了新的混合持久化方式。前面已经详细介绍了AOF持久化以及RDB持久化,这里介绍的混合持久化就是同时结合RDB持久化以及AOF持久化混合写入AOF文件。这样做的好处是可以结合 rdb 和 aof 的优点, 快速加载同时避免丢失过多的数据,缺点是 aof 里面的 rdb 部分就是压缩格式不再是 aof 格式,可读性差。
混合持久化:4.0版本的混合持久化默认关闭的,通过aof-use-rdb-preamble配置参数控制,yes则表示开启,no表示禁用,默认是禁用的
混合持久化过程:混合持久化同样也是通过bgrewriteaof完成的,不同的是当开启混合持久化时,fork出的子进程先将共享的内存副本全量的以RDB方式写入aof文件,然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。简单的说:新的AOF文件前半段是RDB格式的全量数据后半段是AOF格式的增量数据,如下图:
数据恢复:当我们开启了混合持久化时,启动redis依然优先加载aof文件,aof文件加载可能有两种情况如下:
- aof文件开头是rdb的格式, 先加载 rdb内容再加载剩余的 aof。
- aof文件开头不是rdb的格式,直接以aof格式加载整个文件
5.4 总结
5.4.1 RDB
优点:
- RDB 是一个非常紧凑(compact)的文件,体积小,因此在传输速度上比较快,因此适合灾难恢复。
- RDB 可以最大化 Redis 的性能:父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。
- RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
缺点:
- RDB是一个快照过程,无法完整的保存所以数据,尤其在数据量比较大时候,一旦出现故障丢失的数据将更多。
- 当redis中数据集比较大时候,RDB由于RDB方式需要对数据进行完成拷贝并生成快照文件,fork的子进程会耗CPU,并且数据越大,RDB快照生成会越耗时。
- RDB文件是特定的格式,阅读性差,由于格式固定,可能存在不兼容情况。
5.4.2 AOF
优点::
- 数据更完整,秒级数据丢失(取决于设置fsync策略)。
- 兼容性较高,由于是基于redis通讯协议而形成的命令追加方式,无论何种版本的redis都兼容,再者aof文件是明文的,可阅读性较好。
缺点:
- 数据文件体积较大,即使有重写机制,但是在相同的数据集情况下,AOF文件通常比RDB文件大。
- 相对RDB方式,AOF速度慢于RDB,并且在数据量大时候,恢复速度AOF速度也是慢于RDB。
- 由于频繁地将命令同步到文件中,AOF持久化对性能的影响相对RDB较大,但是对于我们来说是可以接受的。
5.4.3 混合持久化
优点:
- 混合持久化结合了RDB持久化 和 AOF 持久化的优点, 由于绝大部分都是RDB格式,加载速度快,同时结合AOF,增量的数据以AOF方式保存了,数据更少的丢失。
缺点:
- 兼容性差,一旦开启了混合持久化,在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差