AOFRW存在的问题是什么?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
1.内存开销
在AOFRW期间,主进程会将fork之后的数据变化写进aof_rewrite_buf中,aof_rewrite_buf和aof_buf中的内容绝大部分都是重复的,因此这将带来额外的内存冗余开销。在Redis INFO中的aof_rewrite_buffer_length字段可以看到当前时刻aof_rewrite_buf占用的内存大小。如下面显示的,在高写入流量下aof_rewrite_buffer_length几乎和aof_buffer_length占用了同样大的内存空间,几乎浪费了一倍的内存。当aof_rewrite_buf占用的内存大小超过一定阈值时,我们将在Redis日志中看到如下信息。可以看到,aof_rewrite_buf占用了100MB的内存空间且主进程和子进程之间传输了2135MB的数据(子进程在通过pipe读取这些数据时也会有内部读buffer的内存开销)。对于内存型数据库Redis而言,这是一笔不小的开销。AOFRW带来的内存开销有可能导致Redis内存突然达到maxmemory限制,从而影响正常命令的写入,甚至会触发操作系统限制被OOM Killer杀死,导致Redis不可服务。2.CPU开销
CPU的开销主要有三个地方,分别解释如下:
1)在AOFRW期间,主进程需要花费CPU时间向aof_rewrite_buf写数据,并使用eventloop事件循环向子进程发送aof_rewrite_buf中的数据; 2)在子进程执行重写操作的后期,会循环读取pipe中主进程发送来的增量数据,然后追加写入到临时AOF文件;3)在子进程完成重写操作后,主进程会在backgroundRewriteDoneHandler 中进行收尾工作。其中一个任务就是将在重写期间aof_rewrite_buf中没有消费完成的数据写入临时AOF文件。如果aof_rewrite_buf中遗留的数据很多,这里也将消耗CPU时间。AOFRW带来的CPU开销可能会造成Redis在执行命令时出现RT上的抖动,甚至造成客户端超时的问题。
3.磁盘IO开销
如前文所述,在AOFRW期间,主进程除了会将执行过的写命令写到aof_buf之外,还会写一份到aof_rewrite_buf中。aof_buf中的数据最终会被写入到当前使用的旧AOF文件中,产生磁盘IO。同时,aof_rewrite_buf中的数据也会被写入重写生成的新AOF文件中,产生磁盘IO。因此,同一份数据会产生两次磁盘IO。
4.代码复杂度
Redis使用下面所示的六个pipe进行主进程和子进程之间的数据传输和控制交互,这使得整个AOFRW逻辑变得更为复杂和难以理解。以上内容摘自《阿里开发者手册-Redis专题》电子书,点击https://developer.aliyun.com/ebook/download/7770可下载完整版