redis数据结构汇总

关于key:

1.key不要太长,尽量不要超过1024字节,这不仅消耗内存,而且会降低查找的效率

2.key也不要太短,太短的话,key的可读性会降低

3.在一个项目中,key最好使用统一的命名模式,例如user:10000:passwd。

1.字符串(String终究是我扛下了所有):

redis中的键都是字符串对象,而且其他几种数据结构都是在字符串对象基础上构建的。字符串对象的值可以是字符串(Json/XML)、数字(int/double等)或二进制(图片视频音频等),最大不能超过512MB。字符串对象的内部编码有3种 :int(字符串对象保存的是int ,并且可以用long表示)、raw(字符串对象保存的字符串值长度>32字节)和embstr(<=32字节)。Redis会根据当前值的类型和长度来决定使用哪种编码来实现。

应用场景:

①Redis经常作为缓存层来缓存热点数据。先去redis读取,没有再去数据库。不过要注意一些问题:缓存穿透、雪崩以及缓存更新问题等。

②计数器:经常可以被用来做计数器,如微博的评论数、点赞数、分享数,抖音作品的收藏数,京东商品的销售量、评价数等。限速器:如验证码接口访问频率限制,会限制用户每分钟获取验证码的频率。分布式ID:由于Redis自增自减操作的原子性,也经常在分布式系统中用来生成唯一的订单号、序列号等。

③分布式系统共享session:用户的请求可能分发到不同的服务器上,从而导致用户登录保存Session是在一台服务器上,而读取Session是在另一台服务器上因此会读不到Session。

④二进制数据的存储(图片视频音频等)。

2.列表(List栈和队列我都行):

存储一组有序的、可重复的数据。因有序性,它可以获取指定范围的列表元素,可以0(1)时间复杂度获取指定索引下标的元素

①当列表的元素个数<512并且每个元素的值<64字节时: List对象使用ziplist(压缩列表)数据结构,否则用linkedlist作为内部实现。

②Redis 3.2版本开始使用quicklistzipList和linkedList的混合体,代替了ziplist和linkedlist(双向循环列表),调高了内存管理效率。

改用quicklist原因:链表的附加空间相对太高prev和next指针就要占去16个字节(64位系统的指针是8个字节), 另外每个节点的内存都是单独分配(加剧内存的碎片化),影响内存管理效率。

应用场景:

①列表对象有序——>做文章、商品等列表的存储。

②队列:lpush和rpop (查询并删除)第一个元素,消息队列。

③栈:1push 1pop

3. 哈希(Hash存储对象我也行):key : map

①两种实现方式ziplist(压缩列表), hashtable(哈希表)

②数据量小的时候:字典中保存的键值大小< 64 字节 并且 字典中键值对个数<512个。否则用hashtable来实现哈希对象。

应用场景:

①字符串对象的很多功能使用哈希对象可以实现。如缓存用户信息的时候,使用Redis哈希对象存储,简单直观,如果使用合理可以减少内存空间的使用。缺点是hashtable会消耗更多内存。②购物车、计数器等功能。

4. 集合(Set标签系统我在行)

内部编码两种: 元素都是整数 且 元素个数<512个使用intset编码,否则使用hashtable

应用场景:

无序、不可重复、支持并交差——>可以用于标签系统。

②SPOP(随机移除并返回集合中一个或多个元素)和 SRANDMEMBER(随机返回集合中一个或多个元素)命令——>可以实现抽奖系统。

5. 有序集合(ZSet排名我最棒)

Set + score(分值), ZSet元素不重复但是分值可以重复,可以用于排序。

存储结构:数据较少时,元素个数<128个;元素长度<64字节。用ziplist存储。否则用skiplist(跳表)存储。

应用场景:

①排行榜:网站用户点赞、播放排名、电商系统中商品销量排名等。

6.压缩列表(zip1ist):是列表和哈希的底层实现之一。

    列表只包含少量列表项,并且每个列表项要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做List的底层实现

    哈希只包含少量键值对, 并且每个键值对的键和值要么就是小整数值,要么就是长度比较短的字符串,那么Redis就会使用压缩列表来做Hash的底层实现

7. 跳跃表(skiplist):单链表 + 多级索引

如果一个有序集合元素数量比较多 或 元素成员是比较长的字符串时,Redis 就会使用跳跃表作为有序集合健的底层实现

特点:

①跳跃表在链表的基础上增加了多级索引提升查找的效率,但其是一个空间换时间的方案,必然会带来一个问题-索引是占内存的。原始链表中存储的有可能是很大的对象,而索引结点只需要存储关键值和几个指针优势会放大,缺点可忽略

②跳跃表由zskiplistzskiplistnode两个结构组成,其中 zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistnode则用于表示跳跃表节点(层level、后退指针backward、分值score、成员对象oj)

③Redis每个跳跃表节点的层高都是1至32之间的随机数

④在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的跳跃表中的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。(分值可以重复,但元素不能重复)

8.快速列表(quicklist):

Redis 3.2版本以后提出的,是 zipList 和 linkedList 的混合体,相对于链表它压缩了内存即有链表的双向性质,又有ziplist高效的内存使用率。一个quicklistnode的数据由ziplist存储存储,新建一个ziplist就会新建一个quicklistnode节点。

插入

①头结点的头部或尾节点的尾部插入:如果头节点(或尾节点)上ziplist大小没有超过限制, 那么新数据被直接插入到ziplist中(调用 ziplistPush )。否则新创建一个quicklistNode节点(对应地也会新创建一个ziplist)

②中间插入:

1.没有超过插入位置所在ziplist的限制,直接插;

2.插入位置所在的ziplist超过了限制,并且插在ziplist两端,相邻quicklist的ziplist大小没有超过限制,插入相邻quicklist的ziplist

3.插入位置所在的ziplist超过限制,并且在ziplist两端,相邻的quicklist的ziplist大小超过了限制,新建一个quicklist然后插入到新建的quicklist的ziplist中

4.插入位置所在的ziplist超过限制,并且在ziplist中间插入,需要把ziplist分裂为两个节点,然后再在其中一个节点插入。

②删除

③查找

知道查找数据的index。我们需要先根据node的个数,找到对应的ziplist,调用ziplist的index就能成功找到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值