Permalink: 2014-06-24 10:19:32 by ning in redis tags: all

1   现象

redis 内存居高不下

我们上线了一个新的业务后, 单实例内存从4G彪到6G左右, 凌晨低峰期大约5G. 调整cache时间, 由4h改为2h, 未见内存下降.

怀疑是key已经过期, 但是并未淘汰. 通过把线上aof重放到线下看, 线上有19M个key, 线下只有12M个key, 说明存在很多脏key(过期但是未淘汰)

修改配置 HZ=100 , 加速淘汰, 内存开始下降, 从5.5G下降到3.5G.

2   cen-li的分析

至于hz应该设什么值, 可以参考 cen-li的分析: http://cen-li.github.io/redis-expire.html

总结下来:

  1. key的淘汰有三个时机:
    • 主动(cron定时执行)
      • 每秒执行HZ次(理想情况), 每次执行一个固定时间片: 1s/HZ/4
    • 被动
      • 写操作时, 发现内存超过maxmemory, 此时淘汰n个key, 直到内存降到配置maxmemory以下.
      • 读操作时, 发现当前读取的key已经过期, 则淘汰掉.
  2. 内存不满的集群, 主要受到cron淘汰机制的制约, 此时有一个算法来淘汰, 此时我们可以得出 脏key率key 淘汰速度 的关系:

    X: 脏key率
    Y: 每个主程序循环内执行loop2次数 (Y >= 1)
    HZ: 每秒执行多少次cron
    qps:qps为key的过期速度,不考虑流量的波动的话,约等于当时的过期操作的请求数
    

    得出如下关系:

    X = qps / (20 * HZ * Y)
    

    因为 Y >= 1, 所以上面公式给出了一个 脏key率 X 的上限, 比如:

    HZ=10  => X<=pqs/200.
    HZ=100 => X<=pqs/2000.
    
  3. 调大HZ会导致redis空闲时的cpu占用上升, 我们的场景下单实例CPU占用大约增加 1% .

  4. 其它:
    • aof rewrite和rdb不会包括已过期的key
    • 从库不执行过期操作, 主库过期一个key时,会生成一个DEL操作,该操作会同步到从库。

3   关于hz, antirez 的一个解释

https://groups.google.com/forum/#!topic/redis-db/6kILekxQXBM

Redis HZ was 10 in 2.4
Redis HZ is 100 in 2.6
2.8 里面增加HZ配置, 默认10.

4   结论

  • 对于快速淘汰的cache集群, 应该设置较大的hz, 100是一个无害值.

Comments