Redis 的 string 内存消耗为何如此之大
前言
说到 redis 的数据类型,常用的有 string、list、set 等。在我们使用 string 类型时,如果你注意过,会发现 string 类型有个明显的缺点:string 的数据保存占用的空间较多。接下来就来了解下 string 为何占用那么多内存吧。
Redis string 的数据结构
要知道 string 为何占用那么多内存,首先我们得清楚 Redis 的存储原理。先来个结论:string 除了要记录我们写入的数据外,还需要记录数据长度、空间使用量等信息(元数据),记录这些都要消耗额外空间。当我们用 string 存储很小的数据时,元数据的开销对比起来就显得很大了。
来看看 string 的数据结构,如下图:
除了上图的开销,还要考虑到 RedisObject 结构体的开销。RedisObject 包含了 8 字节的元数据和一个指向具体数据类型的实际数据的 8 字节指针。
最后,Redis 还有一个全局哈希表保存所有键值对。哈希表的每一个数据都记录了键值对的信息,分别记录 key、value 和下个数据的指针,每个占用 8 字节,总共 24 字节。
由此可见,string 类型除了要保存实际数据外,还要记录元数据、redisObject 结构体以及全局哈希表的数据。如果实际数据很小,用 string 的性价比就很低了。
用什么数据类型更省空间
既然 string 占用的内存空间很多,那什么数据类型可以作为替代项呢?压缩列表是一个好的选择。
压缩列表的数据结构如下图:
prev_len 表示前一个数据的长度,len 表示自身长度(4 字节),encoding 表示编码方式(1 字节),content 用来保存实际数据。这些数据会放置在连续的内存空间,不用额外指针指向,因此比较省空间。Redis 的 list、hash、sorted set 底层数据结构都用到了压缩列表。我们可以考虑用这些数据类型去存储数据。
小结
redis 的 string 在内存消耗方面没有优势,如果你有大量的数据首先想到的是 string 来存储,那么得好好考量一下这样做预计会产生的内存消耗,以及使用其他数据类型如 list 去替代 string 类型。
版权声明: 本文为 InfoQ 作者【芥末拌个饭吧】的原创文章。
原文链接:【http://xie.infoq.cn/article/e2d47d6505c91ad6170f5e11d】。文章转载请联系作者。
评论