底层数据结构
Redis 作为 Key-Value 存储系统,数据结构如下:
Redis 没有表的概念,Redis 实例所对应的db以编号区分,db 本身就是 key 的命名空间。 比如:user:1000 作为 key 值,表示在 user 这个命名空间下 id 为 1000 的元素,类似于 user 表的 id=1000 的 行。
RedisDB 结构
Redis 中存在“数据库”的概念,该结构由 redis.h中 的 redisDb 定义。 当 redis 服务器初始化时,会预先分配 16 个数据库 所有数据库保存到结构 redisServer 的一个成员 redisServer.db 数组中 redisClient 中存在一个名叫 db 的指针指向当前使用的数据库 RedisDB 结构体源码:
typedef struct redisDb {
int id; //id是数据库序号,为0-15(默认Redis有16个数据库)
long avg_ttl; //存储的数据库对象的平均ttl(time to live),用于统计
dict *dict; //存储数据库所有的key-value
dict *expires; //存储key的过期时间
dict *blocking_keys;//blpop 存储阻塞key和客户端对象
dict *ready_keys;//阻塞后push 响应阻塞客户端 存储阻塞后push的key和客户端对象
dict *watched_keys;//存储watch监控的的key和客户端对象 } redisDb;
RedisObject 结构
Value 是一个对象包含字符串对象,列表对象,哈希对象,集合对象和有序集合对象
结构信息概览
typedef struct redisObject {
unsigned type:4;//类型 五种对象类型
unsigned encoding:4;//编码
void *ptr;//指向底层实现数据结构的指针
//...
int refcount;//引用计数
//...
unsigned lru:LRU_BITS; //LRU_BITS为24bit 记录最后一次被命令程序访问的时间
//...
}robj;
字段说名
4 位 type
type 字段表示对象的类型,占 4 位; REDIS_STRING(字符串)、REDIS_LIST (列表)、REDIS_HASH(哈希)、REDIS_SET(集合)、REDIS_ZSET(有 序集合)。 当我们执行 type 命令时,便是通过读取 RedisObject 的 type 字段获得对象的类型 eg:
127.0.0.1:6379> type a1
string
4 位 encoding encoding 表示对象的内部编码,占 4 位 每个对象有不同的实现编码 Redis 可以根据不同的使用场景来为对象设置不同的编码,大大提高了 Redis 的灵活性和效率。 通过 object encoding 命令,可以查看对象采用的编码方式
127.0.0.1:6379> object encoding a1
"int"
24 位 LRU
lru 记录的是对象最后一次被命令程序访问的时间,( 4.0 版本占 24 位,2.6 版本占 22 位)。 高16位存储一个分钟数级别的时间戳,低8位存储访问计数(lfu : 最近访问次数) lru----> 高16位: 最后被访问的时间 lfu----->低8位:最近访问次数
refcount
refcount 记录的是该对象被引用的次数,类型为整型。 refcount 的作用,主要在于对象的引用计数和内存回收。 当对象的refcount>1时,称为共享对象 Redis 为了节省内存,当有一些对象重复出现时,新的程序不会创建新的对象,而是仍然使用原来的对 象。
ptr ptr 指针指向具体的数据,比如:set hello world,ptr 指向包含字符串 world 的 SDS。
7 种 type
1.字符串对象
C语言: 字符数组 "\0" Redis 使用了 SDS(Simple Dynamic String)。用于存储字符串和整型数据。
struct sdshdr{
//记录buf数组中已使用字节的数量
int len; //记录 buf 数组中未使用字节的数量
int free; //字符数组,用于保存字符串
char buf[];
}
buf[] 的长度 = len+free+1
SDS的优势: 1、SDS 在 C 字符串的基础上加入了 free 和 len 字段,获取字符串长度:SDS 是 O(1),C 字符串是 O(n)。 buf数组的长度=free+len+1 2、 SDS 由于记录了长度,在可能造成缓冲区溢出时会自动重新分配内存,杜绝了缓冲区溢出。 3、可以存取二进制数据,以字符串长度len来作为结束标识 C: \0 空字符串 二进制数据包括空字符串,所以没有办法存取二进制数据 SDS : 非二进制 \0 二进制: 字符串长度 可以存二进制数据 使用场景: SDS的主要应用在:存储字符串和整型数据、存储key、AOF缓冲区和用户输入缓冲。
本文由 chaoohuua 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2023/03/06 12:20