Redis 分享-AOF的阻塞简单记录

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 公司分享讨论一些东西 拿出来大家分享讨论下

背景

团队内每周延安大学分享中,redis中讨论了一个AOF会阻塞主线程的问题,这个问题之前没考虑到过,一直以为fork了子进程一定不会阻塞,没有深度考虑。

因为大家也没有深入研究,这里整理一下,因为这块确实实践较少,可能有描述不准确的,大家多多提意见指正,我多多完善。

AOF

redis中文官网:http://www.redis.cn/topics/persistence.html

什么是AOF

以下定义均来自中文官网

只追加操作的文件(Append-only file,AOF)

快照功能(RDB)并不是非常耐久(dura ble): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。

你可以在配置文件中打开AOF方式:

appendonly yes

从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。

日志重写

因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。举个例子, 如果你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。

为了处理这种情况, Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。执行 BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。

Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4 则可以自动触发 AOF 重写, 具体信息请查看 2.4 的示例配置文件。

通过官网基本可以了解了什么是AOF和重写,如果可以想了解AOF和RDB的区别,官网也有描述可以通过上面链接去阅读。

rdb:默认开启,文件小,格式紧凑,数据恢复快,比较适合用来做灾备,服务宕机丢数据更多一些

aof:默认关闭,文件大,数据恢复慢,但是数据更加完整,支持多种同步策略。

官方推荐使用混合模式。

AOF写入策略

由appendfsync参数控制:

可配置的值 说明
always 命令写入buf后调用系统调用fsync同步AOF文件,fsync完成后线程返回。
no 命令写入buf后调用系统调用write操作,后续fsync同步操作由操作系统来完成,一般为30秒一次。
everysec 命令写入buf后调用系统调用write操作,后续fsync同步操作专门线程每一秒调用一次。

everysec是always和no的折中,是性能和安全性的这种,是redis默认的配置,也是比较推荐的配置。

重写流程图

重写流程:
  1. bgrewriteaof 触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行
  2. 主进程fork出子进程执行重写操作,保证主进程不会阻塞
  3. 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区 保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失
  4. 1).子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。2).主进程把aof_rewrite_buf中的数据写入到新的AOF文件
  5. 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写


流程图来源:https://blog.csdn.net/wsdc0521/article/details/106765809

阻塞

虽然在everysec配置下aof的fsync是由子线程进行操作的,但是主线程会监控fsync的执行进度。

主线程在执行时候如果发现上一次的fsync操作还没有返回(也有一种对比上一次的fsync操作时间,大于2秒阻塞的),那么主线程就会阻塞。

解决阻塞

  1. 修改配置为yes,减少IO竞争:

no-appendfsync-on-rewrite yes/no

  • 设置为yes,重写期间会停止appendfsync操作,避免io竞争((表示在日志重写时,不进行命令追加操作,而只是将命令放在重写缓冲区里,避免与命令的追加造成磁盘IO上的冲突))。但是这样的风险:如果在aof重写期间redis宕机了,那么aof的数据便会丢失,可靠性下降
  • 配置就是设置为no时候,aof重写期间还是会执行fsync,这个时候就会产生IO竞争,有可能阻塞主线程。如果当前AOF文件很大,那么相应的rewrite时间会变长,appendfsync被阻塞的时间也会更长
  1. 为了保证可靠性,进行集群化
  • 给当前Redis实例添加slave节点,当前节点设置为master, 然后master节点关闭AOF,slave节点开启AOF。
  • 这样的方式的风险是如果master挂掉,尚没有同步到salve的数据会丢失。而且 集群选举时,aof配置怎么根据选举结果动态修改修改,可能需要手动上去改一遍。感觉运维成本比较大。
  1. 闲的时间定时重写、提升服务器io性能
  1. 在凌晨低峰期定时手动执行bgrewriteaof命令完成每日一次的AOF重写
  2. 比如使用ssd
  1. 将配置设为no
  2. 硬盘采用高速固态硬盘SSD
  1. 如果是三方服务器,购买私有或者用户隔离的混合云,不要购买共有云,不要让其他用户影响该服务器磁盘稳定性
  1. 上监控人工介入,监控所有系统必不可少的一部分。
  1. 在重写时为了避免硬盘空间不足或者IO使用率高影响重写功能,我们还添加了硬盘空间报警和IO使用率报警保

扩展链接


相关实践学习
基于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
目录
相关文章
|
7天前
|
存储 缓存 NoSQL
Redis中的rdb和aof
本文深入探讨了Redis的持久化机制,包括RDB和AOF两种方式。详细解释了RDB的工作原理、优势和劣势,以及AOF的实现原理、配置选项、文件重写机制和三种数据同步方式,还介绍了AOF文件修复工具redis-check-aof的使用,并通过实例展示了如何开启和配置AOF持久化方式。
Redis中的rdb和aof
|
22天前
|
存储 NoSQL Redis
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
Redis持久化、RDB和AOF方案、Redis主从集群、哨兵、分片集群、散列插槽、自动手动故障转移
SpringCloud基础7——Redis分布式缓存,RDB,AOF持久化+主从+哨兵+分片集群
|
2月前
|
缓存 NoSQL Linux
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
【Azure Redis 缓存】Windows和Linux系统本地安装Redis, 加载dump.rdb中数据以及通过AOF日志文件追加数据
|
5天前
|
存储 缓存 NoSQL
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
15 0
|
2月前
|
存储 NoSQL Redis
Redis 文件总大小问题之计算待加载AOF文件总大小如何解决
Redis 文件总大小问题之计算待加载AOF文件总大小如何解决
|
2月前
|
NoSQL Redis
Redis AOF重写问题之减少CPU和fork开销如何解决
Redis AOF重写问题之减少CPU和fork开销如何解决
|
2月前
|
NoSQL Redis 数据库
Redis AOF重写问题之同一数据产生两次磁盘IO如何解决
Redis AOF重写问题之同一数据产生两次磁盘IO如何解决
Redis AOF重写问题之同一数据产生两次磁盘IO如何解决
|
2月前
|
监控 NoSQL Redis
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.
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.
|
2月前
|
NoSQL Redis
Redis AOF重写问题之产生过多INCR AOF文件如何解决
Redis AOF重写问题之产生过多INCR AOF文件如何解决
|
2月前
|
人工智能 NoSQL Redis
Redis 旧AOF文件移动问题之文件路径如何解决
Redis 旧AOF文件移动问题之文件路径如何解决
下一篇
无影云桌面