文章目录
- 1 为什么使用Redis
- 2 为什么Redis这么快
- 3 Redis命令参考
- 4 Redis的数据结构
- 4.1 string(字符串)
- 4.2 list(列表)
- 4.3 hash(字典)
- 4.4 set(集合)
- 4.5 zset(有序列表)
- 5 过期时间
- 参考
1 为什么使用Redis
- Redis的性能高,官方宣称能支持10W QPS。
- Redis的数据类型丰富,能够支撑很多的业务需求使用场景。
- Redis支持持久化、复制、哨兵、集群等高级特效,可靠性高。
2 为什么Redis这么快
- Redis的数据存储在内存中,并发能力强。
- Redis的数据结构非常精简。
- Redis采用分片存储,不会因为数据的增长而严重影响性能。
- Redis通过单线程IO多路复用的方式,减少了线程上下文切换等消耗。
注意:关于IO多路复用,个人推荐一篇写的非常好的博客:select、poll、epoll之间的区别
3 Redis命令参考
推荐一个Redis命令参考手册
4 Redis的数据结构
此处的数据结构介绍写的比较精简,推荐大家阅读以下《Redis深度历险:核心原理和应用实践》这本书,里面有不仅有详细的介绍,还有示例演示。
4.1 string(字符串)
string相当于Java中的ArrayList,即数组实现。string是Redis最基础的数据结构,Redis的key都是字符串类型,不同数据结构的差异是体现在value中。
Redis在增长字符串时采用预分配冗余空间的方式来减少内存的频繁分配,每次扩容会多扩1 MB,字符串最大长度为512 MB。在缩短时采用惰性空间释放的方式,即不立即使用内存重分配来回收缩短后多出来的字节, 而是使用free属性将这些字节的数量记录起来,并等待将来使用。
4.2 list(列表)
list相当于Java中的LinkedList,这时候已经不是链表而是数组了。所以和链表一样,插入和删除速度非常快,时间复杂度仅为O(1),但是index速度很慢,需要遍历查询,时间复杂度为O(n)。列表结构常常被用来做异步队列使用。
当列表弹出最后一个元素之后,就会被自动删除,内存被回收。
就如同Hashmap当链表长度大于等于7就会转换为红黑树一样,Redis的列表也并非单纯的linkedlist结构。当列表元素较少的情况下是使用一块连续的内存存储,此结构称为ziplist,也叫压缩列表,当数据量较多时会转化为quicklist。这是因为普通的列表需要的附加指针空间太大,会比较浪费空间,而且会加重内存的碎片化。
4.3 hash(字典)
hash相当于Java中的HashMap,是无序字典。其内部结构和HashMap一致,第一维为数组,第二维为链表。
但是在扩容时rehash的过程上和HashMap有所不同,因为HashMap在rehash时是直接一次性rehash,会停止当前线程的读写任务,过程非常耗时。而Redis采用了渐进式rehash策略,保证了当前线程可以继续执行读写任务。渐进式rehash是创建一个扩容后新hash,同时保留旧的hash,查询时会同时从查询两个hash,然后会开启一个任务循序渐进地将旧hash的内容一点点迁移到新的hash中。当hash移除了最后一个元素后,就会被自动删除,内存被回收。
4.4 set(集合)
set相当于Java中的HashSet,它内部的键值对是无序、唯一的,可以用来做去重功能,set所有的value都是NULL。当set中最后一个元素移除后,就会被自动删除,内存被回收。
4.5 zset(有序列表)
zset是Java中SortSet和HashMap的结合体,他内部的键值对是有序、唯一的。“唯一”是因为zset也属于set,“有序”是因为它可以给每一个value赋予一个score,通过value来排序,其内部实现使用了一种叫“跳跃列表”的数据结构。当zset中最后一个元素移除后,就会被自动删除,内存被回收。
5 过期时间
- 所有的数据结构都可以设置过期时间,是以倒计时的方式,如果时间到了,整个对象就会被删除,内存被回收。
- 如果一个字符串设置了过期时间,但是又被调用set方法做了修改,那么她的过期时间会失效。
参考
- 电子工业出版社,钱文品 著,《Redis 深度历险:核心原理与应用实践》。