Redis内部数据结构
1. redis数据结构和内部编码
数据结构 | 内部编码 | 备注 |
---|---|---|
string | raw | 基本的字符串(类似于C语言的char数组) |
string | int | 可计数类型 |
string | embstr | 短字符串的特殊优化 |
hash | hashtable | 基本哈希表 |
hash | ziplist | 压缩列表,在hash表元素较少时会使用 |
list | quicklist | 实际是链表,每个元素是ziplist,类似于std::deque |
set | hashtable | 基本哈希表 |
set | intset | 如果存的都是整数会使用 |
zset | skiplist | 跳表 |
zset | ziplist | 压缩列表 |
数据类型是redis承诺提供给用户的,但其内部如何实现由redis自动适应选择最合适的编码
可以通过object encoding命令查询内部编码~
Redis这样设计有两个好处:
- 可以改进内部编码,而对外的数据结构和命令没有任何影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令
- 多种内部编码实现可以在不同场景下发挥各⾃的优势,例如
ziplist
比较节省内存,但是在列表元素比较多的情况下,性能会下降,这时候Redis
会根据配置选项将列表类型的内部实现转换为linkedlist
,整个过程用户同样无感知。
2. string
字符串类型是Redis
最基础的数据类型,关于字符串需要特别注意:
1)首先Redis
中所有的键的类型都是字符串类型,而且其他几种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型,所以字符串类型能为其他4种数据结构的学习奠定基础。
2)其次,字符串类型的值实际可以是字符串,包含一般格式的字符串或者类似JSON、XML
格式的字符;数字,可以是整型或者浮点型;甚至是二进制流数据,例如图片、音频、视频等。
不过一个字符串的最大值不能超过512MB。
注:由于Redis
内部存储字符串完全是按照二进制流的形式保存的,所以Redis
是不处理字符集编码问题的,客户端传⼊的命令中使用的是什么字符集编码,就存储什么字符集编码。在终端输入汉字,是按照utf8编码的,汉字是3字节;可以在启动redis客户端是加上–raw,让客户端尝试将字节流翻译成结果
2.1 常见命令
SET:将string
类型的value
设置到key
中。如果key
之前存在,则覆盖,无论原来的数据类型是什么。之前关于此key
的TTL
也全部失效。
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
时间复杂度:O(1)
SET命令支持多种选项来影响它的行为:
- EX seconds – 设置key的过期时间(秒级)
- PX milliseconds – (毫秒级)
- NX – 只在key不存在时才进行设置,即如果key之前已经存在,设置不执行。
- XX – 只在key存在时才进行设置,即如果key之前不存在,设置不执行。
GET:获取key对应的value。如果key不存在,返回nil。如果value的数据类型不是string,会报错。
GET key
时间复杂度:O(1)
MGET、MSET:分别是GET和SET的多次版,获得多个key对应的value和设置多个key
意义:由于Redis采用客户端服务器模式,每个请求都会封装成一个网络请求,通过网络传输,一次性操作多个key的效率是要高于多次操作一个key的
2.2 计数命令
INCR:将key对应的string表示的数字加⼀。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
INCR key
时间复杂度:O(1)
返回值:integer类型的加完后的数值。
INCRBY:将key对应的string表示的数字加上对应的值。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
INCRBY key decrement
DECR、DECYB、INCRBYFLOAT:与INCR
和INCRBY
类似,数值可以为负数
2.3 字符串操作命令
APPEND:如果key已经存在并且是⼀个string,命令会将value追加到原有string的后边。如果key不存在,则效果等同于SET命令。
APPEND KEY VALUE
返回值:追加完成之后string的长度。
GETRANGE:返回key对应的string的⼦串,由start和end确定(左闭右闭)。可以使用负数表示倒数。-1代表倒数第一个字符,-2代表倒数第二个,其他的与此类似。超过范围的偏移量会根据string的长度调整成正确的值。
GETRANGE key start end
返回值:string类型的子串
SETRANGE:覆盖字符串的⼀部分,从指定的偏移开始。如果key不存在也是能操作的,会把offset之前比特位设置为0x00
SETRANGE key offset value
STRLEN:获取key对应的string的⻓度。当key存放的类似不是string时,报错。
2.4 典型使用场景
- 缓存(Cache)功能 :Redis作为缓冲层,MySQL作为存储层,