redis 持久化

redis 是基于内存运行的数据库,所有数据加载在内存中进行读写,所以数据库重启以后不做持久化策略前提下数据会全部消失。

redis必须使用数据持久化吗?如果我们的Redis服务器只作为缓存使用,Redis中存储的所有数据都是从其他地方同步过来的备份,那么就没必要开启数据持久化的选项。

Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。

RDB持久化方式

Redis会定期保存数据快照至一个rbd文件中,并在启动时自动加载rdb文件,恢复之前保存的数据。

触发机制

手动触发:

save 和  bgsave命令

save  操作在Redis主线程中工作,因此会阻塞其他请求操作,应该避免使用。

bgSave 是调用Fork,产生子进程,父进程继续处理请求。子进程将数据写入临时文件,并在写完后,替换原有的.rdb文件。Fork发生时,父子进程内存共享,所以为了不影响子进程做数据快照,在这期间修改的数据,将会被复制一份,而不进共享内存。所以说,RDB所持久化的数据,是Fork发生时的数据。在这样的条件下进行持久化数据,如果因为某些情况宕机,则会丢失一段时间的数据。如果你的实际情况对数据丢失没那么敏感,丢失的也可以从传统数据库中获取或者说丢失部分也无所谓,那么你可以选择RDB持久化方式。

 自动触发:

配置文件中配置如下:        #注释3个save 即表示关闭rdb持久化策略

save 900 1
save 300 10
save 60 100                #每60秒检查一次数据变更情况,如果发生了100次或以上的数据变更,则进行RDB快照保存。Redis默认开启RDB快照。

stop-writes-on-bgsave-error yes   #在开启RDB且最近一次bgsave执行失败的情况下,如果该参数为yes,则Redis会阻止客户端的写入,直到bgsave执行成功。

rdbcompression yes           #使用LZF算法压缩字符对象。

rdbchecksum yes             #从RDB V5开始,在保存RDB文件时,会在文件末尾添加CRC64校验和,这样,能较容易的判断文件是否被损坏。但同时,对于带有校验和的RDB文件的保存和加                                                                           载,会有10%的性能损耗。

dbfilename dump.rdb            #RDB文件名
dir ./                  #RDB文件保存的目录

Tips:

因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。

如果采用RDB方式,也需要定期对dum.rdb 文件做异地备份。 

AOF 持久化方式

采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里。在Redis重启时,会把AOF文件中记录的所有写操作顺序执行一遍,确保数据恢复到最新。AOF默认是关闭的,如要开启,进行如下配置:appendonly yes

AOF的工作流程:

1. 所有的写入命令追加到 aof_buf缓冲区中。

2. AOF会根据对应的策略向磁盘做同步操作。刷盘策略由appendfsync参数决定。

3. 定期对AOF文件进行重写。重写策略由auto-aof-rewrite-percentage,auto-aof-rewrite-min-size两个参数决定。

配置解析:

appendonly     yes            #yes 表示开启,默认为No
appendfilename   "appendonly.aof"     #记录写操作的日志文件名称
appendfsync     everysec         #同步数据的策略,everysec 每秒,always 有写就同步,实时的,no 大概30s一次。
no-appendfsync-on-rewrite   no      #
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size   64mb
aof-load-truncated        yes

AOF 重写机制:

随着AOF不断地记录写操作日志,因为所有的操作都会记录,所以必定会出现一些无用的日志。大量无用的日志会让AOF文件过大,也会让数据恢复的时间过长。不过Redis提供了AOF rewrite功能,可以重写AOF文件,只保留能够把数据恢复到最新状态的最小写操作集。

重写条件:

1. 手动触发

     直接调用bgrewriteaof命令

2. 自动触发

    与auto-aof-rewrite-percentage,auto-aof-rewrite-min-size两个参数有关。

    触发条件,aof_current_size > auto-aof-rewrite-min-size 并且 (aof_current_size  - aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage。

    其中,aof_current_size是当前AOF文件大小,aof_base_size 是上一次重写后AOF文件的大小,这两部分的信息可从info Persistence处获取。

 Tips

1、如果Enalbe AOF,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了。代价一是带来了持续的IO,

  二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G             以上。默认超过原大小100%大小时重写可以改到适当的数值。

2、如果不Enable AOF ,仅靠Master-Slave Replication 实现高可用性也可以。能省掉一大笔IO也减少了rewrite时带来的系统波动。代价是如果Master/Slave同时倒掉,会丢失十几分钟的数据,启动脚本也要          比较两个Master/Slave中的RDB文件,载入较新的那个。

总结比较

RDB的优点:

对性能影响最小。如前文所述,Redis在保存RDB快照时会fork出子进程进行,几乎不影响Redis处理客户端请求的效率。每次快照会生成一个完整的数据快照文件,所以可以辅以其他手段保存多个时间点的快照(例如把每天0点的快照备份至其他存储媒介中),作为非常可靠的灾难恢复手段。使用RDB文件进行数据恢复比使用AOF要快很多。

RDB的缺点:

快照是定期生成的,所以在Redis crash时或多或少会丢失一部分数据。如果数据集非常大且CPU不够强(比如单核CPU),Redis在fork子进程时可能会消耗相对较长的时间,影响Redis对外提供服务的能力。

AOF的优点:

最安全,在启用appendfsync always时,任何已写入的数据都不会丢失,使用在启用appendfsync everysec也至多只会丢失1秒的数据。AOF文件在发生断电等问题时也不会损坏,即使出现了某条日志只写入了一半的情况,也可以使用redis-check-aof工具轻松修复。AOF文件易读,可修改,在进行了某些错误的数据清除操作后,只要AOF文件没有rewrite,就可以把AOF文件备份出来,把错误的命令删除,然后恢复数据。

AOF的缺点:

AOF文件通常比RDB文件更大性能消耗比RDB高数据恢复速度比RDB慢

数据恢复

最后:

不过大多数应用场景下,建议至少开启RDB方式的数据持久化。Redis 对于数据备份是非常友好的, 因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 rename(2) 原子地用临时文件替换原来的 RDB 文件。

参考:https://baijiahao.baidu.com/s?id=1611955931705092609&wfr=spider&for=pc

https://www.cnblogs.com/tdws/p/5754706.html

https://www.cnblogs.com/ivictor/p/9749465.html

原文地址:https://www.cnblogs.com/fanggege/p/11200183.html