Redis基本数据结构与常用场景
Redis(Remote Dictionary Server)是开源的基于内存的数据结构存储服务,通常用作数据库、缓存、消息队列、流引擎。Redis提供的主要数据结构包括字符串、哈希表、列表、集合、有序集合、位图、HLL、GEO等。
**0 Key
**
Redis的Key是二进制安全的,也就是说可以使用任何二进制序列作为Key。可以是普通的字符串,一张JPEG图片,甚至空串作为Redis的Key。
-
Key最大允许512M
-
Key不要过长(占内存,查询慢),也不要太短,最好保持良好的业务可读性,如user:1000:followers表示用户id=1000的关注列表
1 字符串
Redis中的Key或者字符串值均是sds(simple dynamic string),最大长度512M,sds兼容C语言字符串,大致结构如下
相比C语言字符串
-
常数时间获取长度
-
二进制安全,不再需要\0结尾,不会发生缓冲区溢出
-
len和alloc的数据类型根据存储类型调整,节省内存空间
常用场景
-
_简单KV存储,如session缓存,计数器
_ -
分布式锁,set nx px
-
分布式全局唯一ID(单线程命令执行)
2 列表
简单的string列表,插入顺序即存储顺序。Redis的列表底层采用链表实现,最大长度为2^32-1(超过40亿),头尾附近的插入、删除非常快速,访问中间元素较慢。
常用场景
-
最新列表,lpush+lrange
-
有限集合,lpush+ltrim
-
阻塞队列,lpush+brpop(先监听,先返回)
**3 哈希表
**
哈希表的值是string类型field和string类型的value,非常适合对象存储。每个哈希表可以存储2^ 32-1个field-value对。
哈希表是最接近关系数据库结构的数据类型,可以将数据库一条记录或某个JSON对象存放在Redis哈希表中,相比字符串,哈希表可以省去对象序列化与反序列化的开销,同时容量也更大。
4 集合
无序字符串集合,增加、删除可以在常数时间完成,与集合的大小无关。最大容量2^32-1,集合中元素具备不重复特性,集合间的交、并、差也可以非常快速的完成。
常用场景
-
独立访客IP
-
标签交集
-
随机抽签(无放回spop,有放回srandommember)
5 有序集合
与无序集合不同的是有序集合的每个元素关联了一个浮点score,内部采用跳表和哈希表实现,所有元素处于已序状态,因此范围访问非常快速。增加、更新、删除以较快的时间完成,复杂度O(logN),N为当前集合元素个数。需要注意的是,当score相同时,集合中的元素按字典序排列。
常用场景
-
topK实时排名榜,范围排名(K~M排名,K附近相似排名)
-
索引存储在Redis的其他数据,如zsort(value=id,score=age),可以快速查询某个age范围的全部id,并进一步获取user信息
**6 位图(BitMap)
**
在Redis中,位图并非真正意义上的数据类型,它是基于字符串的位操作集合。Redis字符串最大容量是512M(2^38位 × 2^101024 × 29512),那么位图的空间是232个bit(实际使用过程中,字符串的长度根据需要动态增加)。
准确计算0/1状态问题时,使用位图相对节约空间。例如用每一位表示当前用户是否在线(第10位是1表示id=10的用户在线),利用512M的空间,可以容纳超过40亿的用户量。
常用场景
-
各类0/1实时统计,如活跃用户,连续签到
-
如果数据集很大(位很多),可以将数据集进行切分(通常应避免单Key很大的位空间),一个简单的方式是数据集切为M个子集,子集的Key=位号/M,第N位在子集中的位置=位号%M
**7 HLL(HyperLogLogs)
**
HLL是一种用作基数统计的概率数据结构,最坏情况以12K内存(根据数据集大小调整),计算2^64个元素的基数且标准错误率小于1%。
HLL基于伯努利实验和极大似然估计
-
在概率论中,把在同样条件下重复进行试验的数学模型称为独立试验序列概型,进行n次试验,若任何一次试验中各结果发生的可能性都不受其它次试验结果发生情况的影响,则称这n次试验是相互独立的。特别的,当每次试验只有两个可能结果时,称为n重伯努利试验。例如连续抛硬币n次
-
在连续抛硬币试验中,正反面出现的概率相同。第 k次试验中出现正面的概率为1/2k,2k就是实验次数n的估计
-
类似的,将元素转换为2进制,数据的每一个位(bit)0和1出现的概率都是1/2。假设出现1的最高位是第k位,那么2^k就是数据集的估计
-
为了减少误差,Redis将数据进行分桶(每个桶6位),然后计算调和平均数
常用场景
- 计算独立UV,数据量较大但不需要存储原始数据
**8 GEO
**
Redis3.2提供了地理位置信息的支持,将位置信息<维度,经度,名称>添加到Key中,可以很容易的进行基于位置的检索,内部采用有序集合实现,score=GeoHash。
常用场景
- 基于地理位置的搜索,如附近的人

浙公网安备 33010602011771号