今天分享下redis支持的一些数据结构
字符串
- 字符串类型是Redis最基础的数据结构。首先键都是字符串类型,而且 其他几种数据结构都是在字符串类型基础上构建的,所以字符串类型能为其 他数据结构的学习奠定基础
- 字符串类型的值实际可以 是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能 超过512MB
- setnx和setxx可以作为分布式锁的一种 实现方案
- 可以使用mget这样的批量命令
- 字符串类型的内部编码有3种(根据当前值的类型和长度决定使用哪种内部编码实现):
- int:8个字节的长整型
- embstr:小于等于39个字节的字符串
-raw:大于39个字节的字符串
哈希
- 键值本身又是一个键值对结构
- 在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。 如果开发人员只需要获取部分field,可以使用hmget,如果一定要获取全部 field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型
- 内部编码:
- ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的 结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀
- hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使 用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而 hashtable的读写时间复杂度为O(1)
列表
- 用来存储多个有序的字符串
- 列表类型有两个特点:第一、列表中的元素是有序的,这就意味着可以 通过索引下标获取某个元素或者某个范围内的元素列表,第二、列表中的元素可以是重复的。
- 内部编码:
- ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置 (默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时 (默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使 用
- linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用 linkedlist作为列表的内部实现
- 列表的使用场景很多,如
- lpush+lpop=Stack(栈)
- lpush+rpop=Queue(队列)
- lpsh+ltrim=Capped Collection(有限集合)
- lpush+brpop=Message Queue(消息队列)
集合
- 是用来保存多个的字符串元素,和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素
- 内部编码:
- intset(整数集合):当集合中的元素都是整数且元素个数小于set-max- intset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实 现,从而减少内存的使用
- hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使 用hashtable作为集合的内部实现
- 使用场景推荐:
- sadd=Tagging(标签)
- spop/srandmember=Random item(生成随机数,比如抽奖)
- sadd+sinter=Social Graph(社交需求)
有序集合
- 保留了集合不能有重复成员的特性,有序集合中的元素可以排序,给每个元素设置一个分数(score)作为排序的依 据
- 内部编码:
- ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist- entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配 置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用
- skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作 为内部实现,因为此时ziplist的读写效率会下降
- 有序集合比较典型的使用场景就是排行榜系统
Bitmaps
- Bitmaps本身不是一种数据结构,实际上它就是字符串(如图3-10所 示),但是它可以对字符串的位进行操作
- Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符 串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的 每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量
HyperLogLog
- HyperLogLog并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数 的统计,数据集可以是IP、Email、ID等
特别说明
- 可以使用类似setnx和setxx实现分布式锁
- 批量操作使用mget之类的批量命令减少网络开销
- redis是单线程模式,类似keys, hgetall类似的命令可能会阻塞redis,生产环境尽量不用
- redis命令参考