Redis hash数据存储空间优化
最近遇到一个需求,需要将hive中16亿行数据存储到redis中。数据存储采用hash结构,将16亿行数据根据key离散到32万个hash中。
由于每一行的key是16个字节,数据为1个字节,一开始在预估存储空间为:16亿*(16+1) = 26 G 左右。于是部署了16个分片,每个分片10G的集群。但是实际数据推上集群后,发现占用了140G空间,这大大超出了之前的预估。
感到很疑惑,于是查找相关资料。发现 ,中提到hash结构在redis中有ziplist和dictionary两种实现形式。当hash中的数据不超过hash-max-ziplist-entries、hash-max-ziplist-value的配置值时,redis会将hash中的数据以ziplist的格式存储,从而最大可能的减少维持map的内部数据结构消耗。
查看我自己的集群配置,发现hash-max-ziplist-entries=512,而我16亿行数据散列到32万个hash中,每个hash下有5000条记录。这里redis在存储我数据时应该使用了dictionary结构,导致存储的额外开销特别高。于是将hash数修改为320万,使数据散列在320万个hash中,每个hash下500条记录。
重新推数,发现这次空间占用降到了28G左右。符合预期。
备注:
hash-max-ziplist-entries:表示hash结构中field的数量阈值。如果超过该值,则自动从ziplist转成dictionary结构。
hash-max-ziplist-value:表示hash结构中每个field和对应value的长度阈值。如果任意field或者value的长度超过该值,则自动从ziplist转成dictionary结构。