Redis数据结构必知必会

我是非典型理科男号主。 关注后你可以收获最硬核的知识分享, 最有趣的互联网故事

Redis数据结构

Redis在互联网实践中被广泛使用。 一方面是内存存储以及高效的内存管理保障了数据高效读写。另一方面高效的IO模型使得Redis单机就可以扛住10W/秒的读请求。

除了这些之外, Redis支持丰富的数据结构并且每个数据结构都经过了极致的优化。 这些特性推动了Redis在互联网领域开花结果。

作为一名资深的研发工程师,不仅需要知道Redis支持五种基本数据类型,还需要掌握不同编码具体实现和相关优化以及不同数据类型在实践中的应用。

由于相关内容众多,我将分两篇文章介绍相关内容。

你将从这篇文章获取Redis对象以及相关构成、 五种基本类型和六种编码方式、不同类型使用场景和相关的Redis命令。

下一篇文章,将详细介绍每种数据结构的具体实现细节。 你讲了解到SDS、空间预分配和惰性删除、渐进式rehash技术、阻塞队列、跳跃表等。

注:所有源代码来源于redis-6.2.4版本, 点击redis relase列表下载对应的源码版本。

Redis核心对象简介

在Redis有一个「核心对象」叫做redisObject。 redisObject是Redis定义的数据结构, 用它在表示所有的key和value。

redisObject定义在server.h文件中, 具体定义如下:

typedef struct redisObject {
    // 数据类型
    unsigned type:4;
    //  lru时钟修改后,2位的对齐位( unsigned notused:2),在新版本已经去掉;
    // 数据编码
    unsigned encoding:4;
    // LRU时间(全局lru时钟相对时间或者8位经常用到或者16位访问时间)
    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;
} robj;

三属性

type、 encoding 和 ptr 是最重要的三个属性。

type表示Redis对象的类型, redis支持五种数据类型。分别为:

/*-----------------------------------------------------------------------------
 * Data types
 *----------------------------------------------------------------------------*/

/* A redis object, that is a type able to hold a string / list / set */

/* The actual Redis Object */
#define OBJ_STRING 0    /* String object. */
#define OBJ_LIST 1      /* List object. */
#define OBJ_SET 2       /* Set object. */
#define OBJ_ZSET 3      /* Sorted set object. */
#define OBJ_HASH 4      /* Hash object. */

encoding表示对象的编码方式, encoding表示实际存储的数据结构。 redis最新版本支持11种数据编码。 分别为:

/* 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  /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#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 ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */

对象可以以多种方式编码:
字符串可以被编码为 raw (一般字符串)或 int (用字符串表示64位数字是为了节约空间)。
列表可以被编码为 ziplist 或 linkedlist 。 ziplist 是为节约大小较小的列表空间而作的特殊表示。
集合可以被编码为 intset 或者 hashtable 。 intset 是只储存数字的小集合的特殊表示。
哈希表可以编码为 zipmap 或者 hashtable 。 zipmap 是小哈希表的特殊表示。
有序集合可以被编码为 ziplist 或者 skiplist 格式。 ziplist 用于表示小的有序集合,而 skiplist 则用于表示任何大小的有序集合。

ptr是实际存储结构体的内存指针。

下图展示了 redisObject 、Redis 所有数据类型、以及 Redis 所有编码方式(底层实现)三者之间的关系:

在这里插入图片描述

通过命令窥看redisObject

可以通过objectkey命令窥看redisObject相对应的属性。

OBJECT命令

OBJECT subcommand [arguments [arguments]]

OBJECT 命令允许从内部察看给定 key 的 Redis 对象。

它通常用在除错(debugging)或者了解key对应的编码情况。

常用的SUBCOMMAND如下:

OBJECT REFCOUNT  返回给定 key 引用所储存的值的次数。此命令主要用于除错。
OBJECT ENCODING  返回给定 key 锁储存的值所使用的内部表示(representation)。
OBJECT IDLETIME  返回给定 key 自储存以来的空转时间(idle, 没有被读取也没有被写入),以秒为单位。

TYPE 命令

type命令用户返回value值的类型。

返回值:

none (key不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)

你可能感兴趣的:(Redis数据结构必知必会)