当前位置: 首页 > article >正文

【后端面试总结】Redis持久化

Redis的持久机制有两种,第一种是快照,第二种是AOF日志。

快照是一次全量备份,AOF日志是连续的增量备份。快照是内存数据的二进制序列化形式,在存储上非常紧凑,而AOF日志记录的是内存数据修改的指令记录文本。AOF日志在长期的运行过程中会变得无比庞大,数据库重启时需要加载AOF日志进行指令重放,这个时间就会无比漫长,所以需要定期进行AOF重写,给AOF日志进行瘦身。

快照:

Redis使用操作系统的多进程COW(Copy on Write)机制来实现快照持久化。

Redis在持久化时会调用glibc的函数fork产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。子进程刚刚产生时,它和父进程共享内存里面的代码段和数据段。这时你可以把父子进程想象成一个连体婴儿,它们在共享身体。这是Linux操作系统的机制,为了节约内存资源,所以尽可能让他们共享起来。在进程分离的一瞬间,内存的增长几乎没有明显变化。

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

这个时候就会使用操作系统的COW机制来尽心数据段页面的分离。数据段是由很多操作系统的页面(Page)组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。这是子进程相应的页面是没有变化的,还是进程产生时那一瞬间的数据。

随着父进程修改操作的持续进行,越来越多的共享页面被分离出来,内存就会持续增长,但是也不会超过原有数据内存的2倍大小。另外,Redis实例里冷数据占的比例往往是比较高的,所以很少会出现所有的页面都被分离的情况,被分离的往往只有其中一部分农业面。每个页面的大小只有4KB,一个Redis实例里面一般都会有成千上万个页面。

子进程因为数据没有变化,它能看到的内存里的数据在进程产生的一瞬间就凝固了,再也不会改变,这也是为什么Redis的持久化叫“快照”的原因。接下来子进程就可以非常安心地遍历数据,进行序列化写磁盘了。

AOF:

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

Redis会在接收到客户端修改指令后,进行参数校验、逻辑处理,如果没问题,就立即将该指令文本存储到AOF日志中,也就是说,先执行指令才将日志存盘。这点不同于leveldb、hbase等存储引擎,它们都是先存储日志再做逻辑处理。

Redis在长期运行的过程中,AOF的日志会越来越长。如果实例宕机重启,重放整个AOF日志会非常耗时,导致Redis长时间无法对外提供服务,所以需要对AOF日志瘦身。

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

Linux的glibc提供了fsync(int fd)函数可以将制定文件的内容强制从内核缓存刷到磁盘。只要Redis进程实时调用fsync函数就可以保证AOF日志不丢失。但是fsync是一个磁盘IO操作,它很慢!如果Redis执行一条指令就要fsync一次,那么Redis高新更能的地位就不保了。

所以在生产环境的服务器中,Redis通常是每隔1s左右执行一次fsync操作,这个1s的周期是可以配置的。这是在数据安全性和性能之间做的一个折中,在保持高新更能的同时,尽可能使数据少丢失。


http://www.kler.cn/a/414256.html

相关文章:

  • shell查看服务器的内存和CPU,实时使用情况
  • 【docker】安装数据库脚本
  • 【工具】JS解析XML并且转为json对象
  • 养老院、学校用 安科瑞AAFD-40Z单相电能监测故障电弧探测器
  • 人工智能如何改变你的生活?
  • python画图plt.close()一直闪烁
  • 展示和添加篮球队信息--laravel与elementplus
  • Flutter:GetBuilder页面模板,可复用,视图,控制器分离
  • IntelliJ IDEA安装内网穿透实现远程连接家里或公司的MySQL数据库助力开发
  • 【C语言】结构体、联合体、枚举类型的字节大小详解
  • 累积局部效应 (ALE) 图分析记录
  • Unity中Http框架
  • 微知-arp如何删除所有表项?(arp -d; ip neighbor delete 192.168.0.100)
  • 力扣—912. 排序数组
  • queue 和 Stack
  • Unity shaderlab 实现LineSDF
  • 根据中缀二叉树构建中缀表达式
  • 「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历
  • Unity中的数学应用 之 插值函数处理角色朝向 (初中难度 +Matlab)
  • 【计算机网络】—— 物理层
  • IPguard与Ping32对比评测:数据安全保护谁更强?
  • 【热门主题】000067 React前端框架:探索高效Web开发之路
  • 在C#中使用OpenCV的.net包装器EmguCV
  • 11.25Scala
  • Maven 依赖项配置
  • 初级数据结构——二叉搜索树题库(c++)