侧边栏壁纸
  • 累计撰写 98 篇文章
  • 累计创建 20 个标签
  • 累计收到 3 条评论

Redis持久化

林贤钦
2021-04-13 / 0 评论 / 1 点赞 / 828 阅读 / 1,583 字
温馨提示:
本文最后更新于 2021-07-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

持久化

Redis的数据全部在内存中,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证Redis的数据不会因为故障而丢失,这种机制就是Redis的持久化机制。

Redis的持久化机制有两种,快照rdb和aof日志。

RDB快照

快照是一次全量备份,是内存数据的二进制序列化形式,在存储上非常紧凑。

Redis是单线程程序,这个线程要同时负责多个客户端套接字的并发读写操作和内存数据结构的逻辑读写。如果在服务线上请求的同时,Redis还要进行内存快照,进行io操作,那么这样会严重拖累服务器的性能,这明显和Redis的高性能违背。

fork(多进程)

Redis在持久化时,会调用glibc的函数fork产生一个子进程,快照持久化完全交给子进程来处理,主进程继续处理客户端的请求。子进程刚刚产生时,它和主进程共享内存的代码段和数据段,子进程做数据持久化,不会修改现有的内存数据结构,它只是对数据结构进行遍历读取,然后序列化写到磁盘中。但父进程不一样,它必须持续服务客户端请求,然后度内存数据结构进行不间断的修改。

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

数据段是由很多操作系统的页面组合而成,当父进程对其中一个页面的数据进行修改时,会将被共享的页面复制一份分离出来,然后对这个复制的页面进行修改。

AOF原理

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

Redis会在收到客户端修改指令,进行参数校验、逻辑处理,如果没问题了就立即将该指令文本存储到AOF日志中。也就是先执行指令才将日志存盘

AOF重写

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

fsync

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

如果机器突然宕机了,AOF的日志内容可能还没来得及刷到磁盘中,这时候可能会出现日志丢失。那怎么办?

linux的glibc提供了fsync(int df)函数可以将指定文件的内容强制从内存缓存刷到磁盘。只要Redis进程实时调用fsync函数就能保证AOF日志不丢失,但是fsync是一个磁盘IO操作,在Redis通常是每隔1s左右执行一次fsync操作,这个1s的周期是可以配置的。

通常主节点不会进行持久化,持久化操作主要在从节点进行,从节点是备份节点,没有来自客户端请求的压力

Redis 4.0 混合持久化

重启Redis的时候,我们很少使用RDB来恢复内存状态,因为会丢失大量的数据,我们通常使用AOF日志重放,但是AOF重放相对于RDB会慢很多,如果Redis数据比较多,启动会花费很长的时间。

Redis 4.0为了解决这个问题,带来了一个新的持久化方式-------混合持久化

Redis_RDB_AOF

将RDB文件的内容和AOF日志文件存放在一起,这里的AOF不再是全量的日志,而是从持久化结束这段时间发生的增量AOF日志,这里的日志通常很小。重启的时候就先加载RDB的内容,然后再重放AOF日志,启动效率大幅度提升。

1

评论区