Redis底层结构一

11 篇文章 0 订阅
1 篇文章 0 订阅

Redis底层结构,更多关注redisDb结构体和redisObject

RedisDB结构

Redis中存在“数据库”的概念,该结构由server.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;

id

id是数据库序号,为0-15(默认Redis有16个数据库)

dict

存储数据库所有的key-value

expires

存储key的过期时间

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 位;

当我们执行 type 命令时,便是通过读取 RedisObject 的 type 字段获得对象的类型

127.0.0.1:6379> type k1
string

4位encoding

encoding 表示对象的内部编码,占 4 位 每个对象有不同的实现编码 Redis 可以根据不同的使用场景来为对象设置不同的编码,大大提高了 Redis 的灵活性和效率。

通过 object encoding 命令,可以查看对象采用的编码方式

127.0.0.1:6379> object encoding k1
"embstr"

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。

10种encoding

encoding 表示对象的内部编码,占 4 位。 Redis通过 encoding 属性为对象设置不同的编码

少的和小的数据,Redis采用小的和压缩的存储方式,体现Redis的灵活性,大大提高了 Redis 的存储量和执行效率 比如Set对象:

intset : 元素是64位以内的整数

hashtable:元素是64位以外的整数

如下所示:

127.0.0.1:6379> sadd set:001 1  3 5 6 2
(integer) 5
127.0.0.1:6379> object encoding set:001
"intset"
127.0.0.1:6379> sadd set:004 1 100000000000000000000000000 9999999999
(integer) 3
127.0.0.1:6379> object encoding set:004
"hashtable"

String

int、raw、embstr

1. int

REDIS_ENCODING_INT(int类型的整数)

127.0.0.1:6379> set n1 123
OK
127.0.0.1:6379> object encoding n1
"int"

2. embstr

REDIS_ENCODING_EMBSTR(编码的简单动态字符串)

小字符串 长度小于44个字节

127.0.0.1:6379> set name:001 zhangfei
OK
127.0.0.1:6379> object encoding name:001
"embstr"

3. raw

REDIS_ENCODING_RAW (简单动态字符串)

大字符串 长度大于44个字节

127.0.0.1:6379> set address:001
asdasdasdasdasdasdsadasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdas
dasdasdas
OK
127.0.0.1:6379> object encoding address:001
"raw"

list

列表的编码是quicklist。

REDIS_ENCODING_QUICKLIST(快速列表)

127.0.0.1:6379> lpush list:001 1 2 5 4 3
(integer) 5
127.0.0.1:6379> object encoding list:001
"quicklist"

hash

散列的编码是字典和压缩列表

1. dict

REDIS_ENCODING_HT(字典)

当散列表元素的个数比较多或元素不是小整数或短字符串时。

127.0.0.1:6379>  hmset user:003
username111111111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111  zhangfei password 111 num
2300000000000000000000000000000000000000000000000000
OK
127.0.0.1:6379> object encoding user:003
"hashtable"

2. ziplist

REDIS_ENCODING_ZIPLIST(压缩列表)

当散列表元素的个数比较少,且元素都是小整数或短字符串时。

127.0.0.1:6379> hmset user:001  username zhangfei password 111 age 23 sex M
OK
127.0.0.1:6379> object encoding user:001
"ziplist"

set

集合的编码是整形集合和字典

1. intset

REDIS_ENCODING_INTSET(整数集合)

当Redis集合类型的元素都是整数并且都处在64位有符号整数范围内(<18446744073709551616)

 127.0.0.1:6379> sadd set:001 1  3 5 6 2
(integer) 5
127.0.0.1:6379> object encoding set:001
"intset"

2. dict

REDIS_ENCODING_HT(字典)

当Redis集合类型的元素是非整数或都处在64位有符号整数范围外(>18446744073709551616)

127.0.0.1:6379> sadd set:004 1 100000000000000000000000000 9999999999
(integer) 3
127.0.0.1:6379> object encoding set:004
"hashtable"

zset

有序集合的编码是压缩列表和跳跃表+字典

1. ziplist

REDIS_ENCODING_ZIPLIST(压缩列表)

当元素的个数比较少,且元素都是小整数或短字符串时。

127.0.0.1:6379> zadd hit:1 100 item1 20 item2 45 item3
(integer) 3
127.0.0.1:6379> object encoding hit:1
"listpack"

2. skiplist

REDIS_ENCODING_SKIPLIST(跳跃表)

当元素的个数比较多或元素不是小整数或短字符串时。

127.0.0.1:6379>  zadd hit:2 100
item1111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111 20 item2 45 item3
(integer) 3
127.0.0.1:6379>  object encoding hit:2
"skiplist"

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值