本文已收录至 Github,举荐浏览 👉 Java 随想录
微信公众号:Java 随想录
摘要
Redis 是一款开源的高性能 key-value 数据库,广泛应用于各种场景。在 Redis 中,数据类型(type)和编码(encoding)是十分重要的概念。本篇博客将具体介绍 Redis 反对的数据类型以及相应的编码方式和底层实现原理。
要查看 Redis 某个 key 的外部编码,能够应用 Redis 命令 OBJECT ENCODING key
。其中,key
是你想要查问的键名。例如,如果你想要查问名为 mykey
的键的外部编码,能够执行以下命令:
127.0.0.1:6379> object encoding mykey // 查看某个 Redis 键值的编码
redisObject
在 Redis 中,redisObject 是 Redis 中最根本的数据结构之一。redisObject 用于示意 Redis 中的键值对中的值,它能够是字符串、整数、列表、哈希表等任意一种 Redis 数据类型。
redisObject 的定义如下:
typedef struct redisObject {
// 类型
unsigned type:4;
// 编码方式
unsigned encoding:4;
// 援用计数
int refcount;
// 指向理论值的指针
void *ptr;
} robj;
- type:示意 redisObject 的类型。
- encoding:示意 redisObject 的编码方式。
- refcount:示意以后 redisObject 被援用的次数。
- ptr:ptr 字段则是一个指针,指向理论的 Redis 对象。
Redis 源码 encoding 取值有如下几种:
#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 */
类型与编码介绍
Redis 反对五种次要的数据类型:字符串 (string)、列表(list)、汇合(set)、有序汇合(sorted set) 和哈希(hash)。每种数据类型都有对应的编码方式。
数据类型与编码方式总览如下:
数据类型 | 编码方式 |
---|---|
字符串 | int、embstr、raw |
哈希表 | ziplist、hashtable |
列表 | ziplist、linkedlist、quicklist |
汇合 | intset、hashtable |
有序汇合 | ziplist、skiplist |
字符串
字符串是 Redis 中最根本的数据类型,通常用于存储文本或二进制数据。Redis 反对两种编码方式:
- int:当字符串能够示意为整数时,Redis 会将其转换为整数,并采纳 int 编码方式存储。int 编码方式的长处是存储空间小,操作效率高。毛病是只能存储整数,不反对字符串操作。
- embstr(embstr-encoded string):保留长度小于 44 字节的字符串,当一个字符串比拟短,采纳此编码方式存储,能够缩小内存占用。
- raw(raw-encoded string):保留长度大于 44 字节的字符串,当一个字符串比拟长时,采纳此编码方式存储。
列表
列表是一系列有序的字符串汇合,能够增加、批改和删除元素。Redis 反对三种编码方式:
- ziplist:在 Redis3.2 版本之前,当 List 列表中每个字符串的长度都小于 64 字节并且 List 列表中元素数量小于 512 个时,List 对象应用 ziplist 编码,其余状况应用 linkedlist 编码。ziplist 是一种紧凑的、压缩的列表构造,能够节俭内存。实用于小型列表。
- linkedlist:linkedlist 是一种链表构造,反对任意大小的列表。但其内存占用会随着列表长度的减少而减少。
- quicklist:Redis 3.2 版本引入,quicklist 是一种由多个 ziplist 组成的列表构造,既能保障性能,又能节俭内存。实用于大型列表。
汇合
汇合是一系列无序的字符串汇合,反对增加、删除和查问元素。Redis 反对两种编码方式:
- intset:当汇合中的元素都是整数时,Redis 会采纳 intset 编码方式存储。intset 编码方式的长处是存储空间小,操作效率高。
- hashtable:当汇合中的元素蕴含字符串时,Redis 会采纳 hashtable 编码方式存储。hashtable 编码方式的长处是能够存储任意类型的元素,反对字符串操作。毛病是存储空间绝对较大,操作效率绝对较低。
有序汇合
有序汇合是一系列无序的字符串汇合,每个元素关联一个分数,能够依据分数排序。Redis 反对两种编码方式:
- ziplist:保留的元素少于 128 个并且所有元素大小都小于 64 字节应用 ziplist 编码,ziplist 是一种紧凑的、压缩的列表构造,实用于小型有序汇合。
- skiplist:skiplist 是一种跳跃表构造,反对疾速查问和排序。实用于大型有序汇合。
哈希表
哈希表是一系列键值对汇合,每个键关联一个值。Redis 反对两种编码方式:
- ziplist:哈希对象保留的所有键值的字符串长度小于 64 字节并且键值对数量小于 512 个,Redis 会采纳 ziplist 编码方式存储。ziplist 编码方式的长处是存储空间小,操作效率高。毛病是不反对疾速的键查找操作。
- hashtable:除上述条件之外,Redis 会采纳 hashtable 编码方式存储。hashtable 编码方式的长处是反对疾速的键查找操作。毛病是存储空间绝对较大,操作效率绝对较低。
类型与编码底层原理
理解 Redis 反对的数据类型和编码方式后,咱们来看一下它们的底层实现原理。
编码转换
Redis 中的每个键值对都有一个类型标识,示意该键值对的数据类型。当咱们对一个键进行操作时,Redis 会依据该键以后的编码方式以及操作所需的编码方式,对键值对进行编码转换。
例如,当咱们向一个字符串中追加内容时,如果该字符串以后的编码方式为 raw,然而新的内容能够应用 embstr 编码方式存储,那么 Redis 会将该字符串的编码方式从 raw 转换为 embstr。
数据结构
除了编码方式外,Redis 还应用了许多经典的数据结构来实现各种数据类型。例如,Redis 的列表和哈希表都是采纳链表构造实现的。而有序汇合则采纳了跳跃表 (Skip List) 这种高效的数据结构。
这些数据结构都通过了精心设计和优化,以满足各种场景下的利用需要。例如,链表构造适宜频繁地增加和删除元素,而跳跃表构造则适宜排序和查找。
总结
本篇博客介绍了 Redis 反对的五种次要数据类型以及相应的编码方式。Redis 的数据类型和编码方式是为了在不同的场景下达到最佳的性能和内存占用。在应用 Redis 时,须要依据理论状况抉择适合的数据类型和编码方式,以达到最佳的成果。同时,须要留神不同数据类型和编码方式的优缺点,以便在理论应用中做出正当的抉择。
本篇文章就到这里,感激浏览,如果本篇博客有任何谬误和倡议,欢送给我留言斧正。文章继续更新,能够关注公众号第一工夫浏览。