程序员

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

作者:admin 2021-08-16 我要评论

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

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)
背景

团队内每周延安大学分享中 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 的示例配置文件。

Everything about Redis 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默认的配置 也是比较推荐的配置。

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


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

阻塞

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

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

解决阻塞修改配置为yes 减少IO竞争

no-appendfsync-on-rewrite yes/no

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



本文转自网络,原文链接:https://developer.aliyun.com/article/787047

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • Redis 分享-AOF的阻塞简单记录

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

  • 5G会给物联网行业带来哪些变化?

    5G会给物联网行业带来哪些变化?

  • 物联网太难 ? 不妨试试用Python来开发

    物联网太难 ? 不妨试试用Python来开发

  • HaaS EDU场景式应用学习 - 首页信息屏

    HaaS EDU场景式应用学习 - 首页信息屏

腾讯云代理商
海外云服务器