5 大结构底层 C 语言源码分析

Redis 数据类型与数据结构总纲图

源码分析总体数据结构大纲

  • SDS 动态字符串
  • 双向链表
  • 压缩列表 ziplist
  • 哈希表 hashtable
  • 跳表 skiplist
  • 整数集合 intset
  • 快速列表 quicklist
  • 紧凑列表 listpack

数据类型以及数据结构的关系

Redis6 之前

Redis-Redis6-之前数据类型与数据结构之间的关系

Redis7

Redis-Redis7-数据类型与数据结构之间的关系

源码分析具体数据结构大纲

Redis-程序员写代码时脑子底层思维

上帝视角最终编码如何来的

Redis-字典数据库结构图

redisObject 操作底层定义来自哪里

Redis-redisObject-与-Redis-数据类型编码方式三者间的关系

server.h
/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3  /* No longer used: old hash encoding. */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* No longer used: old list/hash/zset encoding. */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of listpacks */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
#define OBJ_ENCODING_LISTPACK 11 /* Encoded as a listpack */

经典 5 大数据结构解析⭐️

各个类型的数据结构的编码映射和定义

object.c
char *strEncoding(int encoding) {
    switch(encoding) {
    case OBJ_ENCODING_RAW: return "raw";
    case OBJ_ENCODING_INT: return "int";
    case OBJ_ENCODING_HT: return "hashtable";
    case OBJ_ENCODING_QUICKLIST: return "quicklist";
    case OBJ_ENCODING_LISTPACK: return "listpack";
    case OBJ_ENCODING_INTSET: return "intset";
    case OBJ_ENCODING_SKIPLIST: return "skiplist";
    case OBJ_ENCODING_EMBSTR: return "embstr";
    case OBJ_ENCODING_STREAM: return "stream";
    default: return "unknown";
    }
}

Debug Object Key ⭐️

再看一次 set age 17

参数含义
type类型
encoding编码,此处是数字类型
lru最近被访问的时间
refcount等于 1,表示当前对象被引用的次数
ptrvalue 值的多少,当前就是 17

上述解读

  • 命令

    127.0.0.1:6379> DEBUG OBJECT key
  • 案例

    • 开启前

      127.0.0.1:6379> get k1
      "v1"
      127.0.0.1:6379> DEBUG object k1
      (error) ERR DEBUG command not allowed. If the enable-debug-command option is set to "local", you can run it from a local connection, otherwise you need to set this option in the configuration file, and then restart the server.
      127.0.0.1:6379> config get enable-debug-command
      1) "enable-debug-command"
      2) "no"
      127.0.0.1:6379>
    • 开启后

      修改 redis.conf

      enable-debug-command local
      • Value at:内存地址
      • refcount:引用次数
      • encoding:物理编码类型
      • serializedlength:序列化后的长度(注意这里的长度是序列化后的长度,保存为 rdb 文件时使用了该算法,不是真正存贮在内存的大小),会对字串做一些可能的压缩以便底层优化。
      • lru:记录最近使用时间戳
      • lru_seconds_idle:空闲时间
      127.0.0.1:6379> get k1
      "v1"
      127.0.0.1:6379> DEBUG object k1
      Value at:0x7fa040e56fa0 refcount:1 encoding:embstr serializedlength:3 lru:14189758 lru_seconds_idle:5
      127.0.0.1:6379> get k1
      "v1"
      127.0.0.1:6379> DEBUG object k1
      Value at:0x7fa040e56fa0 refcount:1 encoding:embstr serializedlength:3 lru:14189832 lru_seconds_idle:1
      127.0.0.1:6379>