redis中为什么hash比string做缓存更节省内存及效率更高

1.String

-1)string底层采用sds编码(在不是数据的情况下),在redis3.2版本后会根据string的大小来采用不同的位数的sds编码,下面是不同的sds中c语言源码跟sdshdr8格式结构图:

typedef char *sds;
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; //已用
    uint8_t alloc; //buf[]总共分配的长度
    unsigned char flags; //用于内存对齐放在前面的标识位,char类型占一个字节(8位)
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
........

2)首先前提是在hash使用ziplist的编码情况:

下面是ziplist的结构图:

  1. zlbytes:32bit,表示ziplist占用的字节总数。
  2. zltail:32bit,表示ziplist表中最后一项(entry)在ziplist中的偏移字节数。通过zltail我们可以很方便地找到最后一项,从而可以在ziplist尾端快速地执行push或pop操作,保证了时间复杂度为O(1)
  3. zlen:16bit, 表示ziplist中数据项(entry)的个数。
  4. entry:表示真正存放数据的数据项,长度不定
  5. zlend: ziplist最后1个字节,是一个结束标记,值固定等于255。

3)小结:

-a)首先我们存入的是多个缓存,每个sds都需要包含len(已用长度)、alloc(buf[]分配长度)、flags(标识),bug[],

-b)而ziplist中只需要前面几个prerawlen(前一个元素的字节长度)、len(entry中数据的长度)、接着就是紧凑的数据了,这样在多个字符串存储的时候ziplist就省去了大量的数据外的空间占用,这就是省内存的关键。那为什么效率为何更高?正是因为空间占用的少,所以寻址的次数就会更少,效率也就更高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值