本文转载自微信公众号「零零后程序员小三」,作者003 。转载本文请联系零零后程序员小三公众号。
本文是对Redis6的持久化配置,了解什么是AOF和RDB,它们的优缺点是什么,该如何使用。
什么是Redis持久化?
我们都知道Redis是一个基于内存的数据库,如果没有给Redis配置持久化的话,每当重启后Redis的数据就会全部丢失,会很麻烦。因此Redis需要开启持久化功能,将数据保存到磁盘上,当Redis重启后可以在磁盘中恢复数据。这样缓存数据就不容易丢失了。
开启持久化的两种方式
Redis开启持久化有两种方式:RDB(Redis DataBase)与AOF(append only file)
RDB持久化
RDB其实就是把数据以快照的形式保存到磁盘上。什么是快照呢?你可以把快照理解成当前这一时刻的数据拍成一张照片保存下来。RDB持久化是指在指定的时间间隔内将内存中的数据集快照形式写入磁盘。也是默认的持久化方式,这种方式就是将内存中的数据写入到二进制文件当中,默认的文件名为dump.rdb
既然RDB机制是通过某个时刻把所有数据生成一张快照来进行保存的,那么就应该会有一种触发机制来实现这个过程。对于RDB来说,提供了三种机制:save、bgsave、自动化。
1.save触发方式:该命令会阻塞当前Redis服务器,执行save命令的时候,Redis不能处理其他的命令,直到RDB过程执行完成为止。执行完成的时候如果存在老的RDB文件,就会把新的替换掉旧的。
2.bgsave触发方式:执行该命令的时候,Redis会在后台进行异步快照操作,快照的同时还可以响应客户端的请求,具体的操作是Redis进程执行fork操作创建了一个子进程,而RDB持久化过程由子进程负载,完成后自动结束。阻塞只发生在子进程。
3.自动化触发:由配置文件来完成,配置触发Redis的RDB持久化条件。
「RDB有何优缺点?」
优点:
(1)RDB文件紧凑,全量备份,比较适用于备份和灾难恢复
(2)生成RDB文件的时候,Redis主进程会开启让一个子进程来完成所有的保存操作,主进程不需要任何的IO操作
(3)RDB在恢复大数据集的时候速度快。
缺点:
因为RDB快照是一次全量备份的,存储的是内存数据二进制形式,在存储上会非常的紧凑。当进行快照持久化时,会开启一个子进程负载快照的持久化,子进程会拥有父进程的内存数据,父进程修改内存子进程不会反应出来,所有当在快照持久化时修改的数据不会得以保存,还有可能导致丢失数据。
核心配置:(dbfilename 文件名,dir持久化文件的路径)
- #任何ip可以访问
- bind 0.0.0.0
- #守护进程
- daemonize yes
- #密码
- requirepass 123456
- #⽇志⽂件
- logfile "/usr/local/redis/log/redis.log"
- #持久化⽂件名称
- dbfilename xdclass.rdb
- #持久化⽂件存储路径
- dir /usr/local/redis/data
- #持久化策略, 10秒内有个1个key改动,执⾏快照
- save 10 1
- ######之前配置######
- #导出rdb数据库⽂件压缩字符串和对象,默认是yes,会浪费
- CPU但是节省空间
- rdbcompression yes
- # 导⼊时是否检查
- rdbchecksum yes
RDB操作实战
配置文件(根据自行需要配置)
- bind 0.0.0.0
- daemonize yes
- requirepass 123456Xdclass
- logfile "/usr/local/redis/log/redis.log"
- dbfilename xdclass.rdb
- dir /usr/local/redis/data
- #关闭rdb
- #save ""
- #10秒2个key变动则触发rdb
- save 10 2
- #100秒5个key变动则触发rdb
- save 100 5
- #压缩
- rdbcompression yes
- #检查
- rdbchecksum yes
备注:Linux内存分配策略,0表示内核将检查是否有足够的内存供应用进程所使用;如果有足够内存则申请允许;否则申请失败,并发错误返回给应用进程
1表示内核允许分配所有的物理内存,而不管当前的内存状态如何
2表示内核允许分配超过所有物理内存和交换总和内存
- 解决⽅式
- echo 1 > /proc/sys/vm/overcommit_memory
- 持久化配置
- vim /etc/sysctl.conf
- 改为
- vm.overcommit_memory=1
- 修改sysctl.conf后,需要执⾏ sysctl -p 以使⽣效。
AOF持久化
上面介绍了RDB持久化是全量备份的,但这种备份总是耗时的,有时候我们提供了一种更为高效的方式AOF,工作机制很简单,Redis会将每一个收到的命令都通过write函数追加到文件中。通俗点理解就是像日志记录一样。
配置:
与RDB配置方式不一样
- appendonly yes 默认为不开启
- AOF文件名通过appendfilename配置设置,默认文件名为appendonly.aof
- 存储路径同RDB持久化方式一致,使用dir配置
- bind 0.0.0.0
- daemonize yes
- requirepass 123456Xdclass
- logfile "/usr/local/redis/log/redis.log"
- dbfilename xdclass.rdb
- dir /usr/local/redis/data
- #save 10 2
- #save 100 5
- save ""
- rdbcompression yes
- #对rdb数据进⾏校验,耗费CPU资源,默认为yes
- rdbchecksum yes
- appendonly yes
- appendfilename "appendonly.aof"
- appendfsync everysec
AOF核心原理
(1)Redis每次写入命令会追加到aof_buf缓冲区中
(2)AOF缓冲区根据对应的策略向硬盘做同步的操作
(3)高频AOF会带来影响,特别是每次刷盘
AOF三种触发机制
(1)每修改同步always:同步持久化 每次发送数据更变会立即被记录到磁盘中,性能较差但是数据保存的完整性比较好
(2)每秒同步everysec:异步操作,每秒记录,如果一秒内宕机的话,会造成数据丢失。
(3)不同no:从不同步
AOF有何优缺点?
优点:
(1)AOF可以更好的对数据保护,不让数据丢失。一般AOF会每隔一秒,通过后台线程执行一次fsync操作,最多丢失一秒钟的数据
(2)AOF日志文件没有任何磁盘寻址的开销,写入性能非常高,文件也不容易损坏。
(3)AOF日志文件的命令拥有很好的可读方式进行记录,因为这个特征非常适合做灾难性的误删除恢复。
缺点:
(1)对于同一份数据来说的话,AOF文件的日志通常要比RDB数据快照文件要更大。
(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般配置成每秒fsync一次日志文件。
AOF配置实战
「文件重新原理」
AOF的方式也同时带来了另一个问题。持久化文件会变得越来越大,为了压缩aof持久化文件。Redis提供了一个barewriteaof命令。来讲内存中的数据以命令的形式保存到临时文件中,同时会开启一条新进程来重写,重写aof文件的操作,并没有读取旧的aof文件,而是把整个内存中的数据库内容用命令的形式重写了一个新的aof文件,这个和快照有点类似。
重写触发配置
手动触发:直接调用bgrewriteaof命令
自动触发:auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数(auto-aof-rewrite-min-size表示AOF重写文件最小体积,默认为64MB;auto-aof-rewrite-percentage代表AOF文件空间和上一次重写后AOF文件空间的比值)
常用配置
- # 是否开启aof
- appendonly yes
- # ⽂件名称
- appendfilename "appendonly.aof"
- # 同步⽅式
- appendfsync everysec
- # aof重写期间是否同步
- no-appendfsync-on-rewrite no
- # 重写触发配置
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb
- # 加载aof时如果有错如何处理
- # yes表示如果aof尾部⽂件出问题,写log记录并继续执⾏。
- no表示提示写⼊等待修复后写⼊
- aof-load-truncated yes
在线上,我们到底该怎么做?
(1)RDB持久化与AOF持久化起使
(2)如果Redis中的数据并不是特别敏感或者可以通过其它?式重写?成数据
(3)集群中可以关闭AOF持久化,靠集群的备份?式保证可?性
(4)??制定策略定期检查Redis的情况,然后可以?动触发备份、重写数据;
(5)采?集群和主从同步
在Redis4.0后支持混合模式
RDB和AOF可以一起用了,直接将RDB持久化的方式来操作二进制内容覆盖到AOF文件中,因为RDB是二进制,所以很小。有写入的话还是继续append追加到文件的原始命令,等下次文件过大的时候在次rewrite,所以在企业中这种混合模式是比较常见的。