小小去旅游啦,去的是哪里,这次小小去的是我家的后花园,哦不,是颐和园,当年慈禧太后挪用海军经费建立的一个大圆子。小小开始晒旅游照了,爆旅游照骗开始
这是大门,小小从这里进入大门。但是说的是门票已经售完,小小幸好当时买有预约票,所以小小直接进去啦。这是颐和园的西门。这是颐和园西门的大河
由于风大,游船暂停运营。只能观望喽
远方的小桥。此时水天一色。
当时看到这个小楼的时候,震惊了,因为这个小楼是如此的熟悉。
不发了,不发了,当时玩到这就太晚了,直接回家,心累,没有办法,谁让自己也是如此的累呢。
下面开始正文,正文内容超详细揭秘redis持久化内容。
前言Redis数据全部保存在内存中,如果突然宕机,数据会全部丢失,因此必须有一种机制来保证Redis的数据不会因为故障而丢失,这种机制为Redis的持久化机制。Redis持久化策略有两种,一种是快照,第二种是AOF日志,快照是一次全量备份,AOF是日志是连续的增量备份,快照是内存数据的二进制序列化形式,在保存上相当的紧密,而AOF记录的是内存数据修改的指令记录的文本,AOF日志长期在运行的时候会造成无比的庞大,数据库重启的时候需要执行AOF会造成时间相当的漫长,所以需要定期进行AOF重写,达到AOF日志的瘦身。
Redis快照原理我们知道Redis是单线程程序,这个程序需要同时负责多个客户端的并发请求,和内存逻辑的处理。在服务线上请求的同时,Redis还需要进行内存快照,内存快照要求Redis必须进行文件IO读取,可文件IO操作,不能使用复用的多路API。即,单线程在服务器请求的同时,还要进行文件IO操作,文件IO会严重拖慢服务器的性能。此时还有一个重要的问题,为了不阻塞线上业务,Redis还需要一边持久化,一边响应客户端的请求,持久化的同时,内存数据结构还在改变,例如,如果一个大型的hash数据结构正在持久化,此时直接删除,持久化正在进行,此时即产生了冲突。这个时候Redis使用的是操作系统的多进程COW机制实现持久化
Fork多进程Redis在持久化的时候,会调用glibc函数,fork产生一个子进程,快照持久化完全交给子进程处理,父进程继续处理客户端的请求,子进程刚刚产生的时候,和父进程共享内存的代码块和数据块, 此时,子进程会进行数据持久化,不会修改现有内存的数据结构,只是对数据结构进行遍历读取,序列化写入磁盘,父进程需要持续的处理客户端的请求,对内存的数据结构进行不间断的修改。使用的机制是COW实现数据的分离。随着父进程修改操作持续进行,越来越多的共享数据被分离,内存会持续增长,但不会超过2倍,因为Redis中的冷数据占比比较高。所以很少会出现全部被分离的情况,被分离的往往只有一部分。子进程因为数据没有变化,看到的只是那一瞬间的情况,再也不会发生改变,所以称之为快照。
AOF原理AOF日志保存的Redis服务器的顺序指令序列,AOF指令只记录对内存数据修改时的记录。AOF日志记录了自Redis实例创建以来的所有修改的指令序列,那么就可以通过对一个空的Redis序列执行一个AOF文件,此时会进行重放,达到恢复实例的数据结构的状态。Redis会在进行回放之前进行数据校验和数据修改,实现防止错误的逻辑进入其中。Redis在长期运行过程中,会造成日志的越来越长,会造成相当长的耗费时间,此时需要进行对AOF日志进行瘦身。
AOF重写
Redis的bgrewriteaof指令用于对Redis的AOF进行日志瘦身,原理,使用一个开源的进程实现对内存的遍历,转换成一系列的Redis指令,序列化到一个新的AOF日志中,序列化完毕以后,对发生增量的AOF进行日志的增量同步到新的AOF日志中,然后拿取新的替换旧的AOF日志。这样瘦身工作就完成了
fsyncAOF日志是以文件形式存在的,当程序对AOF日志文件进行写操作的时候,实际上是吧内容写到一个内存缓存中,然后内核会进行定期的刷新到磁盘中。如果突然宕机,会出现日志的丢失,此时使用的是Linux的glibc的fsync函数实现强制刷新到磁盘中。在生产环境中,一般是每隔一秒调用这个函数,实现强制刷新的。
关于运维快照是通过开启子进程的方式开启的,会发生如下的系统资源耗费
- 遍历整个内存,大块写磁盘会增加负担。
- AOF的sync会增加Reids的IO的时间,降低性能。所以综上所述,一般情况是在主节点不做操作,持久化在从节点进行。从节点备份节点,由于没有客户端的压力,所以不会影响现有系统的使用。
重启Redis以后,使用快照恢复内存,会丢失大量的数据,使用AOF指令执行,会导致过慢,所以出现了把这两种方法合并的方法,混合持久化。
如上图,快照和AOF保存在一起,这里的AOF不再是全量,是增量,是自持久化开始到持久化结束这一段时间发生的增量的AOF日志,这部分AOF日志通常很小。于是在重启Redis的时候,会先加载RDB中的内容,即快照中的内容,再以增量的方式,实现指令的重放,使得重启效率大大的提升。
关于作者我是小小,一个生于二线,在一线城市工作的佛系程序猿,我们下期再见。