redis灵魂拷问:聊一聊AOF日志重写

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
日志服务 SLS,月写入数据量 50GB 1个月
简介: redis灵魂拷问:聊一聊AOF日志重写

AOF日志重写到底会不会阻塞主线程?




01



AOF介绍

redis的AOF日志,是redis持久化的一种方式,它是一种write after log,即先执行命令后记录日志。这样的好处是日志不会记录执行失败的命令,同时记录日志不会阻塞当前命令执行。


记录AOF是在主线程中执行的,所以也会阻塞主线程。这个跟AOF的写回策略有关,这个配置项参数叫appendfsync,在redis.conf文件中,默认值是everysec。下面是3种写回策略的比较:

写回策略

策略说明

优点

缺点

always

执行命令同步写盘

基本不丢失命令

性能损耗大

everysec

每秒写一次盘

always性能损耗小

可能丢失1秒内命令

no

操作系统控制写盘

性能损耗最新

可能会丢失很多命令

这样,我们就需要在性能和可靠性之间做一些取舍了。


当redis上执行的命令越来越多,AOF日志文件会变得很大,这样AOF文件追加命令会很慢,而且操作系统对文件大小也有一定的限制,再者如果使用AOF做主从同步或数据恢复的话,因为命令记录太多会导致耗时很长。redis解决这个问题的手段就是AOF日志重写。


02

AOF重写介绍


在redis.conf文件中,有下面2个参数来控制AOF重写:

auto-aof-rewrite-percentage 100 #AOF文件大小较上次重写超过100%时进行重写
auto-aof-rewrite-min-size 64mb #aof文件大小超过64m时重写

下面我们执行6条命令:

192.168.59.146:6379> set name jinjnzhu
OK
192.168.59.146:6379> set password 123456
OK
192.168.59.146:6379> set name jinjunzhu1
OK
192.168.59.146:6379> set password 1234567
OK
192.168.59.146:6379> set name jinjunzhu2
OK
192.168.59.146:6379> set password 12345678
OK

之后我们查看name和password的值:

192.168.59.146:6379> get name
"jinjunzhu2"
192.168.59.146:6379> get password
"12345678"

这2个key的值被赋予了最新的一次赋值,虽然我们执行了6条命令,但是AOF重写后日志文件就剩了最后2条命令。


03

AOF重写对性能的影响


在上小节的介绍中,如果AOF文件较上次重写超过了100%,就要进行重写。但是如果日志特别大,AOF重写后把日志写回磁盘也是一个非常耗时的操作,那么AOF重写是否会阻塞主线程呢

  1. AOF重写并不是在主线程中,而是redis会fork一个bgrewriteaof子进程,这样就不会阻塞主线程执行了。
  2. fork子进程的过程是要在主线程中执行的,这时候主线程需要拷贝内存页表,这个页表记录了虚拟内存和物理内存的映射关系,如果内存很大,拷贝过程花费的时间就会很大,而这个拷贝过程中主线程是阻塞的。
  3. fork子进程完成后,主线程和bgrewriteaof子进程使用的是同一块儿内存空间,这时如果有新的写请求到来,并且写命令是已经存在的key,主线程会使用CopyOnWrite的方式,为这个key申请新的内存空间,进行写操作。如果这个key是一个bigkey,那也会耗时很多。


下面我画了一个简单的图,主线程fork出bgrewriteaof子进程时,复制了一个页表给子进程用,跟自己指向相同的内存空间。但是AOF重写过程中收到了foo这个key的写命令,这时主线程需要拷贝一份数据到新的内存空间进行修改。

微信图片_20221212160701.png

在AOF重写的过程中,如果有新的写命令到来了,会影响AOF重写吗

当然不会,新的写命令不仅会记录到AOF日志的缓存区,还会记录到重写的新AOF日志缓存区,这样当AOF重写结束后,把重新缓存区数据写到新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
相关文章
|
13天前
|
存储 缓存 NoSQL
Redis中的rdb和aof
本文深入探讨了Redis的持久化机制,包括RDB和AOF两种方式。详细解释了RDB的工作原理、优势和劣势,以及AOF的实现原理、配置选项、文件重写机制和三种数据同步方式,还介绍了AOF文件修复工具redis-check-aof的使用,并通过实例展示了如何开启和配置AOF持久化方式。
Redis中的rdb和aof
|
27天前
|
存储 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日志文件追加数据
|
11天前
|
存储 缓存 NoSQL
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
深入探究Redis的AOF持久化:保障数据安全与恢复性能的关键机制
25 0
|
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
【Azure Redis 缓存】Azure Reids是否可以开启慢日志(slowlog)和执行config指令
【Azure Redis 缓存】Azure Reids是否可以开启慢日志(slowlog)和执行config指令
|
5月前
|
NoSQL 关系型数据库 MySQL
Redis持久化机制 RDB 和 AOF 的选择
Redis持久化机制 RDB 和 AOF 的选择
85 0
|
5月前
|
存储 缓存 NoSQL
Redis之持久化(RDB和AOF)
Redis之持久化(RDB和AOF)
129 0
|
2月前
|
缓存 NoSQL Redis
redis数据持久化之RDB和AOF
redis数据持久化之RDB和AOF
|
4月前
|
存储 NoSQL Redis
《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化
《面试官之你说我听》:简明的图解Redis RDB持久化、AOF持久化