博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis存在大量脏页问题的追查记录
阅读量:5112 次
发布时间:2019-06-13

本文共 3486 字,大约阅读时间需要 11 分钟。

 

参见note:https://www.zybuluo.com/SailorXiao/note/136014

case现场

线上发现一台机器内存负载很重,top后发现一个redis进程占了大量的内存,TOP内容如下:

27190   root    20   0  18.6g   18g  600 S  0.3     59.2    926:17.83   redis-server

发现redis占了18.6G的物理内存。由于redis只是用于cache一些程序数据,觉得很不可思议,执行redis的info命令,发现实际数据占用只有112M,如下:

# Memory    used_memory:118140384    used_memory_human:112.67M  used_memory_rss:19903766528  used_memory_peak:17871578336  used_memory_peak_human:16.64G  used_memory_lua:31744  mem_fragmentation_ratio:168.48  mem_allocator:libc

于是用了pmap -x 27190 查看redis进程的内存映像信息,结果如下:

  27190:   ./redis-server ../redis.conf  Address             Kbytes      RSS     Dirty           Mode        Mapping  0000000000400000    548         184         0           r-x--       redis-server  0000000000689000    16          16          16          rw---       redis-server  000000000068d000    80          80          80          rw---       [ anon ]  0000000001eb6000    132         132         132         rw---       [ anon ]  0000000001ed7000    19436648    19435752    19435752    rw---       [ anon ]  00007f5862cb2000    4           0           0           -----       [ anon ]

发现存在大量的内存脏页。现在问题原因已经比较清晰了,是redis的脏页占用了大量的内存导致系统内存负载过高。那么为什么redis会存在那么多的脏页呢? 

case 分析

看了下linux脏页的定义:

脏页是linux内核中的概念,因为硬盘的读写速度远赶不上内存的速度,系统就把读写比较频繁的数据事先放到内存中,以提高读写速度,这就叫高速缓存,linux是以页作为高速缓存的单位,当进程修改了高速缓存里的数据时,该页就被内核标记为脏页,内核将会在合适的时间把脏页的数据写到磁盘中去,以保持高速缓存中的数据和磁盘中的数据是一致的。

也就是说,脏页是因为内存中的很多数据没来得及更新到磁盘导致的。看了下linux系统的脏页flush机制: 

 
发现跟内存flush的可以进行设置(/proc/sys/vm底下)

dirty_background_bytes/dirty_background_ratio:    - 当系统的脏页到达一定值(bytes或者比例)后,启动后台进程把脏页刷到磁盘中,此时不影响内存的读写(当bytes设置存在时,ratio是自动计算的)dirty_bytes/dirty_ratio:    - 当系统的脏页到达一定值(bytes或者比例)后,启动进程把脏页刷到磁盘中,此时内存的写可能会被阻塞(当bytes设置存在时,ratio是自动计算的)dirty_expire_centisecs:    - 当内存和磁盘中的数据不一致存在多久以后(单位为百分之一秒),才会被定义为dirty,并在下一次的flush中被清理。不一致以磁盘中文件的inode时间戳为准dirty_writeback_centisecs:    - 系统每隔一段时间,会把dirty flush到磁盘中(单位为百分之一秒)

查看当前系统的flush配置,发现没问题,dirty_background_ratio为10%,dirty_ratio为20%,dirty_writeback_centisecs为5s,dirty_expire_centisecs为30s,可是为啥redis的脏页没有被flush到磁盘中呢?

一般脏页是要把内存中的数据flush到磁盘中,那么会不会是redis的持久化导致了脏页呢?查看下redis关于这些方面的配置:

  rdb持久化已经被关闭   # save 900 1  # save 300 10  # save 60 10000  # append持久化也被关闭  appendonly no  # 最大内存设置、内存替换策略都是默认值  # maxmemory 
  # maxmemory-policy volatile-lru

如上所示,发现redis自身已经完全关闭持久化,只是作为cache使用,而且对于最大内存使用默认值(代表没有限制),内存的淘汰机制是volatile-lru。翻看redis的文档,查看对应的淘汰机制:

  volatile-lru:      从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰(默认值)  volatile-ttl:      从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰  volatile-random:   从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰  allkeys-lru:       从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰  allkeys-random:    从数据集(server.db[i].dict)中任意选择数据淘汰  no-enviction:      禁止驱逐数据

而在当前的使用环境中,程序对redis的使用是当做cache,并且会对数据设置expire超时时间,到期后等待redis进行删除的。那么脏页的原因,是不是因为过期数据清理机制的问题呢(比如清理不及时等)?因此,需要查看redis在对过期数据进行删除时采取的策略,参考信息如下: 

 

redis过期键删除机制:

惰性删除:    -  到期后,不会自动删除,只会在每次读取键时进行检查,检查该键是否已经过期,如果过期,则进行删除动作。这样可以保证删除操作只会在非做不可的情况下进行定期删除:    - 每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,籍此来减少删除操作对 CPU 时间的影响。 redis使用的是惰性删除 + 定期删除的策略

case 定位

通过以上的分析,问题已经比较明确了,原因如下:

  1. 由于某种原因,redis使用的内存越来越大(可能是由于惰性删除,导致expire的数据越积越多,或者其它原因,具体原因取决于redis内部的实现)
  2. redis由于只当做cache,并没有实际读写文件,因此操作系统并不会帮它flush到磁盘中(因为没有地方可以flush)
  3. 由于redis没有设置maxmemory,因此默认的是机器的内存大小,只有当redis自身使用的内存达到机器内存大小时,redis才会自身进行清理(volatile-lru机制)
  4. 因此当前的redis的内存越来越大,而且脏页数据越来越多(大部分可能都是已经过期的数据)

case解决

为了解决这个问题,比较方便且合理的方法就是:

  • 合理设置redis的maxmemory大小,用于让redis实现自身的数据清理
 
 

转载于:https://www.cnblogs.com/williamjie/p/9373318.html

你可能感兴趣的文章
大家在做.NET B/S项目的时候多用什么设技术啊?
查看>>
Java SE和Java EE应用的性能调优
查看>>
Android设计模式系列--原型模式
查看>>
免费的论文查重网站
查看>>
C语言程序第一次作业
查看>>
leetcode-Sort List
查看>>
phpcms
查看>>
中文词频统计
查看>>
[.net 面向对象编程基础] (19) LINQ基础
查看>>
Win10 虚拟桌面
查看>>
了解node.js
查看>>
想做移动开发,先看看别人怎么做
查看>>
Dynamics CRM 2013 初体验(1):系统的安装
查看>>
Ping其他电脑ping不通的解决方法
查看>>
Eclipse相关集锦
查看>>
虚拟化架构中小型机构通用虚拟化架构
查看>>
继承条款effecitve c++ 条款41-45
查看>>
[置顶] OGG-01091 Unable to open file (error 89, Invalid file system control data detected)
查看>>
linux 内核参数VM调优 之 参数调节和场景分析
查看>>
HTML+CSS学习笔记(九)
查看>>