如果一个Key的Value特别大,那么可能会对Redis产生巨大的性能影响,因为Redis是单线程模型,对大Key进行查询或删除等操作,可能会引起Redis阻塞甚至是高可用切换。 应该如何查询Redis中的大Key,以及如何在设计上实现大Key的拆分呢?
key分类如下:
尝试将对象分拆成几个K.V, 使用multiGet获取值。 拆分旨在降低单次操作的压力,将操作压力平摊到多个Redis实例,降低对单个redis的I/O影响。
如果key个数过多,会带来更多内存空间占用:
这两方面在key个数上亿时消耗内存十分明显(Redis 3.2及以下版本均存在这个问题,4.0有优化)。所以减少K个数可以减少内存消耗,可以参考的方案是转Hash结构存储,即原先是直接使用Redis String 的结构存储,现在将多个key存储在一个Hash结构:
比如多个K代表一个对象,每个K是对象的一个属性,这种可直接按照特定对象的特征来设置一个新K——Hash结构, 原先的K则作为这个新Hash 的field。
预估总量,预分一个固定的桶数量: 比如现在预估K总计2亿,按一个hash存储 100个field算,需要 2亿 / 100 = 200W 个桶 (200W 个K占用的空间很少,2亿可能有近20G )。 现在按200W固定桶分,即先计算出桶的序号
hash(123456789) % 200W
最好保证该hash算法的值是个正数,否则需要调整模除的规则。
这样算出三个key 的桶分别是 1、2、2。 所以
注意hash取模对负数的处理,还有预分桶时, 一个hash 中存储的值最好不要超过 512,100 左右较为合适。