我命由我,不由天!


  • 搜索
prometheus docker golang linux kubernetes

redis-持久化(十二)

发表于 2021-05-30 | 0 | 阅读次数 364

未雨绸缪——持久化

Redis数据全部在内存中,如果宕机,数据将全部丢失。需要通过持久化机制

持久化机制有两种

  1. 快照
  2. AOF日志

快照试一次全量备份,AOF日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而AOF日志是连续的增量备份

AOF日志在长期运行过程中变得无比庞大,需要定期进行AOF重写,给日志瘦身

快照原理

Redis是单线程程序,在服务线上请求的同时,Redis还需要进行内存快照,内存快照要求Redis必须进行文件IO操作。

Redis使用操作系统的多进程COW机制来实现快照持久化

fork(多进程)

Redis在持久化时会调用glibc的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时和父进程共享内存里面的代码段和数据段。

子进程做数据持久化,不会修改现有的内存数据结构,只是对数据结构进行遍历读取,然后序列化写到磁盘中。但是父进程不一样,它必须持续服务客户端请求,然后对内存数据结构进行不间断的修改。

使用操作系统的COW机制来进行数据段页面的分离,当父进程对其中的页面数据进行修改时,会将被共享的页面复制一份出来分离。修改操作进行,共享的页面被分离雨多。

子进程因为数据没有变化,它能看到内存里的数据在进程产生的一瞬间就凝固了,这就是Redis的持久化叫快照的原因。接下来子进程可以安心遍历。

AOF原理

AOF日志存储的是Redis服务器的顺序指令序列,AOF只记录对内存进行修改的指令记录。

Redis会在收到客户端修改指令后,进行参数校验、逻辑处理,就理科将该指令文本存储到AOF日志中(先执行指令再写日志)

Redis在长期运行的过程中,AOF日志会越来越常,重放整个AOF日志会非常耗时,所以需要对AOF日志瘦身。

AOF重写

Redis提供了bgrewriteaof指令用于对AOF日志进行瘦身,其原理是开辟一个子进程对内存就行遍历,转换成一系列的Redis操作指令,序列化到一个新的AOF日志文件中。序列化完毕后再讲操作期间发生的增量AOF日志追加到这个新的AOF日志文件中,追加完毕后就立即替代旧的AOF日志文件,瘦身工作就完成了

fsync

AOF日志是以文件的形式存在的,当程序对AOF日志文件进行写操作时,实际上是将内容写到内核为文件描述符分配的一个内存缓冲中,然后内核会异步将脏数据刷回到磁盘中。

AOF日志内容可能还没来得及完全刷到磁盘中,这个时候就会出现日志丢失。

Linux的glibc提供fsync函数可以将指定文件的内容强制从内核缓存刷到磁盘。所以生产环境的服务器,Redis通常是每隔1s左右执行一次fsync操作,这个1s是数据安全和性能之间的一个折中

运维

快照是通过开启进程的方式进行的,是比较耗资源的

  1. 遍历整个内存,大块写磁盘会加重系统负载
  2. AOF的fsync是一个耗时的IO操作,会降低Redis性能,同时也会增加系统IO负担

所以Redis的主节点不会进行持久化操作,从节点进行持久化,在网络分区的情况下,增加一个从节点来降低网络分区的概率,只要一个从节点数据同步正常,数据就不会丢失。做好实时监控工作,保证网络顺畅或能快速修复

Redis 4.0混合持久化

重启Redis时,很少使用rdb来恢复内存状态,因为会丢失大量的数据,使用AOF日志重放,但速度很慢。

4.0增加了混合持久化,AOF不再是全量的日志,而是自持久化开始到持久化结束的这段时间发生的增量AOF日志,这部分日志很小。

重启的时候,先加载rdb内容,再重放增量AOF日志,重启效率大幅提升

  • 本文作者: Dante
  • 本文链接: https://gaodongfei.com/archives/redis-持久化
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
redis-RESP协议(十一)
redis-管道(十三)
  • 文章目录
  • 站点概览
Dante

Dante

119 日志
5 分类
5 标签
RSS
Creative Commons
0%
© 2023 Dante
由 Halo 强力驱动
|
主题 - NexT.Pisces v5.1.4
沪ICP备2020033702号