Redis持久化

Posted hellohello

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis持久化相关的知识,希望对你有一定的参考价值。

RDB

将redis内存中的数据一次完整地写入一个二进制文件中,复杂度是O(n),生成的新文件会将老的rdb文件替换,相关指令:

  • save:阻塞直至快照是生成完成
  • bgsave:创建后台进程来生成快照,fork生成子进程的过程是阻塞的,但一般来说这个过程比较快,创建的子进程名字是redis-rdb-bgsave。

可以配置文件中配置快照的触发条件,按照某种条件自动触发bgsave:缺点能以控制,可能会造成写入硬盘的频率高,而且两次save之间,如果redis宕机,就会导致丢失期间的数据。所以一般关闭自动写入,不使用这个功能。

因为redis是单线程的,所以一台主机多核可能会运行多个redis程序。每个rdb文件以端口命名:dump-${port}.rdb

生成rdb文件的策略:先写到一个临时文件,后将临时文件重命名为实际的rdb文件名。生成过程中会扫描全部数据,期间redis可能会产生写操作,此时的策略是copy-on-write。也就是当父进程没有写内存时,父子进程共用同一份内存,当父进程写内存时,会对内存进行复制一份出现,以保证子进程读取的内存不变。这时候内存才会增长,所以一般在写入比较少时,才进行持久化。

AOF

通过appendonly yes来开启AOF功能。这类似于日志,将每次写操作都记录到文件中,实时性更强。每次不是直接写文件,而是先到缓冲区中,然后同步到硬盘上。同步的频率是可以通过配置appendfsync来控制的:

  • always:每条命令实时同步,所以不会丢失数据,磁盘IO可能会很高
  • everysec:每秒执行一次,所以宕机的话最多会丢失一秒的数据。默认配置
  • no:同步的时机由操作来决定。一般不使用这种

AOF重写

因为每次写操作都会记录到文件中,所以文件体积可能比较大。为了解决这个问题,降低文件中指令的数量,会将多条指令合并成一条,如两个incr自增操作,会变成一条set xxx 2的指令,即只记录关键结果的指令(忽略这个结果的生成过程),不会保存过期数据。重写后能减少磁盘空间占用,加快数据恢复速度。

bgrewriteaof:执行这个指令,会开启一个子进程、对已有的aof文件进行格式化(重写),然后新内容替换老内容。

AOF重写时可能会有阻塞问题:当重写时,redis发生写操作,并且当前数据量比较大,导致重写比较慢。no-appendfsync-on-rewrite这个配置默认值是no,就是正在重写AOF文件,redis出现写操作,会将新增的写指令同步到磁盘中,因为AOF文件没重写完,就会导致阻塞问题。要解决这个阻塞问题,将配置设置为yes,写操作就不会阻塞了。此时新增的写操作不会同步到磁盘中,而先临时记录到内存中,后续再同步到磁盘,所以不会有阻塞问题。

AOF和RDB对比

AOF优先级更高:如果同时开启了aof和rdb,然后也生成了对应的数据文件,那么redis重启时,会读取aof文件,而不读取rdb。因为aof的数据完整程度比rdb要高。

AOF体积大:,RDB文件是二进制格式,有自己的压缩方式,而AOF类似于日志,记录的是指令,而不是具体的数据

AOF恢复速度慢:通过指令来恢复数据。

AOF数据安全性更高:按照AOF同步策略,最多只可能丢失1秒或一个指令的数据。

AOF:更轻量级,因为是增量备份的,属于对文件追加内容,RDB每次备份需要扫描全部数据。

使用小分片:一个主机中,设置redis的最大内存为4G,开启多个redis。每个小分片内的数据量较少,数据持久化更快。

以上是关于Redis持久化的主要内容,如果未能解决你的问题,请参考以下文章

Redis高级(持久化--redis主从架构--redis哨兵模式--redis分片集群)

Redis持久化

redis 之redis持久化rdb与aof

redis学习系列——redis持久化

Redis学习-4-2 Redis持久化

redis 的持久化策略有几种