Redis环境描述

  • 服务器: 阿里云16GB服务器
  • Redis版本: 5.0.5
  • 持久化方式: AOF

问题描述

阿里云环境,使用docker安装的单节点redis5.x,频繁出现redis进程被操作系统kill,直到redis容器直接启动失败,查找/var/log/messages文件,可以看到以下内容:

谷歌了一下total-vmanon-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-sizeauto-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%的空闲物理内存。

本次问题先使用临时的解决方案进行处理,后续优化缓存内容以及扩展机器以后再进行整体的优化配置。

参考内容

1.Redis开发与运维

AOF重写导致的Redis进程被kill的更多相关文章

  1. 优化 | Redis AOF重写导致的内存问题 不错

    一.问题说明 业务上接到报警提示服务器内存爆了,登录查看发现机器剩余内存还很多,怀疑是被OOM了,查看/var/log/messages: kernel: [25918282.632003] Out ...

  2. Redis之AOF重写及其实现原理

    Reference: https://blog.csdn.net/hezhiqiang1314/article/details/69396887 AOF 重写AOF 持久化是通过保存被执行的写命令来记 ...

  3. Reids 持久化AOF 重写实现原理

    AOF重写 AOF重写并不需要对原有AOF文件进行任何的读取,写入,分析等操作,这个功能是通过读取服务器当前的数据库状态来实现的.(auto-aof-rewrite-percentage和auto-a ...

  4. Golang 实现 Redis(4): AOF 持久化与AOF重写

    本文是使用 golang 实现 redis 系列的第四篇文章,将介绍如何使用 golang 实现 Append Only File 持久化及 AOF 文件重写. 本文完整源代码在作者GithubHDT ...

  5. Linux下禁止使用swap及防止OOM机制导致进程被kill掉

    首先解释两个概念: swap:在linux里面,当物理内存不够用了,而又有新的程序请求分配内存,那么linux就会选择将其他程序暂时不用的数据交换到物理磁盘上(swap out),等程序要用的时候再读 ...

  6. [转]Linux下防止进程使用swap及防止OOM机制导致进程被kill掉

    首先解释两个概念:swap:在linux里面,当物理内存不够用了,而又有新的程序请求分配内存,那么linux就会选择将其他程序暂时不用的数据交换到物理磁盘上(swap out),等程序要用的时候再读进 ...

  7. [翻译自官方]什么是RDB和AOF? 一文了解Redis持久化!

    ​概述 本文提供Redis持久化技术说明,  建议所有Redis用户阅读. 如果您想更深入了解Redis持久性原理机制和底层持久性保证, 请参考文章 揭秘Redis持久化: http://antire ...

  8. redis3.2 aof重写

    redis关闭aof,缩容,redis实例一直在重写. 原因也是redis3.2的bug,aof重写是没有判断aof是否开启. redis缩容后改变的是redis重写的min_size,缩容之前,实例 ...

  9. Redis Cluster 强制kill某一个节点和shutdown某一个节点后修复过程

    redis cluster 命令行,执行以下命令需登录cluster,是集群所独有的集群(cluster)CLUSTER INFO 打印集群的信息CLUSTER NODES 列出集群当前已知的所有节点 ...

随机推荐

  1. Linux用户登录查看命令总结 - w,who,last,lastlog

    Linux用户登录查看命令总结 - w,who,last,lastlog linux shell 747 次阅读  ·  读完需要 15 分钟 0 1. 查看登录用户信息 who -H 命令输出 NA ...

  2. BUUCTF(八)[极客大挑战 2019]LoveSQL

    BUUCTF 1.打开题目 注入方法可参考NewsCenter 2.测试注入点 username: 1'or'1=1 password: 1'or'1=1 登录成功,说明存在注入漏洞. 下面测试位点个 ...

  3. 008.Python循环for循环

    for 循环 特指用于遍历容器类型数据,(遍历 循环 迭代 都是一个意思)就是把所有的数据一个一个拿出来的过程, while循环有局限性,不能遍历无序容器数据 setvar = {"a&qu ...

  4. IDEA 打包和导入 Jar 包

    Jar 包介绍 Jar 包 ( Java Archive,Java 归档文件) 是与平台无关的压缩文件格式,它允许将多个 Java 源文件编译生成的 class 文件(即字节码文件)打包成一个压缩文件 ...

  5. HDFS 05 - HDFS 的元数据管理(FSImage、EditLog、Checkpoint)

    目录 1 - NameNode 的启动流程 2 - NameNode 的元数据 2.1 EditLog 操作日志 2.2 查看 EditLog 文件 2.3 FSImage 元数据镜像 2.4 查看 ...

  6. GO学习-(30) Go语言操作kafka

    go操作kafka Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据,具有高性能.持久化.多副本备份.横向扩展等特点.本文介绍了如何使用Go语言发送和接收 ...

  7. nginx 重定向到系统维护页面

    上周末兄弟项目准备扩展服务器以便提供更好的服务,兄弟项目有一些功能是实时提供到我这边的,需要我这边暂时把对应系统功能屏蔽,因为使用nginx,所以可以直接配置nginx重定向到固定系统维护页面. ng ...

  8. AIFramework基本概念整理

    AIFramework基本概念整理 本文介绍: 对天元 MegEngine 框架中的 Tensor, Operator, GradManager 等基本概念有一定的了解: 对深度学习中的前向传播.反向 ...

  9. oracle单机开机自启动

    ====================== 单机数据库开机自启动  ============================= 环境: oracle数据库单机 版本:11.2.0.4 1.修改配置文 ...

  10. 狂神说redis笔记(一)

    一.Nosql概述 1.单机Mysql时代 90年代,一个网站的访问量一般不会太大,单个数据库完全够用.随着用户增多,网站出现以下问题: 数据量增加到一定程度,单机数据库就放不下了 数据的索引(B+ ...