Redis AOF重写导致的内存问题

一、问题说明

业务上接到报警提示服务器内存爆了,登录查看发现机器剩余内存还很多,怀疑是被OOM了,查看/var/log/messages:

kernel: [25918282.632003] Out of memory: Kill process 18665 (redis-server) score 919 or sacrifice child
kernel: [25918282.637201] Killed process 18665 (redis-server) total-vm:17749556kB, anon-rss:14373204kB, file-rss:1236kB
kernel: [25918791.441427] redis-server invoked oom-killer: gfp_mask=0x24280ca, order=0, oom_score_adj=0

发现redis-server被oom kill了,但是登录查看发现redis-server并没有down掉.

二、问题排查

既然redis-server并没有被kill,那被kill的有可能是redis的子进程。

进入redis的data目录查看:

-rw-rw-r-- 1 myuser myuser 18044223152 4月   8 12:01 appendonly.aof
-rw-rw-r-- 1 myuser myuser  3603981186 4月   8 12:01 temp-rewriteaof-25595.aof
-rw-rw-r-- 1 myuser myuser  4083774382 4月   8 11:46 temp-rewriteaof-18665.aof
-rw-rw-r-- 1 myuser myuser  4326578230 4月   8 11:21 temp-rewriteaof-8116.aof

发现有好几个temp-rewriteaof文件,这是redis在进行aofrewrite时产生的临时文件。

注意看其中一个的名字:temp-rewriteaof-18665.aof ,后面的18665即rewrite子进程的pid,上面被oom kill的进程ID也是18665,说明是redis的aofrewrite子进程被kill了。

而多个temp文件,而且时间都是最近的,说明redis已经尝试了多次rewrite,都因为内存不足被中途kill。

查看监控发现,近期确实多次出现了内存突增的情况:

redis_memory

为什么aof重写会导致内存爆涨?这要从它的原理说起。

AOF 是redis的一种持久化方式,用来记录所有的写操作,但是随着时间增加,aof文件会越来越大,所以需要进行重写,将内存中的数据重新以命令的方式写入aof文件。
在重写的过程中,由于redis还会有新的写入,为了避免数据丢失,会开辟一块内存用于存放重写期间产生的写入操作,等到重写完毕后会将这块内存中的操作再追加到aof文件中。

从原理中可以了解到,如果在重写过程中redis的写入很频繁或写入量很大,就会导致占用大量额外的内存来缓存写操作,导致内存爆涨。

查看redis的访问情况:

redis_ops

从监控中可以看到,redis实际的访问OPS并不高,那么剩下的可能性就只有写入量了。

登录Redis使用monitor监控了一段时间的访问,记录到文件中:

[myuser@redis-00 ~]$ time redis-cli -p 6379 monitor > monitor.log
^C

real	0m24.219s
user	0m0.552s
sys	    0m0.036s

通过查看monitor.log发现,存在这样一条语句:

1523351418.461744 [0 10.10.10.10:6379] "SET" "xx_xx_id_17791" 
"[615249,615316,615488,616246,616498,616580,617117,617291,617510,617879,
618052,618377,618416,619010,619185,619603,619816,620190,620230,620387,
620445,620524,621012,621214,621219,621589,621596,621616,621623,621669,
621670,621682,621683,621820,621994,622168,622207,622245,622384,622442,
622450,622608,622644,622654,622658,622704,622784,622785,622786,622810,
622834,622876,622887,622934,622936,622937,622939,622943,622967,......]"
  • 为了看起来方便,我做了换行处理,并且省略了大部分的key内容,但实际上该set命令的内容一直拉不到头。

过滤该key进行分析:

# monitor.log 大小
[myuser@redis-00 ~]$ du -sh monitor.log
62M    monitor.log
[myuser@redis-00 ~]$ wc -l monitor.log
12114    monitor.log

[myuser@redis-00 ~]$ grep 'xx_xx_id_17791' monitor.log | grep -v 'GET' > xx_xx_id_17791.log

# xx_xx_id_17791 key 大小
[myuser@redis-00 ~]$ du -sh xx_xx_id_17791.log
61M    xx_xx_id_17791.log
[myuser@redis-00 ~]$ wc -l xx_xx_id_17791.log
17    xx_xx_id_17791.log

62M的monitor文件,17行 xx_xx_id_17791 的set命令一共占了61M,很明显就是这个key搞的鬼了,去找开发确认,果然是程序出了问题。

三、处理结果

1. 临时处理

在接到报警时是在夜间,而aof rewrite一直失败,因此做了临时处理:

127.0.0.1:6379> config get auto-aof-rewrite-percentage
1) "auto-aof-rewrite-percentage"
2) "200"
127.0.0.1:6379> config set auto-aof-rewrite-percentage 800
OK

auto-aof-rewrite-percentage 是设置aof rewrite触发时机的一个参数,当当前的aof文件大小超过上一次rewrite后aof文件的百分比后触发rewrite。

200 改为 800 ,即当前的aof文件超过上一次重写后aof文件的8倍时才会再次rewrite,这样可以保证短期内不会再次进行重写操作。

2. 问题解决

找开发进行确认后,将该key进行了删除,开发也说已经修改了程序,auto-aof-rewrite-percentage重新改为200。

结果只是消停了一阵子,不久后又出现一个类似的超大key,还是半夜报的警😒。

又找开发再次修改才真的算是改好了,和开发确认了下业务场景,发现该redis现在当做纯缓存来用了,不需要数据持久化,于是果断关掉AOF。

关闭aof持久化:

redis-03:6379> config get appendonly
1) "appendonly"
2) "yes"
redis-03:6379> config set appendonly no
OK

问题解决,万事大吉。

四、后记

这个问题导致了多次的夜间报警,弄的心里还是比较烦躁的,但是针对线上暴露的一些问题还是要和开发详细沟通,一方面对于问题的原因、相关原理要尽可能的给开发讲清楚,而不是只要解决问题就万事大吉,这样可以避免类似的问题重复发生;另一方面,对于运维人员而言也要充分了解相关的业务场景才行。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redis AOF重写是一种机制,用于解决AOF文件过大导致IO性能问题的情况。AOF重写的过程并不需要对原有AOF文件进行读取、写入或分析操作,而是通过读取服务器当前的数据库状态来实现的。\[3\]AOF重写的执行流程包括命令追加、文件写入和文件同步以及文件重写。首先,Redis的写命令被追加到缓冲区aof_buf中。然后,根据不同的同步策略,将aof_buf中的内容同步到硬盘,以确保数据的持久化。最后,定期进行AOF文件的重写,以达到压缩AOF文件的目的。\[3\]通过AOF重写,可以有效地减小AOF文件的大小,提高IO性能,同时保证数据的持久化。 #### 引用[.reference_title] - *1* *3* [缓存数据库REDIS之二:AOF重写原理](https://blog.csdn.net/qq_18343913/article/details/119343547)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [redisaof重写机制](https://blog.csdn.net/qq_63431773/article/details/131691454)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值