Redis-5种基础数据结构

Redis基础数据结构

知识整理源于《Redis深度历险 核心原理与应用实践》这本书

Redis 有的数据结构都以 唯一的 key 字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结构的差异就在于 value 结构不样。

下面介绍redis几种基础的数据结构。

一、String(字待串)

字符串 tring Redis 最简单的数据结构,它的内部表示就是一 个字符数组。Redis 的字符串是动态字符串,是可以修改的字符串,内部结构的实现类似于 Java ArrayList ,采用预分配冗余空间的方式来减少内存的频繁分配,内部为当前字符串分配的实际空间 capacity 般要高于实际字符串长度 len 。当字符 串长度小于 1MB 肘,扩r容都是加倍现有的空间 。如果字符串长度超过 1MB ,扩容时 一次只会多扩1MB 的空间 。需要注意的是字符串最大长度为 512MB。

介绍几种字符串常用的命令:

set   [key]  [value]   给指定key设置值(set 可覆盖老的值)

get  [key]   获取指定key 的值

del  [key]   删除指定key

exists  [key]  判断是否存在指定key

mset  [key1]  [value1]  [key2]  [value2] ...... 批量存值

mget  [key1]  [key2] ......   批量取值

expire [key]  [time]    给指定key 设置过期时间  单位秒

setex    [key]  [time]  [value]  等价于 set + expire 命令组合

setnx  [key]  [value]   如果key不存在则set 创建,否则返回0

incr   [key]           如果value为整数 可用 incr命令每次自增1

incrby  [key] [number]  使用incrby命令对整数值 进行增加 number

二、list(列表)

Redis 的列表相当于 Java 语言里面的 LinkedList 注意它是链表而不是数组。这 意味着 list 的插入和删除操作非常快,时间复杂度为 0(1 ),但是索引定位很慢,时间 复杂度为 O(n ),这点让人非常意外。如下图 表中的每个元素都使用双向 指针顺序,串起来可以同时支持前向后向遍历 当列表弹出了最后一个元素之后,该数据结构被自动删除,内存被回收。

Redis 的列表结构常用来做异步队列使用 将需要延后处理的任务结构体序列化 成字符串,塞进 Redis 的列表,另 个线程从这个列表中轮询数据进行处理。

Redis 的列表数据结构既可以做队列也可以做栈使用。

【快速列表】

如果再深入一点,你会发现 Redis 底层存储的不是个简单的 linkedlist ,而是 之为“快速链表 ( quicklist )的一个结构。 首先在列表元素较少的情况下,会使用一块连续的内存存储,这个结构是zip list ,即压缩列表。它将所有的元素彼此紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成 quicklist 。因为普通的链表需要的附加指针空间 太大,会浪费空间,还会加重内存的碎片化,比如某普通链表里存的只是 int 类型的 数据,结构 还需要两个额外的指针 prev next 。所以 Redis 将链表和 ziplist 结合起来组成了 quicklist ,也就是将多个 ziplist 使用双向指针串起来使用。如图 1-6 所示, quicklist 满足了快速的插入删除性能,又不会出现太大的空间冗余。

 

介绍几种list操作的常用命名:
rpush  [key] [value1] [value2] ......    链表右侧插入

rpop    [key]  移除右侧列表头元素,并返回该元素

lpop   [key]    移除左侧列表头元素,并返回该元素

llen  [key]     返回该列表的元素个数

lrem [key] [count] [value]  删除列表中与value相等的元素,count是删除的个数。 count>0 表示从左侧开始查找,删除count个元素,count<0 表示从右侧开始查找,删除count个相同元素,count=0 表示删除全部相同的元素

(PS:   index 代表元素下标,index 可以为负数, index= 表示倒数第一个元素,同理 index=-2 表示倒数第二 个元素。)

lindex [key] [index]  获取list指定下标的元素 (需要遍历,时间复杂度为O(n))

