Redis · 特性分析 · AOF Rewrite 分析

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介:

AOF介绍

Redis提供两种持久化机制

  1. RDB: 将数据库的快照以二进制的方式保存到磁盘;
  2. AOF: 将所有写入命令及相关参数以协议文本的方式写入文件并持久保存磁盘。

本文只关心AOF,简单介绍一下:Redis Server将所有写入的命令转换成协议文本的方式写入AOF文件,例如:Server收到 set key value的的写入命令,server会进行以下几步操作:

  1. 将命令转换成协议文本,转换后的结果:*3\r\n$3\r\nSET\r\n$3\r\nKEY\r\n$5\r\nVALUE\r\n
  2. 将协议文本追加到aof缓存,也就是aof_buf;
  3. 根据sync策略调用fsync/fdatasync。

到目前为止已经成功保存数据,如果想要还原AOF,只需要将AOF里命令读出来并重放就可以还原数据库。

AOF持久化机制存在一个致命的问题,随着时间推移,AOF文件会膨胀,如果频繁写入AOF文件会膨胀到无限大,当server重启时严重影响数据库还原时间,影响系统可用性。为解决此问题,系统需要定期重写AOF文件,目前采用的方式是创建一个新的AOF文件,将数据库里的全部数据转换成协议的方式保存到文件中,通过此操作达到减少AOF文件大小的目的,重写后的大小一定是小于等于旧AOF文件的大小。

重写AOF提供两种方式

  1. REWRITE: 在主线程中重写AOF,会阻塞工作线程,在生产环境中很少使用,处于废弃状态;
  2. BGREWRITE: 在后台(子进程)重写AOF, 不会阻塞工作线程,能正常服务,此方法最常用。

本文只关心BGREWRITE的问题,因此只介绍此命令的实现机制。

AOF后台Rewrite实现方式

Server收到BGREWRITE命令或者系统触发AOF重写时,主进创建一个子进程并进行AOF重写,主进程异步等待子进程结束(信号量),此时主进程能正常接收处理用户请求,用户请求会修改数据库里数据,会使得当前数据库的数据跟重写后AOF里不一致,需要有种机制保证数据的一致性。当前的做法是在重写 AOF 期间系统会新开一块内存用于缓存重写期间收到的命令,在重写完成以后再将缓存中的数据追加到新的AOF。在处理命令时既要将命令追加到 aof_buf,也要追加到重写AOF Buffer。

AOF后台Rewrite存在的问题

重写AOF Buffer是个不限大小的buffer,但用户写入的数据量较多时会出现以下两个问题:

  1. 占用过多内存,浪费资源;
  2. 主进程将AOF buffer数据写入到新AOF文件中时会阻塞工作线程,用户正常请求的延时会变高,严重情况下会超时,主备同步也会出问题,断开重连,重新同步等。

AOF后台Rewrite解决方案

官方解决方案

主要思路是AOF重写期间,主进程跟子进程通过管道通信,主进程实时将新写入的数据发送给子进程,子进程从管道读出数据交缓存在buffer中,子进程等待存量数据全部写入AOF文件后,将缓存数据追加到AOF文件中,此方案只是解决阻塞工作线程问题,但占用内存过多问题并没有解决。

新解决方案

主要思路是AOF重写期间,主进程创建一个新的aof_buf,新的AOF文件用于接收新写入的命令,sync策略保持不变,在AOF重写期间,系统需要向两个aof_buf,两个AOF文件同时追加新写入的命令。当主进程收到子进程重写AOF文件完成后,停止向老的aof_buf,AOF文件追加命令,然后删除旧的AOF文件(流程跟原来保持一致);将将子进程新生成的AOF文件重命名为appendonly.aof.last,具体流程如下:

  1. 停止向旧的aof_buf,AOF文件追加命令;
  2. 删除旧的的appendonly.aof.last文件;
  3. 交换两个aof_buf,AOF文件指针;
  4. 回收旧的aof_buf,AOF文件;
  5. 重命令子进程生成的AOF文件为appendonly.aof.last;

系统运行期间同时存在两个AOF文件,一个是当前正在写的AOF,另一个是存量的AOF数据文件。因此需要修改数据库恢复相关逻辑,加载AOF时先要加载存量数据appendonly.aof.last,再加载appendonly.aof。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
5月前
|
存储 缓存 NoSQL
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
大数据-46 Redis 持久化 RDB AOF 配置参数 混合模式 具体原理 触发方式 优点与缺点
111 1
|
8月前
|
NoSQL Redis
Redis性能优化问题之根据 Redis 的 AOF 配置级别优化性能,如何解决
Redis性能优化问题之根据 Redis 的 AOF 配置级别优化性能,如何解决
|
9月前
|
存储 NoSQL 安全
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
127 1
|
9月前
|
NoSQL 容灾 Redis
Redis系列学习文章分享---第十一篇(Redis高级实战篇---RDB演示 +RDB的fork原理+A0F演示 +RDB和AOF)
Redis系列学习文章分享---第十一篇(Redis高级实战篇---RDB演示 +RDB的fork原理+A0F演示 +RDB和AOF)
62 0
|
10月前
|
存储 监控 NoSQL
【Redis技术专区】「优化案例」谈谈使用Redis慢查询日志以及Redis慢查询分析指南
【Redis技术专区】「优化案例」谈谈使用Redis慢查询日志以及Redis慢查询分析指南
216 0
|
缓存 NoSQL Redis
Redis(二十六)-持久化操作之AOF
上一篇文章我们介绍了 Redis(二十五)-持久化操作之RDB ,这篇文章接着来介绍另一种持久化的方式AOF。
292 0
Redis(二十六)-持久化操作之AOF
|
缓存 NoSQL Redis
redis灵魂拷问:聊一聊AOF日志重写
redis灵魂拷问:聊一聊AOF日志重写
297 0
redis灵魂拷问:聊一聊AOF日志重写
|
NoSQL 前端开发 Java
【Redis基础】一起读懂Redis持久化机制(RDB+AOF 图文详解)
案例详解Redis持久化机制!一起打卡学习吧!
150 0
【Redis基础】一起读懂Redis持久化机制(RDB+AOF 图文详解)
|
算法 NoSQL Redis
Redis · 引擎特性 · 基于 LFU 的热点 key 发现机制
前言 业务中存在访问热点是在所难免的,redis也会遇到这个问题,然而如何发现热点key一直困扰着许多用户,redis4.0为我们带来了许多新特性,其中便包括基于LFU的热点key发现机制。 Least Frequently Used Least Frequently Used——简称LFU,意为最不经常使用,是redis4.0新增的一类内存逐出策略,关于内存逐出可以参考文章《Redis数据过期和淘汰策略详解》。
1678 0
|
缓存 NoSQL Redis
Redis实践(十一)-缓存设计与优化
很小的内存就能实现过滤,适用于固...
1124 0