bigkey

  bigkey是指key对应的value所占的内存空间比较大。按照数据结构细分,一般分为字符串类型bigkey和非字符串类型bigkey。

(1) 字符串类型:一般认为超过10KB就是bigkey。
(2) 非字符串类型:哈希、列表、集合、有序集合,体现在元素个数过多。

1 bigkey的危害

  (1) 内存使用不均匀:例如在Redis集群中,bigkey会造成节点的内存空间使用不均匀。
  (2) 超时阻塞:由于Redis单线程的特性,操作bigkey比较耗时,也就意味着阻塞Redis的可能性增大。
  (3) 网络拥塞:每次获取bigkey产生的网络流量比较大,假设一个bigkey为1MB,每秒访问量为1000,那么每秒产生1000MB的流量。

2 发现bigkey

  redis-cli --bigkeys可以命令统计bigkey的分布。
  判断一个key是否是bigkey,只需执行debug object key查看serializedlength属性即可,它表示key对应的value序列化之后的字节数。
  例如如果执行以下命令:

127.0.0.1:6379> debug object msg
Value at:000007F51306AEB0 refcount:1 encoding:raw serializedlength:31 lru:221580
4 lru_seconds_idle:10

  可以发现serializedlength=31 字节,encoding是embstr,也就是字符串类型,可以通过strlen看以下字符串的字节数为1675个字节。

127.0.0.1:6379> strlen msg
(integer) 1675

  serializedlength不代表真是的字符大小,它返回对象使用RDB编码序列化后的长度,值偏小。但是对于排查bigkey具有一定的辅助作用,因为不是每一种数据结构都有类似strlen的命令,如列表类型就没有strlen命令。

127.0.0.1:6379> lpush databases mysql oracle redis
(integer) 3
127.0.0.1:6379> strlen databases
(error) WRONGTYPE Operation against a key holding the wrong kind of value

在实际生产环境中,发现bigkey的两种方式:
(1) 被动收集:所谓被动收集就是等到出现了问题再去分析原因,如命令的慢查询或网卡跑满的情况,通过分析找到可能的原因是bigkey,这种方式不推荐使用。建议修改Redis客户端,当抛出异常打印所操作的key,方便排查bigkey。
(2) 主动收集:scan + debug object的命令,如果怀疑存在bigkey,可以使用scan命令渐进的扫描出所有的key,分别计算每个key的serializedlength,找到对应的bigkey进行相应的处理和报警,这种方式比较推荐。

SCAN 命令:用于迭代当前数据库中的数据库键。跟keys命令返回全部的数据库键不同,它每次执行都只会返回少量元素,所以可以用于生产环境
  SCAN 命令是一个基于游标的迭代器(cursor based iterator): SCAN 命令每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

127.0.0.1:6379> scan 0
1) "13"
2)  1) "h"
    2) "e"
    3) "n"
    4) "f"
    5) "d"
    6) "s"
    7) "i"
    8) "msg"
    9) "k"
   10) "databases"
127.0.0.1:6379> scan 13
1) "0"
2) 1) "r"
   2) "t"
   3) "message"
   4) "m"
   5) "j"
   6) "l"

scan 0:第一次迭代使用 0 作为游标, 表示开始一次新的迭代。
第二次迭代使用的是第一次迭代时返回的游标, 也即是命令回复第一个元素的值 —— 13
在第二次调用SCAN命令时,命令返回了游标 0,这表示迭代已经结束, 整个数据集(collection)已经被完整遍历过了。

3 删除bigkey

  使用del命令删除bigkey通常来说会阻塞Redis服务器,在生产环境中要尽量避免。
  当bigkey对应的value越来越大,删除的时间也会随着增加。除了string类型删除时一般不产生阻塞,其他四种数据结构的删除都有可能产生阻塞。
  删除bigkey要使用渐进式遍历的方式,利用sscan、hscan、zscan命令将若干个键拿出来。
  实际中如何避免bigkey:

(1) 在数据结构的选择和设计应合理,如出现了bigkey,考虑可不可以优化(例如拆分数据结构)尽量让bigkey消失在业务中。
(2) 如果bigkey不可避免,也要考虑是不是每次都要将所有的元素都取出来,有时仅仅只需要hmget,而不是hgetall。
(3) Redis 4.0支持lazy delete free模式,删除bigkey不会阻塞Redis。

小结

(1) bigkey会造成数据倾斜,网络拥塞和超时阻塞,在实际环境中要重视bigkey。
(2) bigkey删除要使用渐进式遍历方式,防止出现Redis阻塞的情况。
(3) Redis 4.0支持lazy delete free,它不会阻塞Redis。

  本文完


  注:本文参考《Redis开发与运维》,如发现错误,请指正!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容