String类型数据结构内存分析

1、redis中字符串类型的结构:
redis构建了一种名为简单动态字符串(simple dynamic string SDS)的数据抽象类型,默认字符串都是使用这种数据结构保存。整体结构如下:

struct sdshdr{
	//记录buf数组中已使用的字节的数量,等于SDS所保存字符串的长度 int 占用四字节
    int len;
    //记录buf数组中未使用的字节数量 int占用4字节
    int free;
    //字节数组,用户保存字符串;
    //为了表示字节数组的结束,Redis 会自动在数组最后加一个“\0”,
    //这就会额外占用 1 个字节的开销。
    char buf[];
}

a、String内存消耗如图所示:在这里插入图片描述
redis有多个数据类型,不同数据类型都有一些相同的元数据需要记录(最后一次访问,被引用次数等)所有会有一个RedisObject的结构体记录这些数据,并指向实际数据。最终一个字符串除去本身实际字符串会多占用25个字节, 所以使用String类型有个比较明显的短板,内存开销比较大,容易产生大内存redis生产RDB导致响应变慢的问题。这个连接可以预估内存占用量: 内存预估

b、String数据结构内存分布如图所示:
在这里插入图片描述

如果保存的字符串数据小于等于44字节,redisObject和SDS是一块连续的区域,可以避免内存碎片,被称为embstr编码方式;大于44字节就不会再布局到一起,被称为raw编码方式。
2、当面对大量String类型键值对需求如何优化空间分配(内存占用量超过2G得可以考虑)
可以使用集合类型保存这种类型的数据,具体举例如下:
可以采用Hash类型的二级编码方法,就是将一个单值的数据拆分成两部分,前一部分作为集合的key,后一部分作为Hash集合的value值中的key,这样可以将单值数据保存到Hash集合中,实例如下:

/**以图片 ID 1101000060 和图片存储对象 ID 3302000080 为例,
我们可以把图片 ID 的前 7 位(1101000)作为 Hash 类型的键,
把图片 ID 的最后 3 位(060)和
图片存储对象 ID 分别作为 Hash 类型值中的 key 和 value。*/

127.0.0.1:6379> info memory
# Memory
used_memory:1039120
127.0.0.1:6379> hset 1101000 060 3302000080
(integer) 1
127.0.0.1:6379> info memory
# Memory
used_memory:1039136
//使用了16个字节,而原本的直接以id为key,存储对象为值得需要64字节。

在使用Hash类型底层数据结构得时候,Hash会根据两个配置决定底层数据结构。为了充分使用压缩列表精简内存布局,就需要控制Hash集合中得元素个数,具体参数参考如下:
hash-max-ziplist-entries:表示用压缩列表保存时哈希集合中的最大元素个数。
hash-max-ziplist-value:表示用压缩列表保存时哈希集合中单个元素的最大长度。
如果在Hash集合中写入得元素个数超过hash-max-ziplist-entries或者单个元素大小超过hash-max-ziplist-value,redis就会自动把Hash的存储结构转换为哈希表。所以使用Hash要根据实际清空调整存入数据的单个长度和存入集合数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值