文章目录
关于Redis
Redis(Remote Dictionary Service,远程字典服务)是一种内存数据库,也被称为KV数据库、数据结构数据库。
Redis常用作数据的缓存,缓存热点数据,减少数据库的压力。
完整的Redis命令查看:Redis命令中心。
key-value数据对象
Redis对外的接口总是通过键key来获取数据值value。
Redis对外提供了5种数据对象来存储key-value:string、list、hash、set以及zset。
应用场景
- 缓存热点数据,减少数据库压力(hash)
- 记录朋友圈点赞数、评论数和点击数(hash)
- 记录朋友圈说说列表(排序),便于快速显示朋友圈(zset或list)
- 记录文章的标题、摘要、作者和封面,用于列表页展示(hash)
- 记录朋友圈的点赞用户ID列表,评论ID列表,用于显示和去重计数(zset)
- 如果朋友圈说说ID是整数id,可使用redis来分配朋友圈说说id(计数器)(string)
- 通过集合(set)的交并差集运算来实现记录好友关系(set)
- 游戏业务中,每局战绩存储(list)
对象的基础数据结构及其选择
Redis将key通过siphash函数转化为哈希值,然后以该值为索引在hashtable数组中找到对应的key-value对象,此时并没有直接得到value值,因为对于不同的对象,其内部value的存储形式是不一样的(或者说value是按不同的形式进行编码的),还需要到具体的基础数据结构中去检索value值。此处的数据结构包含字典、双向链表、压缩列表、跳表、整数数组及动态字符串等等。这个检索的过程大致如下图所示,包括两个层次,第一个层次就是前面讲的通过hashtable去找到key-value对象,第二个层次就是在具体的数据结构中找到value:
我个人理解这样设计的好处就是将对外提供的数据操作接口统一成key-value的形式,内部再根据不同的数据形式和数据结构进行不同方式的数据编码。
数据结构的选择以及选择的条件如下表所示:
注意:Redis中的多数字符串是简单动态字符串(Simple Dynamic String,SDS),它是一种二进制安全字符串,可以存储图片等二进制数据。一般来说key和value都是以SDS形式存储。
数据对象及其操作命令
1 string
动态字符串,实质是字符数组的封装,最大长度512M。可扩容,字符串长度小于1M时,每次加倍扩容;超过1M时,每次只多扩1M。
1.1 基础数据结构
- 字符串长度小于等于 20 且能转成整数,则使用
int
存储; - 字符串长度小于等于 44,则使用
embstr
存储; - 字符串长度大于 44,则使用
raw
存储;
embstr
是专门用于保存短字符串的一种优化编码方式,与raw
字符串几乎相同,都使用对象描述符结构体redisObject
+sds描述符结构体sdshdr
来表示一个字符串对象(字符串内容的空间紧随sdshdr
其后),只不过raw
字符串会分两次来为二者分配内存,而embstr
仅调用一次内存分配来为整体分配一块连续的空间,好处是减少内存分配和释放的次数,也更容易利用缓存。
redis的内存分配器在数据长度小于等于64字节时,认为是小字符串,而在大于64字节时,认为是大字符串。以此为分界Redis将对数据做不同的处理。然而上面对string对象不同存储方式的分界却为44字节。这是与Redis内部描述对象的结构体redisObject
以及描述string对象的结构体sdshdr
大小有关,这些结构体会使用19字节空间,同时字符串要给\0
预留一个字节,所以就要占用掉20个字节,对