千里之行始于足下,我们先来看看redis的基础知识。
Redis有5中基本数据类型:字符串(string)、列表(list)、集合(set)、有序集合(zset)、字典(hash)。熟练掌握这5种基本数据结构也是最基本最重要的部分。
String(字符串)
字符串是redis中最简单的数据结构,Redis所有的数据结构都是以唯一key作为名称,然后通过唯一的key来获取相应的redis数据。不同类型的数据结构的差异就在于value的结构不一样。
字符串使用非常广泛,最常用的就是缓存用户信息,通常我们将用户信息使用JSON序列化成字符串,然后将序列化后的字符串塞进redis中,同样,取用户信息的时候再进行一次反序列化的过程。
Redis的字符串是动态字符串,内部结构类似java的ArrayList。采用与分配空间的方式肩上内存的频繁分配。内部为当前字符串实际分配的空间capacity,当字符串小于1M时,扩容都是加倍现有的空间,当超过1M时,扩容只会多扩1M的空间,需要注意的是字符串的最大空间是512M。
键值对
>set name QQsir
ok
>get name
"QQsir"
>exists name
(integer) 1
>del name
(integer) 1
>get name
(nil)
批量键值对
>mset name1 QQ name2 wx
>mget name1 name2
1)"QQ"
2)"wx"
过期和set命令扩展
>set name QQsir
>get name
"QQsir"
>expire name 5 #5秒后过期
...wait 5s
>get name
(nil)
计数
如果value是整数,可以对它自增操作
>set age 30
ok
>incr age
(integer)31
>incrby age 5
(integer)36
>incrby age -5
(integer)31
list(列表)
Redis列表相当于java语言里面的linkedlist,注意它是链表而不是数组。意味着list的插入和删除非常的快,时间复杂度O(1) ,但是索引定位很慢,时间复杂度O(n).
当列表弹出最后一个元素之后,该数据结果自动被删除,内存回收。
Redis的列表结构可以用来做异步队列,将延后处理的任务结构体序列成字符串放到Redis的列表中。另一个线程从这个列表中轮训获取数据进行处理。
左边进左边出
> rpush books python java golang
(integer) 3
> llen books
(integer) 3
> lpop books
"python"
> lpop books
"java"
> lpop books
"golang"
> lpop books
(nil)
右边进右边出:栈
> rpush books python java golang
(integer) 3
> rpop books
"golang"
> rpop books
"java"
> rpop books
"python"
> rpop books
(nil)
快速列表
ziplist.png如果再深入一些,list列表的底层是一个快速列表quicklist的数据结构。
当存储元素较少的时候,会分配一块连续的内存,这个结构是压缩列表ziplist,当元素过多,就需要使用quicklist,因为普通的链表使用空间太大,增加内存的碎片化,比如存储一个int类型,还需要两个指针,增加内存占用空间。所以使用链表和ziplist结合的方式,使用双箭头将ziplist链接起来,这样即满足快速插入和删除,又能不占用过多的空间。
hash(字典)
Redis字典相当于java里面的hashmap,它是无序字典,内部结构上同hashmap一样,使用数组加链表的方式,第一维hash的数组发生碰撞,就会将碰撞的元素使用链表串联起来。
hash.png
不同的是redis存储的只能是字符串,另外他们的rehash的方式不一样,java的hashmap是一次性全部rehash,在元素很多时,是很耗时的操作,redis为了不堵塞服务,提高性能,采用的是渐进式rehash策略。
redis在rehash时会保留新旧两个hash结构,在查询时会从两个结构中查询,后续一点点的将旧hash的内容迁移到新hash上,当最后一个元素迁移完成,替代旧hash,内存被回收。
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象,hash 可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪费网络流量。
set(集合)
Redis的集合相当于java语言中的hashSet,内部的键值对是无序的唯一的,它的内部实现相当于一个特殊的字典,字典中的所有value都是null。
set集合可以用来存储中将用户,这样就确保不会重复。
zset(有序集合)
有序集合是最有特色的数据结构,类似于java的sortedSet和hashmap的结合体。一方面是一个set保证内部value的唯一性,另一方面对每个值赋予一个score,代表这个值的权重排序。内部使用的是一种叫做跳跃列表的数据结构。
zset的最后一个元素被移除后,数据结构自动删除,内存被回收。
以上是Redis的基本数据结构类型,后面给大家分享一下redis的高级用法。
网友评论