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. ELK日志收集分析平台部署使用

    一.ELK介绍 开源实时日志分析ELK平台能够完美的解决我们上述的问题,ELK由ElasticSearch.Logstash和Kiabana三个开源工具组成: 1.ElasticSearch是一个基于 ...

  2. vim 编辑器高级用法

    vim编辑器介绍 如果没有安装vim使用下面方式安装 yum -y install vim vi与vim的不同 两者最大的不同:vim可以高亮显示,vi不可以. vim三种工作模式 普通模式 # 光标 ...

  3. zabbix企业级的分布式开源监控解决方案 v5.0 LTS

    目录 zabbix简介 服务模块 客户端守护进程 监控流程 功能拆解 安装 zabbix 5.0 LTS 参考官网 zabbix 5.0.12-1.el7 zabbix-server相关优化 1. 字 ...

  4. GO学习-(8) Go语言基础之数组

    Go语言基础之数组 Array(数组) 数组是同一种数据类型元素的集合. 在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小不可变化. 基本语法: // 定义一个长度为3元素类型为 ...

  5. Python+Selenium学习笔记14 - python官网的tutorial - just() fill() format()

    repr(x).rjust(n)  左侧空格填充,右侧列对齐,str()和repr()是一种输出,也可不用,直接x.rjust() repr(x).ljust(n)  右侧空格填充,左侧列对齐 rep ...

  6. CVD-ALD前驱体材料

    CVD-ALD前驱体材料 ALD前驱体源瓶特点是什么   ALD前驱体源瓶(起泡器)用于固态.液态及气态超纯物料类的封装,涉及微正压.常压.中低压的危险化学品,对源瓶的安全性和洁净度提出严苛的要求. ...

  7. Docker App应用

    Docker App应用 这是一个实验特性. 实验性功能提供了对未来产品功能的早期访问.这些特性仅用于测试和反馈,因为它们可能在没有警告的情况下在不同版本之间更改,或者可以从将来的版本中完全删除.在生 ...

  8. 单点突破:MySQL之基础

    前言 开发环境:MySQL5.7.31 本文并不是mysql语法语句的教程或者笔记,如果初学MySQL,想要看sql的教程或者学习各种语法语句规范,可以看看一千行MySQL学习笔记或者MySQL教程| ...

  9. 02:HTML

    HTML介绍 Web服务本质 import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen(5 ...

  10. Echarts的使用教程

    项目中需要使用图表,最初使用的.NET自带的MSChart控件,做出来的效果不太好,所以又使用了Echarts控件. MSChart源码放在最后,可自行下载查看. Echarts是一个基于 JavaS ...