服务器后端开发程序员技术栈Amazing Redis

Redis持久化的原理及优化

2019-05-26  本文已影响0人  全菜工程师小辉

Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性。

RDB

保存数据快照至一个RDB文件中,用于持久化。RDB操作和Mysql Dump相似。

执行方式

save和bgsave的对比

Redis-RDB

注意:

除了上述三种执行方式,以下情况也会生成RDB文件:

Redis RDB过程

RDB的缺点

AOF

采用AOF持久方式时,Redis会把每一个写请求都记录在一个日志文件里,AOF操作和Mysql Binlog相似。通过AOF重写机制减少AOF文件的体积,从而减少恢复时间。

执行方式

Redis AOF的执行方式对比

AOF重写

为了解决AOF文件体积膨胀的问题,Redis提供了AOF重写功能:Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个文件所保存的数据库状态是相同的,但是新的AOF文件不会包含任何浪费空间的冗余命令,通常体积会较旧AOF文件小很多。

AOF重写方式

AOF重写并不需要对原有AOF文件进行任何的读取,写入,分析等操作,这个功能是通过读取服务器当前的数据库状态来实现的。

RDB vs AOF

Redis RDB和AOF的对比

Redis启动时的数据加载

Redis RDB和AOF的对比

Redis启动数据加载流程:

  1. AOF持久化开启且存在AOF文件时,优先加载AOF文件。
  2. AOF关闭或者AOF文件不存在时,加载RDB文件。
  3. 加载AOF/RDB文件成功后,Redis启动成功。
  4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息。

开发运维中常见的问题

fork操作

fork()的实际开销就是复制父进程的页表以及给子进程创建一个进程描述符,所以速度一般比较快

内存量越大,耗时越长;物理机相对较快,虚拟机相对较慢。

优化方法

  1. 优先使用物理机或者高效支持fork操作的虚拟化技术
  2. 控制Redis实例最大可用内存maxmemory
  3. 合理配置Linux内存分配策略:vm.overcommit_memory=1。默认值为0,会使Linux在内存分配时,发现不够内存不足时,不会进行分配,进而造成fork阻塞
  4. 降低fork频率。例如放宽AOF重写自动触发时机或者减少不必要的主从全量复制

进程外开销

优化方法

  1. 不要和高硬盘负载服务部署在一起:存储服务、消息队列等
  2. 配置no-appendfsync-on-rewrite=yes。这样在AOF重写的期间,不要进行AOF追加操作(主线程只将数据写入缓冲区),可以减少内存的开销。

但如果AOF重写期间,Redis宕机的话,在Linux的系统默认配置下,最多会丢失30s的数据。如果无法忍受数据丢失,no-appendfsync-on-rewrite配置no;如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为yes。

  1. 根据写入量决定磁盘类型:例如ssd
  2. 单机多实例持久化文件目录可以考虑分盘,或者使用类似cgroups机制进行硬盘资源的合理分配

AOF追加阻塞

Redis RDB和AOF的对比

例如在AOF的everysec策略中,主线程会对比上次fsync的时间,如果距离上次fsync时间超过两秒,就会造成主线程阻塞(等待同步线程同步完成)。

日常开发可以使用info persistence命令,查看历史发生AOF阻塞的次数;然而需要了解AOF追加阻塞的发生时间则需要查看Redis日志。

发送AOF追加阻塞的时候,日志如下:

Asynchronous AOF fsync is taking too long (disk is busy?). Writing the AOF buffer without waiting for fsync to complete, this may slow down Redis.

优化方法(参考其他方面的优化点)

哎呀,如果我的名片丢了。微信搜索“全菜工程师小辉”,依然可以找到我
上一篇 下一篇

猜你喜欢

热点阅读