Redis
用到的所有主要数据结构,简单动态字符串(SDS
)、双端列表、字典、跳跃表、整数集合、压缩列表。
Redis
并没有直接使用这些数据结构来实现键值对的数据库,而是基于这些数据结构创建了一个对象西永,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每中对象都用到了至少一种我们前面所介绍的数据结构。
通过这五种不同类型的对象,Redis
可以在执行命令之前,根据对象的类型来判断一个对象是否可以执行给定的命令。使用对象的一个好处是,我们可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。
Redis
的对象系统还实现了基于引用计数技术的内存回收机制,当程序不在使用某个对象的时候,这个对象所占用的内存就会被自动释放;另外,Redis
还通过引用计数技术实现了对象的共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享用一个对象来节约内次。
最后,Redis
的对象带有访问时间记录信息,该信息可以用于计算数据库键的空转时长,在服务器启用了maxmemory
功能的情况下,空转时长较大的那些键可能会优先被服务器删除。
8.1 对象的类型与编码
Redis
使用对象来表示数据库中的键和值,每次当我们在Redis
的数据库中新创建一个键值对,我们至少创建两个对象,一个对象用作键值对的键,另一个对象用作键值对的值。
Redis
中的每个对象都由一个redisObject
结构表示,该结构中和保存数据有关的三个属性分别是type
属性、encoding
属性和ptr
属性:
typedef struct redisObject{
//类型
unsigned type:4;
//编码
unsigned encoding:4;
//指向底层实现数据结构的指针
void *ptr;
}
8.1.1 类型
对象的type
属性记录了对象的类型,这个属性的值如下
类型常量 | 对象的名称 |
---|---|
REDIS_STRING |
字符串对象 |
REDIS_LIST |
列表对象 |
REDIS_HASH |
哈希对象 |
REDIS_SET |
集合对象 |
REDIS_ZSET |
有序结合对象 |
对于Redis
数据库保存的键值对来说,键总是一个字符串对象,而值则可以是String
, List
, Hash
, Set
, ZSet
对象中的其中一个。
TYPE
命令:当我们对一个数据库键执行TYPE
命令时,命令返回的结果为数据库键对应的值对象的类型,而不是键对象的类型
8.1.2 编码和底层实现
对象的ptr
指针指向对象的底层实现数据结构,而这些数据结构由对象的encoding属性决定。
encoding
属性记录了对象所使用的编码,也就是说这个对象上用了什么数据结构作为对象的底层实现,属性如下:
编码常量 | 编码所对应的底层数据结构 |
---|---|
REDIS_ENCODING_INT |
long 类型的整数 |
REDIS_ENCODING_EMBSTR |
embstr 编码的简单动态字符串 |
REDIS_ENCODING_RAW |
简单动态字符串 |
REDIS_ENCODING_HT |
字典 |
REDIS_ENCODING_LINKEDLIST |
双端列表 |
REDIS_ENCODING_ZIPLIST |
压缩列表 |
REDIS_ENCODING_INTSET |
整数集合 |
REDIS_ENCODING_SKIPLIST |
跳跃表 |
每种类型的对象都至少使用了两种不同的编码
类型 | 编码 | 对象 |
---|---|---|
REDIS_STRING |
REDIS_ENCODING_INT |
使用整数值实现的字符串对象 |
REDIS_STRING |
REDIS_ENCODING_EMBSTR |
使用embstr编码的简单动态字符串实现的字符串对象 |
REDIS_STRING |
REDIS_ENCODING_RAW |
使用简单动态字符串实现的字符串对象 |
REDIS_LIST |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的列表对象 |
REDIS_LIST |
REDIS_ENCODING_LINKEDLIST |
使用双端列表实现的列表对象 |
REDIS_HASH |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的哈希对象 |
REDIS_HASH |
REDIS_ENCODING_HT |
使用字典实现的哈希对象 |
REDIS_SET |
REDIS_ENCODING_INTSET |
使用整数集合实现的集合对象 |
REDIS_SET |
REDIS_ENCODING_HT |
使用字典实现的集合对象 |
REDIS_ZSET |
REDIS_ENCODING_ZIPLIST |
使用压缩列表实现的有序集合对象 |
REDIS_ZSET |
REDIS_ENCODING_SKIPLIST |
使用跳跃表实现的有序集合对象 |
OBJECT ENCODING
命令:可以查看一个数据库键的值对象的编码:
通过encoding
属性来设定对象所使用的编码。而不是为特定类型的对象关联一种固定的编码,极大地提升了Redis
的灵活性,因为Redis可以根据不同的使用场景来为一个对象设置不同的编码,从而优化对象在某一场景下的效率。
8.1.3 Key(键)命令
1. DEL
DEL key [key ...]
删除给定的一个或多个key
不存在的key
会被忽略
2. DUMP
DUMP key
序列化给定key
,并返回被序列化的值,使用RESTORE
命令可以将这个值反序列化为Redis
键
序列化生成的值有以下几个特点:
- 带有64为的校验和,用于检测错误,
RESTORE
在进行反序列化之前会先检查校验和。 - 值的编码格式和RDB文件保持一致。
- RDB版本会编码在序列化值当众,如果因为Redis的版本不同造成RDB格式不兼容,那么Redis会拒绝为这个值进行反序列操作。
序列化的值不包括任何生存时间信息。
3. EXISTS
EXISTS key
检查给定的key
是否存在
4. EXPIRE
EXPIRE key seconds
为给定的key
设置生存时间,当key
过期时,会被自动删除。
5. EXPIREAT
EXPIREAT key timestamp
EXPIREAT
的作用和EXPIRE
类似,都用于为key
设置生存时间
不同在于EXPIREAT
命令接受的时间参数是UNIX
时间戳
6. KEYS
KEYS pattern
查询所有符合给定模式pattern
的key
KEYS *
匹配数据库中所有的key
KEYS h?llo
匹配hello
, hallo
和hxllo
等
KEYS h*llo
匹配hllo
, heeeeello
等
KEYS h[ae]llo
匹配hello
和hallo
,但不匹配hillo
。
7. MIGRATE
MIGRATE host port key destination-db timeout [COPY] [REPLACE]
将key
原子性地从当前实例传送到目标实例的指定数据库上,一旦传送成功,key
保证会出现在目标实例上,而当前实例上的key
会被删除。
这个命令是一个原子操作,它在执行的时候会阻塞进行迁移的两个实例,直到以下任意结果发生:迁移成功,迁移失败,等待超时。
命令的内部实现是这样的:它在当前实例对给定key
执行DUMP
命令 ,将它序列化,然后传送到目标实例,目标实例再使用RESTORE
对数据进行反序列化,并将反序列化所得的数据添加到数据库中;当前实例就像目标实例的客户端那样,只要看到RESTORE
命令返回OK
,它就会调用DEL
删除自己数据库上的key
。
timeout
参数以毫秒为格式,指定当前实例和目标实例进行沟通的最大间隔时间。这说明操作并不一定要在timeout
毫秒内完成,只是说数据传送的时间不能超过这个timeout
数。
MIGRATE
命令需要在给定的时间规定内完成IO
操作。如果在传送数据时发生IO
错误,或者达到了超时时间,那么命令会停止执行,并返回一个特殊的错误:IOERR
。
当IOERR
出现时,有以下两种可能:
-
key
可能存在于两个实例 -
key
可能只存在于当前实例
唯一不可能发生的情况就是丢失key
,因此,如果一个客户端执行MIGRATE
命令,并且不幸遇上IOERR
错误,那么这个客户端唯一要做的就是检查自己数据库上的key
是否已经被正确地删除。 -
COPY
:不移除源实例上的key
。 -
REPLACE
:替换目标实例上已存在的key
。
8. MOVE
MOVE key db
将当前数据库的key
移动到给定的数据库db
当中。
如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key
,或者key
不存在于当前数据库,那么MOVE
没有任何效果。
因此,也可以利用这一特性,将MOVE
当作锁(locking
)原语(primitive
)。
9. OBJECT
OBJECT subcommand [arguments [arguments]]
OBJECT
命令允许从内部察看给定key
的Redis
对象。
OBJECT
命令有多个子命令:
OBJECT REFCOUNT <key>
返回给定key
引用所储存的值的次数。此命令主要用于除错。
OBJECT ENCODING <key>
返回给定key
锁储存的值所使用的内部表示(representation
)。
OBJECT IDLETIME <key>
返回给定key
自储存以来的空闲时间(idle
, 没有被读取也没有被写入),以秒为单位。
10. PERSIST
PERSIST key
移除给定key
的生存时间,将这个key
从『易失的』(带生存时间key
)转换成『持久的』(一个不带生存时间、永不过期的key
)。
11. PEXPIRE
PEXPIRE key milliseconds
这个命令和EXPIRE
命令的作用类似,但是它以毫秒为单位设置key
的生存时间,而不像EXPIRE
命令那样,以秒为单位。
12. PEXPIREAT
PEXPIREAT key milliseconds-timestamp
这个命令和EXPIREAT
命令类似,但它以毫秒为单位设置key
的过期unix
时间戳,而不是像EXPIREAT
那样,以秒为单位。
13. PTTL
PTTL key
这个命令类似于TTL
命令,但它以毫秒为单位返回key
的剩余生存时间,而不是像TTL
命令那样,以秒为单位。
14. RANDOMKEY
RANDOMKEY
从当前数据库中随机返回(不删除)一个key
。
15. RENAME
RENAME key newkey
将key
改名为newkey
。
当key 和
newkey相同,或者
key不存在时,返回一个错误。 当
newkey已经存在时,
RENAME`命令将覆盖旧值。
16. RENAMENX
RENAMENX key newkey
当且仅当newkey
不存在时,将key
改名为newkey
。
当key
不存在时,返回一个错误。
17. RESTORE
RESTORE key ttl serialized-value [REPLACE]
反序列化给定的序列化值,并将它和给定的key
关联。
18. SORT
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]
返回或保存给定列表、集合、有序集合key
中经过排序的元素。
排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。
19. TTL
TTL key
以秒为单位,返回给定key
的剩余生存时间(TTL
, time to live
)。
20. TYPE
TYPE key
返回key
所储存的值的类型。
返回值:
-
none
(key
不存在) -
string
(字符串) -
list
(列表) -
set
(集合) -
zset
(有序集) -
hash
(哈希表)
21. SCAN
SCAN cursor [MATCH pattern] [COUNT count]
网友评论