redis深度历险 pdf_五分钟了解Redis五种基础数据结构

最近又重新学习了下redis相关的知识,在这里做下分享,我们在实际工作中最常用的还是它的5种基础数据结构,今天不介绍这5种数据结构的基本语法,主要简单的介绍下它们的底层结构还有使用场景。

dbcab7dbde4300307e9dd40bfb996518.png b832f1c3464ba09300acc26c0dfff131.png

5种基础数据结构

+

String

de182b9d376959bc6d04a48b98cb1f56.png 58c7b897f49ed97b728a753a1a7e58c0.png 710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

String是Redis最简单的数据结构,它的内部结构表示就是一个字符数组,字符串应用非常广泛,最常见的是缓存用户信息。我们将用户信息结构体使用JSON序列化成字符串,然后将字符串存入到Redis来缓存。

Redis的字符串是动态字符串,是可以修改的字符串,内部结构类似于java的ArrayList,采用预分配的方式减少内存的频繁分配,内部为当前字符串分配的内容一般高于实际的字符串长度。当需要扩容时会遵循如下规则:

当字符串长度小于1MB时,扩容都是加倍现有空间。

当字符串长度大于1MB时,扩容时一次只能多扩1MB的空间。

最终需要注意的是字符串最大长度为512MB。

710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

List

de182b9d376959bc6d04a48b98cb1f56.png 58c7b897f49ed97b728a753a1a7e58c0.png 710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

相当于java语言里面的LinkedList,它是链表而不是数组,这意味着list的插入和删除操作非常快,时间负责度是O(1),但是查找很慢,时间负责度是O(n)。列表中的每个元素都是用双向指针顺序,串起来可以同时支持前后向的遍历。

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

Redis的底层结构并不是简单的 LinkedList,而是称为“快速链表”(QuickList)的结构,

QuickList结构可以理解为由LinkedList与ZipList组合而成,所谓ZipList是在列表中元素很少的情况下,会使用一块连续的内存存储,这个结构就是ZipList。它所有的元素彼此紧挨着一起存储,分配的是一个连续的内存。

710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

hash

de182b9d376959bc6d04a48b98cb1f56.png 58c7b897f49ed97b728a753a1a7e58c0.png 710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

Redis中的hash相当于java语言中的HashMap。实现结构上都是“数组+链表”的二维结构。不同的是,Redis的字典的值只能是字符串,另外它们rehash的方式不一样。java的HashMap,当字典很大时,rehash是一个耗时的操作,需要一次性全部rehash,Redis为了追求高性能,不能堵塞服务,所以采用了渐进式rehash策略。也就是在rehash的同时保留新旧两个hash结构,查询时会同时查询两个hash结构,然后在后续的定时任务以及hash操作指令中,循序渐进地将就hash的内容一点点地迁移到新的hash结构中。

hash结构也可以用来存储用户信息。与字符串需要一次性全部序列化整个对象不同,hash可以对用户结构中的每个字段单独存储。这样我们在获取信息的时候就可以实现部分获取。在存储用户信息这个问题上与字符串相比hash的缺点是存储消耗更多一些。

710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

set

de182b9d376959bc6d04a48b98cb1f56.png 58c7b897f49ed97b728a753a1a7e58c0.png 710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

Redis中的set相当于java语言中的HashSet。它内部的键值对是无序的,唯一的。

字典中所有的value都是一个值NULL。

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

710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

zset

de182b9d376959bc6d04a48b98cb1f56.png 58c7b897f49ed97b728a753a1a7e58c0.png 710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

zset是Redis提供的最有特色的数据结构。类似java语言中的SortedSet和HashMap的结合体。一方面是一个set保证了value的唯一性,另一方面可以给每个value赋值一个score 。

zset可以用来存储学生的成绩,value是学生的ID,score是学生的成绩。还可以用来存储粉丝的列表,value的只是粉丝的ID,score是关注时间,这样可以对粉丝列表按关注事件进行排序。

710e9c0eef58d3ce5450b45412b60516.png 710e9c0eef58d3ce5450b45412b60516.png

总结

+

本文从内存结构上介绍了下Redis的五种基本结构,这些在实际工作中也许用不到,但是多一些了解还是有必要的。

参考资料

+

《Redis 深度历险 核心原理与应用实践》 钱文品/著

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值