Redis · 特性分析 · AOF Rewrite 分析

本文涉及的产品
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。

目录
相关文章
|
存储 设计模式 负载均衡
一文读懂Spring动态配置多数据源---源码详细分析(下)
一文读懂Spring动态配置多数据源---源码详细分析
2589 0
一文读懂Spring动态配置多数据源---源码详细分析(下)
|
10月前
|
存储 供应链 物联网
《区块链为翼,开启物联网数据可信共享新时代》
在万物互联时代,物联网(IoT)设备产生海量数据,但数据共享面临信任缺失、孤岛化等困境。区块链的分布式账本技术通过去中心化、不可篡改、可追溯和共识机制,为解决这些问题提供了新思路。它确保数据来源可信、传输安全,并通过智能合约实现自动化、透明化的数据共享。应用案例如沃尔玛的食品供应链追踪和GE的工业设备监控,展示了其巨大潜力。尽管存在性能瓶颈和隐私保护挑战,区块链有望打破数据孤岛,释放物联网数据价值,推动产业创新与变革。
261 28
|
8月前
|
机器学习/深度学习 人工智能 自然语言处理
3步,0代码!一键部署DeepSeek-V3、DeepSeek-R1
3步,0代码!一键部署DeepSeek-V3、DeepSeek-R1
293 0
|
12月前
|
数据采集 JavaScript 前端开发
浏览器自动化
浏览器自动化利用工具(如Selenium WebDriver、Puppeteer)模拟用户行为,实现测试、数据抓取等功能。它涵盖启动/关闭浏览器、元素定位操作、事件模拟、性能及可访问性测试等,广泛应用于Web应用的开发与维护,提升测试效率和可靠性。
|
JSON 前端开发 测试技术
API接口 |产品经理一定要懂的10%技术知识
作为产品经理,掌握约10%的技术知识对处理API相关工作至关重要。这包括理解API的基本概念及其作为数据交换的桥梁作用;熟悉JSON和XML两种主要数据格式及其特点;了解常见HTTP请求方法(GET、POST、PUT、DELETE)及响应状态码;关注API安全性,如认证授权和数据加密;掌握API版本管理和错误处理技巧;重视性能优化,以提升用户体验;参与API联调测试,确保稳定可靠;并与前后端团队紧密协作,选择合适的第三方API服务,推动产品高效开发。
|
监控 Linux 测试技术
【实战技巧】使用inotify实现实时文件监控
`inotify`是Linux内核提供的文件系统监控机制,用于实时捕获文件和目录的创建、删除、移动和修改等事件。通过`inotify_init`初始化,`inotify_add_watch`添加监视点,如`. IN_ACCESS`, `. IN_MODIFY`等,及`inotify_rm_watch`移除监视。示例代码展示了监听指定路径下文件修改事件,当事件发生时打印信息。使用`inotify`能高效地构建实时应用,如文件同步和日志监控,简化系统编程。
1896 114
|
11月前
|
数据采集 监控 搜索推荐
用户画像构建:年度数据分析的用户视角
在数据驱动的时代,年度数据分析对企业战略规划和运营优化至关重要。本文从数据收集、预处理、分析、可视化到应用实践,全面探讨如何通过年度数据分析实现业务增长,助力企业精准决策。通过构建全面的数据源体系、清洗整合数据、洞察趋势、发现机会,并借助数据可视化工具,最终将数据转化为实际行动,持续优化企业运营。
|
自然语言处理 安全 Java
Aviator Java 表达式引擎
AviatorScript 是一门高性能、轻量级寄宿于 JVM 之上的脚本语言。
350 10
|
Web App开发 缓存 前端开发
前端性能优化技巧与工具
【6月更文挑战第30天】前端性能优化旨在提升Web应用速度和响应性,关乎用户体验、转化率及SEO。关键技巧包括减少HTTP请求、压缩资源、利用缓存、异步加载和优化DOM操作。工具如Lighthouse、PageSpeed Insights、Webpack Bundle Analyzer及Chrome DevTools提供性能分析和优化建议。优化是持续的过程,适应复杂Web需求。
|
传感器 物联网 智能硬件
什么是 Piconet?
【8月更文挑战第23天】
459 0