AOF重写导致的Redis进程被kill
Redis环境描述
- 服务器: 阿里云16GB服务器
- Redis版本: 5.0.5
- 持久化方式: AOF
问题描述
阿里云环境,使用docker安装的单节点redis5.x,频繁出现redis进程被操作系统kill,直到redis容器直接启动失败,查找/var/log/messages文件,可以看到以下内容:

谷歌了一下total-vm和anon-rss,没看太明白什么意思,服务器物理内存是16GB,姑且认为total-vm是物理内存,anon-rss就是redis进程占用的内存量了,这么看应该是redis占用内存过高导致的进程被杀;
问题查找
查看redis持久化文件appendonly.aof存储目录,如下所示:

从上图可以看到当前目录存在很多temp-rewriteaof-xxx.aof,这是aof文件重写时产生的临时文件,xxx表示重写时fork的子进程的进程号,这里存在这么多的临时文件表示redis已经进行了很多次重写,但是因为内存不足导致子进程被kill掉。查看阿里云的监控信息,发现确实存在内存飙升的情况:

正常来说子进程被kill掉,不应该影响redis容器,但是现在的情况是redis容器直接不可用了,需要重启docker服务才可以,这个应该跟docker的进程管理有关,不做深究,现在基本可以定位导致问题的原因是redis发生aof重写时由于内存不足导致子进程被kill掉,从而导致redis服务不可用。
aof重写原理
这个要从AOF文件重写的过程来说,AOF是Redis的一种持久化方式,在客户端执行写入命令时,Redis会将命令缓存在AOF缓冲区中,再根据同步策略(三种:always、everysec、no)将命令同步到appendonly.aof文件中,随着aof文件越来越大,达到配置文件中auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数配置的阈值时,redis将触发aof重写,此时会fork一个子进程进行aof重写,在aof重写过程中客户端新的写入命令会暂存于aof重写缓冲区中,直到子进程重写完成后,将aof重写缓冲区中的内容再追加到新的aof文件中,最后使用新的aof文件替换旧的aof文件。
基于以上aof重写原理可以知道,如果在子进程重写过程中,系统的写入量很大,那么aof重写缓冲区占用的内存就会越来越大,从而导致内存占用量持续上升。
问题处理
修改redis配置文件中auto-aof-rewrite-percentage参数值为800,表示当当前的aof文件大小是上次重写后aof文件大小的8倍时才触发重写。
然后将redis重启,经过漫长的数据加载之后,通过redis客户端工具可以看到,redis中数据已经超过13GB,服务器的屋里内存是16GB,按理说fork子进程进行重写时使用的是copy_on_write,每10GB内存只需要20MB左右的内存页表,还剩下3GB的内存可用,即使aof复制缓冲区zai在持续增大也不至于直接将redis给kill掉,这个牵扯到操作系统另外一个参数的配置,如下所示:

这个牵扯到linux内存分配的问题,不做深究,根据提示就是需要将vm.overcommit_memory这个参数由0改为1,表示内核允许超量使用内存直到用完为止,设置命令如下:
$ echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
$ sysctl vm.overcommit_memory=1
redis启动时另外一个警告,如下:

