美文网首页架构与管理
redis rehash造成的内存增长

redis rehash造成的内存增长

作者: 白馨_1114 | 来源:发表于2020-05-09 18:25 被阅读0次

一、故障问题

运维的同学反应:某个业务的redis使用总量内存增长了大约20g,但是业务访问量却没有显著增长。

仔细排查过,一直没有没有查到原因。这部分突增的内存开销是由什么造成的,消耗在哪里?

内存增长如下图:
image.png

日志中没有异常信息。但是观测到,cow耗费内存同时增长。

实例redis_cluster_feed_d2_0_39200异常日志:
image.png

二、问题排查过程

为了排查问题方便,选取redis_cluster_feed_d2_0_39200实例作为排查对象。

1. 排查这部分开销是内核系统行为,还是redis主动行为。这部分主要通过used_memory来确定。

    监控显示同时段used_memory增长了2g,确定是redis的主动行为。
image.png

2. 排查这部分开销是用在kv上,还是其他开销上。

    观测到前后时段落磁盘rdb大小几乎没变化,而且dba之前也做过rdb key分析,都显示key的数量、类型、大小都无显著变化。

    说明没有bigkey,也没有大量写入。

    建议dba将前后两个时间段的rdb重新加载,以确认是否是kv存储造成的其他开销。交给dba确认。(这个做了,就可以直接确认rehash问题,不需要继续后面的排查)。

3. 跟2同步排查这部分开销是否是业务访问造成。这部分主要通过instantaneous_input_kbps,qps, bigkey来查看。

    大流量和bigkey都容易造成内存爆涨(但一般爆涨之后,这部分内存都会及时归还,其实不会出现只归还一部分内存的情况)。

    监控显示同时段qps大约600左右,instantaneous_input_kbps大约30上下,非常小。且dba反应,这是一个写少读多的业务。排除业务访问造成的影响。
image.png
image.png
  1. 经过以上排查,基本可以确认这是由于redis为了维护自己的数据库主动发起的。

      比如常见的清理过期键,清理超时客户端,给slave发送ping,rehash等等。其中rehash非常容易造成内存爆涨(网上文章很多)。
    
    1. 排查是否由rehash造成该问题, 网上测试显示:

      (a) 当num(keys)=215=32768,从下面可以看出到key的个数为32769时,内存涨了一些,但是还不明显。


      image.png

      (b) 当num(keys)=220=1048576,从下面可以看出到key的个数为1048577时,内存涨了32M。

      因为rehash会扩容,所以新的哈希表中的槽位变为了221 * 2(因为每个key都设置了过期时间,expires表),指针为8个字节,221 ️ 2 ️ 8 = 225 = 32MB


      image.png

      (c) 当num(keys)=226=67108864,从下面可以看出到key的个数为67108865时,内存涨了2GB。
      因为rehash会扩容,所以新的哈希表中的槽位变为了227 * 2(因为每个key都设置了过期时间,expires表),指针为8个字节,227 ️ 2 ️ 8 = 231 = 2GB


      image.png
      Redis过期键存储:

      命令:expire key seconds
      存储时未过期:往expire库中添加/或者替换一条expires[key]:timeout数据
      此时数据库中存在两条关于这条key的信息:
      dict------dict[key]:value
      expires--expires[key]:timeout

      所以是有两个字典的,也就是说没有过期键时,当key到达 134217730=67108864*2时,由于rehash的原因会增长2g。

      当时我们线上实例的num(keys)=134372150略微大于134217730,也是符合这个情况的。整个增长过程如下图:


      image.png

三、结论

1. 内存增长原因:当key到达 134217730=67108864*2时,由于rehash的原因会增长2g。

2. 归还1g原因:rehash完成后,会释放ht[0]。

3. cow增长原因:rehash过程会更改数据数据指针。造成大部分数据虽未被访问,但是却发生改变,进而导致大范围的缺页异常。

相关文章

  • redis rehash造成的内存增长

    一、故障问题 日志中没有异常信息。但是观测到,cow耗费内存同时增长。 二、问题排查过程 2. 排查这部分开销是用...

  • 转载:探寻 Redis 内存诡异增长的元凶

    转载:探寻 Redis 内存诡异增长的元凶 记一次 Redis 内存诡异增长,由于 一次RedisRehash 造...

  • 从零手写缓存框架(14)redis渐进式rehash详解

    redis 的 rehash 设计 本文思维导图如下: HashMap 的 rehash 回顾 读过 HashMa...

  • 思考题

    1.java hashMap和redis map的rehash有什么区别? Java hashMap rehash...

  • redis存储分析

    一、内存 1、几个关键的数据结构 2、rehash 1)rehash标志 #define dictIsRehash...

  • Redis:rehash

    Redis解决键冲突:使用的是链地址法 随着操作的不断执行, 哈希表保存的键值对会逐渐地增多或者减少, 为了让哈希...

  • redis rehash

    Add 如果不在rehash,加在0表如果在rehash,加到1表上 Delete 先删0表。如果在rehash,...

  • Redis rehash

    rehash分扩容和缩容,两个过程互斥 交替使用h0和h1,来回搬迁,类似jvm的s1和s2 dict结构中的re...

  • Redis笔记

    Redis核心技术与实战 rehash·装载因子(entry个数 除以 hash桶个数) 渐进式rehash·每处...

  • redis笔记

    数据结构 SDS 字典 index确定 渐进式rehash 为了缓解一次性rehash带来的性能问题,redis提...

网友评论

    本文标题:redis rehash造成的内存增长

    本文链接:https://www.haomeiwen.com/subject/rvklnhtx.html