Redis数据结构及各自适用场景

首先,redis 内部使用一个redisObject 核心对象来表示所有的 key 和 value,

redisObject 里包括这些属性:数据类型--type{String/hash/list/set/sorted set}    编码方式--encoding{raw/int/ht/zipmp/linkedlist/zaplist/intset} 数据指针---ptr  虚拟内存--vm 其他信息

下面具体介绍五种基本数据类型:

String:

value 值可以是字符型,也可以是数字。

其实没有什么特别的特点,正常的持久化那些基本操作,get   set  然后获取字符串长度,让字符串拼接等   如果是数字的话,可以incre  decre 计数功能

使用场景:比如计数功能,对字符串的一些存取功能等等 ,没有什么特别的功能。

 

 

hash:

值本身也是键值对的形式,无序的。可以添加,获取,移动元素,获取所有键值对,

使用场景:比如我们存的用户信息,一个用户id ,对应用户的身高,体重,姓名,等等n个信息,如果将这些信息作为一个整体存的话,在序列化反序列化的时候开销就比较大,如果   "id-姓名"---张三   "id-年龄"---25 "id-身高"---178  这样存储的话冗余量又太大

所有hash 就可以很好的用上,id就作为hash-key 找到这个用户信息,里面存的即 "姓名---值" “年龄--值” 这样的形式,实现存储修改获取部分数据。

 

List:

list 是用的一个双向链表,所以他是有顺序的,其特点就跟链表特点一样了,从链表的两端推入或者弹出元素,根据偏移量进行修剪[trim] ,读取单个或者多个元素,根据值查找或者移除元素。

使用场景:

  • 用户关注列表,新增一个关注在后面增加一个。
  • 异步队列使用【将需要延后处理的任务结构体序列化成字符串进redis 的列表,另一个线程从这个列表中轮询数据进行处理】。
  • 秒杀场景,秒杀前将本场秒杀的商品放到list中,因为list的pop操作是原子性的,所以即使有多个用户同时请求,也是依次pop,list空了pop抛出异常就代表商品卖完了.

     

     

set:

存储的是一堆不重复的无序数据,操作有添加,获取,移除单元素,检测是否存在元素,计算交集,并集,差集,从集合里随机获取元素等

set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

使用场景:不可重复,但是value可以为null ,用在一些去重的场景,比如用户只能参加一次活动,一个用户只能中一次奖等等去重场景。还有就是求交集并集补集的场景。

 

 

Sorted Set:

set基础上增加了的顺序的特性,每一个value加入的时候带有一个分值以表示权重,

部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

使用场景:各类排序场景:歌曲排行榜,播放次数,播放数,点赞数等等需要排序的场景。

 

扩展:除了以上五种数据结构,了解其他的数据结构吗?

布隆过滤器:bloom filter:判断是否存在(用户只能参加一次活动) 

1.向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash
运算,然后对位数组长度进行取模运算得到一个位置,这样添加一个key会在多个位加1。
2. 向布隆过滤器询问 key 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出来,看看位数组中这几个位置是否都为 1,只要有一个位为 0,那么说明布隆过滤器中这个 key 不存在

 

HyperLogLog:统计海量去重元素数量(统计页面uv):

16384个桶(16*1024),当一个元素到来时,它会散列(hash)到其中一个桶,每个桶占6bit. 

 

 位图:大量是否的统计(一年的打卡数量)

 

Stream:支持多播的可持久化的消息队列()

 

posted on 2020-05-18 14:13  靠自己的骨头长肉  阅读(343)  评论(0编辑  收藏  举报