在线上某个redis的运行日志中,看到很多aof rewrite相关的日志。

我们知道redis进行AOF Rewrite的主要目的是解决AOF文件过大的问题,因为当AOF文件过大时,可能会影响Redis的性能和加载时间。通过AOF Rewrite,可以生成一个更紧凑的AOF文件,减少磁盘空间的使用,并且在加载时更快地恢复数据库状态。
但是AOF Rewrite是一个相对较耗费IO和CPU资源的操作,而且aof rewrite时需要进行fork进程的操作,可能导致出现redis主线程的阻塞以及OOM的问题,因此在进行AOF Rewrite时,Redis服务器的性能会受到一定的影响。所以我们其实并不希望redis频繁地进行aof rewirte操作。
aof rewrite 为什么会造成OOM?我们知道在redis进行aof rewrite时,会先fork一个子进程出来,底层利用了Copy On Write(写时复制)的机制。这意味着,当主进程中的数据需要修改,redis不会直接在现有内存中修改数据,而是先将这块内存拷贝出来,再修改这块新内存的数据,假设这个时候服务写qps很高,那么这个时候就会导致redis需要申请大量的内存用于修改数据,如果机器预留内存资源不足,就可能导致OOM。
所以线上这个redis频繁地进行aof rewrite的原因是什么?
要弄清楚问题的原因,我们就需要知道redis中aof rewrite的触发机制。
aof rewite的触发机制
手动触发:可以使用Redis提供的BGREWRITEAOF命令来手动触发AOF Rewrite过程。执行该命令后,Redis会在后台启动AOF Rewrite过程。
自动触发:当满足一定的条件时,Redis会自动触发AOF Rewrite。条件通常是根据AOF文件的大小和AOF文件增长的比例来判断。
与自动触发相关的参数有两个:
auto-aof-rewrite-min-size:如果AOF文件大小小于此值,则不会触发AOF重写。默认值为64mb。避免了达到约定百分比但文件大小仍然很小的情况还要重写。 auto-aof-rewrite-percentage:Redis会在最后一次AOF重写操作后记住AOF文件的大小。如果当前AOF文件大小增加了这个百分比值,将触发另一次AOF重写。将此值设置为0,将禁用自动AOF重写。缺省值是100,假设上次AOF重写后的文件大小是100MB,而auto-aof-rewrite-percentage 设置为100,则意味着当AOF文件增长到200MB及以上时,Redis会启动一次新的AOF重写。
再回过头看这个实例的监控,如下图所示,这个实例的入流量速率约为1.3MB/s,文件大小约为1.3G。


那么aof文件增长一倍大概需要1.3*1024/1.3/60 =17分钟,跟下图实例的运行日志中的aof rewrite间隔时间接近,所以运行日志中存在大量aof rewrite记录的原因找到了,也是如日志所写的:Starting automatic rewriting of AOF on 100% growth(aof 达到100%增长值,自动触发了aof auto rewrite。)

为了避免频繁地aof rewrite对生产环境造成负面影响,我们可以通过调大auto-aof-rewrite-percentage来减少aof rewrite的触发频率。
参考:https://cloud.tencent.com/developer/article/1928590
https://blog.51cto.com/u_14731/6674243

点个“赞 or 在看” 你最好看!

👇👇👇 谢谢各位老板啦!!!




