Redis的数据结构
概述,Redis中的数据结构
Redis有5中基础数据结构,分别为:string(字符串)、list(列表)、hash(字典)、set(集合)、和zset(有序集合)
string(字符串)
string的结构
字符串string的内部是一个字符数组,是二进制安全的。
Redis所有的数据结构都以唯一的key字符串作为名称,然后通过这个唯一的key值来获取相应的value数据。不同类型的数据结构的差异就在于value的结构不一样。
Redis的字符串是动态字符串,是可以修改的字符串,内部结构的实现类似于Java的ArrayList,采用预分配空间的方式来减少内存的频繁分配。
1. Redis虽然使用C语言实现的,但是并没有使用’\0’作为字符串的结尾,而是使用一个len变量来记录字符串的长度,提高了查询速度。
2. 如图所示,Redis内部为当前字符串分配的实际空间capacity一般要高于实际字符串长度len。
3. 当字符串长度小于1MB时,扩容加倍现有的空间。
4. 如果字符串长度小于1MB,扩容是一次只会多扩1MB的空间。
5. 字符串的最大长度为512MB。
string的常用方法
- 键值对,相当于Map的Key和Value,支持简单的增删改查操作
- 批量键值对,可以对多个字符串进行批量读写
- 可以对key设置过期时间,到时间会被自动删除,常用来空值缓存的失效时间,实例中设置为10s后过期
setex key1 10 expire_test #10s后过期,相当于set+expire
setnx key1 expire_test #如果key1不存在就执行set操作,存在set创建不成功
- 计数,如果value是一个整数,还可以对它进行自增操作。范围在signed long的最大值和最小值之间。超出范围会报错
list(列表)
list的结构
- Redis的列表相当于Java语言的LinkedList,是一个双向链表。插入和删除的时间复杂度为O(1),查询的时间复杂度为O(n)。
- 当列表弹出了最后一个元素,该数据结构被自动删除,内存被回收
- Redis的列表常用来做异步队列使用。
list的常用方法
- 右边进左边出:队列,常用于消息队列和异步逻辑处理,确保访问元素的顺序性
- 右边进右边出:栈
- 慢操作
lindex lang 2 #相当于LinkedList的get(int index)方法
ltrim lang start_index end_index #保留区间内的元素
- 快速列表——quicklist
ziplist:在列表元素较少时,会使用一块连续的内存存储,这个结构解释ziplist,即压缩列表。当数据量较多时会改成quicklist。ziplist作为双向链表的节点。
hash(字典)
hash的结构
数组+链表,类似Java的HashMap。不同的是,Redis字典的值是能是字符串,并且Redis采用渐进式rehash策略。
渐进式rehash策略:在rehash的同时,保留两个hash结构。查询时会同时查询两个hash结构,然后在后续的定时任务以及hash操作指令中,循序渐进的将旧hash的内容一点点的迁移到新的hash结构中,全部迁移后就会采用新的hash结构代替旧的hash结构。
当hash移除了最后一个元素后,该数据结构会被删除,内存会被回收。
hash的常用方法
set(集合)
set的结构
相当于Java的HashSet,内部的键值对无序、唯一,字典的所有value都是null。
最后一个元素被移除后,内存会被回收。
具有去重功能
set的常用方法
smembers key #获取集合的全部值
sismember key value #判断key集合里有没有value
scard key #获取key集合的长度
spop key #弹出一个元素
zset(有序列表)
zset的结构
类似于Java中SortedSet和HashMap的结合体。
内部value唯一。
为每个value赋予一个score,代表这个value的排序权重。
内部实现是一种叫做跳跃列表的数据结构。
最后一个元素被移除后,内存会被回收。
zset的常用方法
zrange key start_index end_index #获取范围内的值
zrevrange key start_index end_index #倒序获取范围内的值
zscore key "value" #获取value对应的score值
zcard key #集合的长度
zrank key "value" #value的排名
zrangebyscore key startScore endScore #获取startScore-endScore的value,inf——无穷大
zrem key "value" #删除value