lrange [key]  [start_index] [end_index]   获取list 区间内的所有元素 (时间复杂度为 O(n))

ltrim  [key]  [start_index] [end_index]   保留区间内的元素,其他元素删除(时间复杂度为 O(n))

三、hash (字典)

Redis 的字典相 当于 Java 语言里面的 HashMap ,它 内部存储了很多键值对。实现结构上与 Java HashMap 是样的,都是“数组 +链表”二维结构。如下图所示,第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。

Redis采用渐进式rehash。渐进式 rehash 会在 rehash 的同时 保留新旧两个 hash 结构 ,查询时查 两个 hash 结构 然后在后续的定时任务以及 hash 操作指令中 循序 渐进地将 hash 的内容 一点点地迁移到新 hash 结构中。当搬迁完成了,就会使用 新的 hash 结构取而代之。

渐进式rehash的好处:扩容时需要对hash结构里的数据重新rehash,如果数据量过多,一次性rehash特表耗时,redis 单进程而又对性能要求特别高,为了提高性能,不堵塞,采用了渐进式rehash方式。

介绍几种hash常用的操作命令:

hset  [key]  [field] [value]    新建字段信息

hget  [key]  [field]    获取字段信息

hdel [key] [field]  删除字段

hlen  [key]   保存的字段个数

hgetall  [key]  获取指定key 字典里的所有字段和值 (字段信息过多,会导致慢查询 慎用:亲身经历 曾经用过这个这个指令导致线上服务故障)

hmset  [key]  [field1] [value1] [field2] [value2] ......   批量创建

hincr  [key] [field]   对字段值自增

hincrby [key] [field] [number] 对字段值增加number

四、set(集合)

Redis 的集合相当于 Java 语言里面的 HashSet ,它内部的键值对是无序的、唯一 的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL 当集合中最后一个元素被移除之后,数据结构被自动删除,内存被回收。

set 结构可以用来存储在某活动中中奖的用户 ID ,因为有去重功能,可以保证同 一个用户不会中奖两次。

介绍几种set的常用命令:
sadd  [key]  [value]  向指定key的set中添加元素

smembers [key]    获取指定key 集合中的所有元素

sismember [key] [value]   判断集合中是否存在某个value

scard [key]    获取集合的长度

spop  [key]   弹出一个元素

srem [key] [value]  删除指定元素

五、zset(有序集合)

它类似于 Java SortedSet HashMap 的结合体, 方面它是个 set ,保证 了内部 value 的唯性,另方面它可 以给每个 value 赋予一个 score ,代表 这个 value 的排序权重。它的内部实现 用的是一种叫作“跳跃列表”的数据 结构。

zset 可以用来存储粉丝列表, value 值是粉丝的用户 ID, score 是关注时间。我们可以对粉丝列表按关注时间进行排序。 zset 还可以用来存储学生的成绩, value 值是学生的 ID, score 是他的考试成绩。 我们对成绩按分数进行排序就可以得到他的名次。

【跳跃列表】

跳跃列表支持链表的快速插入的特性,也同时具有数组的快速定位特性。简单描述是最下面一层所有元素按顺序串联再一起,从下面一层抽取部分元素组成上一级,依次类推,当查询元素时,从最上面一级来查询,通过下沉找到最下层元素的位置进行相关操作。

介绍几种zset有序集合的常用操作命令:

zadd [key] [score] [value] 向指定key的集合中增加元素

zrange [key] [start_index] [end_index] 获取下标范围内的元素列表,按score 排序输出

zrevrange [key] [start_index] [end_index]  获取范围内的元素列表 ,按score排序 逆序输出

zcard [key]  获取集合列表的元素个数

zrank [key] [value]  获取元素再集合中的排名

zrangebyscore [key] [score1] [score2]  输出score范围内的元素列表

zrem [key] [value]  删除元素

zscore [key] [value] 获取元素的score

posted @ 2020-01-06 15:57  晋级在路上  阅读(141)  评论(0编辑  收藏  举报