这个是redis内核默认开启了THP特性,支持大内存页分配,当开启时可以降低fork子进程的速度,但fork操作之后,每个内存页由4k变成了2M,这个会大幅度增加重写期间主进程内存的消耗,同时每次写命令引起的复制内存页单位放大了512倍,会拖慢写操作的执行时间,导致大量的写操作慢查询,因此redis建议关闭该特性。
禁用命令:
$ echo never > /sys/kernel/mm/transparent_hugepage/enabled
以上两个参数修改完成以后还需要修改redis的最大内存,建议单个redis最大内存在10GB以内,但是目前redis的内存占用已经达到了13GB,因此将该redis迁移到另外一台内存为32GB的服务器上,因为还要进行其他操作暂未设置最大内存,如果考虑集群的话最好单个redis内存不超过10GB,不搭建集群的话需要设置redis的最大内存,建议保留20%-30%的空闲物理内存。
本次问题先使用临时的解决方案进行处理,后续优化缓存内容以及扩展机器以后再进行整体的优化配置。
参考内容
AOF重写导致的Redis进程被kill的更多相关文章
- 优化 | Redis AOF重写导致的内存问题 不错
一.问题说明 业务上接到报警提示服务器内存爆了,登录查看发现机器剩余内存还很多,怀疑是被OOM了,查看/var/log/messages: kernel: [25918282.632003] Out ...
- Redis之AOF重写及其实现原理
Reference: https://blog.csdn.net/hezhiqiang1314/article/details/69396887 AOF 重写AOF 持久化是通过保存被执行的写命令来记 ...
- Reids 持久化AOF 重写实现原理
AOF重写 AOF重写并不需要对原有AOF文件进行任何的读取,写入,分析等操作,这个功能是通过读取服务器当前的数据库状态来实现的.(auto-aof-rewrite-percentage和auto-a ...
- Golang 实现 Redis(4): AOF 持久化与AOF重写
本文是使用 golang 实现 redis 系列的第四篇文章,将介绍如何使用 golang 实现 Append Only File 持久化及 AOF 文件重写. 本文完整源代码在作者GithubHDT ...
- Linux下禁止使用swap及防止OOM机制导致进程被kill掉
首先解释两个概念: swap:在linux里面,当物理内存不够用了,而又有新的程序请求分配内存,那么linux就会选择将其他程序暂时不用的数据交换到物理磁盘上(swap out),等程序要用的时候再读 ...
- [转]Linux下防止进程使用swap及防止OOM机制导致进程被kill掉
首先解释两个概念:swap:在linux里面,当物理内存不够用了,而又有新的程序请求分配内存,那么linux就会选择将其他程序暂时不用的数据交换到物理磁盘上(swap out),等程序要用的时候再读进 ...
- [翻译自官方]什么是RDB和AOF? 一文了解Redis持久化!
概述 本文提供Redis持久化技术说明, 建议所有Redis用户阅读. 如果您想更深入了解Redis持久性原理机制和底层持久性保证, 请参考文章 揭秘Redis持久化: http://antire ...
- redis3.2 aof重写
redis关闭aof,缩容,redis实例一直在重写. 原因也是redis3.2的bug,aof重写是没有判断aof是否开启. redis缩容后改变的是redis重写的min_size,缩容之前,实例 ...
- Redis Cluster 强制kill某一个节点和shutdown某一个节点后修复过程
redis cluster 命令行,执行以下命令需登录cluster,是集群所独有的集群(cluster)CLUSTER INFO 打印集群的信息CLUSTER NODES 列出集群当前已知的所有节点 ...
随机推荐
- 7.12-7.19 id、w、who、last、lastb、lastlog
7.12-7.19 id.w.who.last.lastb.lastlog 目录 7.12 id:显示用户与用户组的信息 7.13 w:显示已登录用户信息 7.14 who:显示已登录用户信息 显示最 ...
- Linux 目录管理
tree命令的基本使用 tree 查看当前目录的树状结构 -a 查看所有包含隐藏文件 -L 1 查看目录层级 tree /root 指定目录 根目录下的主要文件 /bin 普通用户可以执行的二进制文件 ...
- C语言函数sscanf()的用法-(转自Walter L)
在我的学习过程中,从文件读取数据是一件很麻烦的事,所幸有sscanf()函数. C语言函数sscanf()的用法sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int ss ...
- 10.7 netstat:查看网络状态
netstat命令 用于显示本机网络的连接状态.运行端口和路由表等信息. netstat命令的参数选项及说明 -r 显示路由表信息,该功能类似于前面学过的route 和ip route-g 显示多播功 ...
- easyui datagrid 自定义单元格单击与双击事件(Day_38)
$(function(){ $('#tableId').datagrid({//单击事件 onClickRow:function(rowIndex,rowData){ alert("单 ...
- JavaScript正则表达式(深度)(Day_14)
忘不掉的是回忆,继续的是生活,错过的,就当是路过. 简介 正则表达式是用于匹配字符串中字符组合的模式.在 JavaScript中,正则表达式也是对象. 这些模式被用于 RegExp 的 exec 和 ...
- kubernetes技能图谱
深入剖析Kubernetes-张磊(Kubernetes社区资深成员与项目维护者) Kubernetes集群搭建 ver1.20.5
- idea-创建web.xml模板
web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="htt ...
- Python+Selenium - windows安全中心的弹窗(账号登录)
当出现如下图所示的 Windows安全中心弹窗,需要输入用户名和密码时 如何用Python+selenium跳过这个登录. 步骤: 1.在注册表中三个位置各添加两个东西:iexplore.exe 和 ...
- 重新整理 .net core 实践篇—————日志系统之战地记者[十五]
前言 本节开始整理日志相关的东西.先整理一下日志的基本原理. 正文 首先介绍一下包: Microsoft.Extengsion.Logging.Abstrations 这个是接口包. Microsof ...