更高"/>
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的结构图:
- zlbytes:32bit,表示ziplist占用的字节总数。
- zltail:32bit,表示ziplist表中最后一项(entry)在ziplist中的偏移字节数。通过zltail我们可以很方便地找到最后一项,从而可以在ziplist尾端快速地执行push或pop操作,保证了时间复杂度为O(1)
- zlen:16bit, 表示ziplist中数据项(entry)的个数。
- entry:表示真正存放数据的数据项,长度不定
- zlend: ziplist最后1个字节,是一个结束标记,值固定等于255。
3)小结:
-a)首先我们存入的是多个缓存,每个sds都需要包含len(已用长度)、alloc(buf[]分配长度)、flags(标识),bug[],
-b)而ziplist中只需要前面几个prerawlen(前一个元素的字节长度)、len(entry中数据的长度)、接着就是紧凑的数据了,这样在多个字符串存储的时候ziplist就省去了大量的数据外的空间占用,这就是省内存的关键。那为什么效率为何更高?正是因为空间占用的少,所以寻址的次数就会更少,效率也就更高。
更多推荐
redis中为什么hash比string做缓存更节省内存及效率更高
发布评论