浅析 Redis 中 String 数据类型及其底层编码

从 redisObject 说起在 Redis 中 , 任意数据类型的键和值都会被封装为一个 RedisObject  , 也叫做Redis对象 , 源码如下

浅析 Redis 中 String 数据类型及其底层编码

文章插图
我们来看一下这个结构体中的成员变量分别代表什么:
  • unsigned type:4 :对象类型 , 分别是 string hash list set zset  , 占 4 个 bit 位 , 如下所示
  • #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. */
  • unsigned encoding:4: 底层编码方式 , 共有 11 种 , 4 个 bit 位
  • unsigned lru:LRU_BITS :该对象最后一次被访问的时间 , 占 24 个 bit  , 在 Redis 内存回收中起到关键作用
  • int refcount :对象引用计数器 , 计数器为 0 则说明对象无人引用 , 可以被回收
  • void *ptr:指针 , 指向存放实际数据的空间
我们注意到 , 在 Redis 中有 5 中数据结构(用户使用的) , 但在底层却有 11 种编码方式 , Redis 会根据存储的数据类型、存储数据的大小 , 选择不同的编码方式 , 以获得最优的性能 。一种数据结构会对应多种数据结构 , 如下表所示 。
数据类型
编码方式
OBJ_STRING
int、embstr、raw
OBJ_LIST
LinkedList和ZipList(3.2以前)、QuickList(3.2以后)
OBJ_SET
intset、HT
OBJ_ZSET
ZipList、HT、SkipList
OBJ_HASH
ZipList、HT
【浅析 Redis 中 String 数据类型及其底层编码】下面 , 我们现在介绍以下 String 数据类型 , 及其底层的编码方式 。
Redis 数据结构 -- StringString 类型的基本介绍和命令String 类型 , 也就是字符串类型 , 是Redis中最简单的存储类型 。它可以存储字符串、整数或浮点数 。下面是一些 String 类型常用的命令
1.SET key value:设置指定 key 的值为指定的字符串或数字 。
2.GET key:获取指定 key 的值 。
3.本地虚拟机redis:0>set key01 value01 "OK" 本地虚拟机redis:0>get key01 "value01"
4.INCR key:将指定 key 的值加 1 , 如果该 key 不存在 , 则先将其设置为 0 , 再进行加 1 操作 。
5.DECR key:将指定 key 的值减 1 , 如果该 key 不存在 , 则先将其设置为 0 , 再进行减 1 操作 。
6.INCRBY key increment:将指定 key 的值增加指定的增量 。
7.DECRBY key decrement:将指定 key 的值减少指定的减量 。
8.AppEND key value:将指定的值追加到指定 key 的值的末尾 。
9.STRLEN key:返回指定 key 的值的长度 。
10.GETRANGE key start end:返回指定 key 的值的子字符串 , 根据起始位置和结束位置指定 。
11.SETRANGE key offset value:将指定 key 的值从指定偏移位置开始 , 替换为指定的字符串 。
12.MSET key1 value1 [key2 value2 ...]:同时设置多个 key 的值 。(”[ ]” 中括号内表示可选)
13.MGET key1 [key2 ...]:获取多个 key 的值 。
这里仅给出 SET、GET 命令 , 其他的请自行测试 。这些命令只是 Redis String 类型命令的一小部分 , Redis 还提供了其他更多的命令来处理 String 类型的数据 。你可以参考 Redis 官方文档以获取完整的命令列表和详细的命令说明 。
String 类型的底层实现在 Redis 中 , String 类型的数据结构并不是采用 C 语言中自带的字符串类型 , C 语言中的数据结构存在很多问题 , 比如:
  • 获取字符串长度的需要通过运算
  • 非二进制安全
  • 不可修改
因此 , String 在 Redis 中有其他三种编码方式: int、embstr、raw。其中 ,  raw 和 embstr 类型 , 都是基于动态字符串(SDS)实现的 , 下面我们先来看看动态字符串的结构是怎样的 。


推荐阅读