Redis核心技术-数据结构3-String、Redis Object

本文详细介绍了Redis中String类型的底层实现,包括SimpleDynamicString(SDS)结构和RedisObject结构体。SDS结构包含len和free字段,以及buf字节数组。RedisObject则包含type、encoding、lru和refcount属性。字符串类型根据长度采用int编码、embstr编码或raw编码,以优化内存使用。此外,文章还提到了内存分配策略,如jemalloc的内存分配规则,并讨论了key-value存储在哈希表中所需的内存大小。

String类型底层结构

  使用的底层结构为简单动态字符串(Simple Dynamic String SDS)

typedef char *sds;
struct sdshdr {
    int len;
    int free;
    char buf[];
};

  简单动态字符串内存长度:
在这里插入图片描述

  len:记录buf已使用的长度,len长度为4byte;
  alloc:记录buf实际分配的长度,alloc长度为4byte;
  buf:字节数组,保存实际数据,“\0”表示数据结束,额外增加1个字节开销。

  String类型除了SDS内存使用外,还有RedisObject结构体。

  RedisObject结构体使用8byte存储元数据,使用8byte存储数据指针,数据指针指向具体数据所在位置。
在这里插入图片描述

struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
};

结构体RedisObject定义了5个属性:type、enconding、lru、refcount和*prt。

  • type:当前值对象的数据类型
有序集合对象对象的名称
REDIS STRING字符串对象
REDIS LIST列表对象
REDIS HAST哈希对象
REDIS SET集合对象
REDIS ZSET有序集合对象

  查看key type:

> set testkey1 test
OK
> type testkey1
string
  • encoding:当前值对象底层编码类型
类型编 码对 象
REDIS STRINGREDIS ENCODING INT使用整数值实现的字符串对象
REDIS STRINGREDIS ENCODING EMBSTR使用embstr编码的简单动态字符申实现的字符串对象
REDIS STRINGREDIS ENCODING RAW使用简单动态字符申实现的字符串对象
REDIS LISTREDIS ENCODING ZIPLIST使用压缩列表实现的列表对象
REDIS LISTREDIS ENCODING LINKEDLIST使用双端链表实现的列表对象
REDIS HASHREDIS ENCODING ZIPLIST使用压缩列表实现的哈希对象
REDIS HASHREDIS ENCODING HT使用字典实现的哈希对象
REDIS SETREDIS ENCODING INTSET使用整数集合实现的集合对象
REDIS SETREDIS ENCODING HT使用字典实现的集合对象
REDIS ZSETREDIS ENCODING ZIPLIST使用压缩列表实型能有序篇合对象
REDIS ZSETREDIS ENCODING SKIPLIST使用跳跃表和字典实现的有序集合对象

  查看key encoding:

> set testkey1 test
OK
> object encoding testkey1
embstr
> set testkey2 7
OK
> object encoding testkey2
int
  • Iru:存储最后一次使用此对象的时间等信息。当redis内存回收算法设置为volatile-lru或者allkeys-lru时候redis会优先释放最久没有被访问的数据。
  • int refcount:记录对象引用次数。用于共享计数,类似于jvm的引用计数垃圾回收算法,当refcount为0时,表示没有其它对象引用,可以进行释放此对象。
  • void *ptr:指向真正底层数据结构的指针。

  Redis针对不同的数据类型,做了一些优化:
1.如果是Long类型整数,ptr为整数数据,非指针,目的是为了节省内存,这种内存布局方式称为int编码方式;

2.如果是字符串类型,并且长度小于或等于44byte时,RedisObject中的元数据、ptr、SDS为一块连续内存,目的为了避免内存碎片,这种内存布局方式称为embstr编码方式;

3.如果字符串类型大于44byte,ptr指向SDS内存空间,这种内存布局方式称为raw编码方式。

  int编码、embstr编码、raw编码方式结构如下:
在这里插入图片描述
  Redis核心技术-数据结构1-底层结构中说的key和value存储在哈希表dictEntry结构体中,dictEntry结构体需要24byte,但是由于jemalloc内存分配方式规则,dictEntry实际内存为32byte。内存结构如下:
在这里插入图片描述

  Redis使用jemalloc库分配内存,jemalloc分配内存时,根据申请内存字节数N,计算比N大的字节数S,S取值最接近2的次方数。

  例如N=24,S取值2的5次方=32。类似JVM中的内存大小分配。

  由此可以计算出一个key和value最少需要多大内存?
  key和value都是Long整数,都使用int编码,需要64byte,其中dictEntry32byte(24byte+8byte填充)、key值16byte、value值16byte;

参考:
https://www.cnblogs.com/monkey-code/p/13157908.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲上云霄的Jayden

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值