文章目录
0、总体概述
0.1、十大数据类型
0.2、提前声明
- 这里说的数据类型是value的数据类型,key的数据类型都是字符串。
0.3、分别是
redis字符串(String)
redis列表(List)
redis哈希表(Hash)
redis集合(Set)
redis有序集合(ZSet—Sorted Set)
redis地理空间(GEO)
redis基数统计(HyperLogLog)
redis位图(bitmap)
redis位域(bitfield)
redis流(Stream)
0.4、哪里去获取redis常见数据类型操作命令
官网英文:https://redis.io/commands/
中文:http://www.redis.cn/commands.html
1、Redis常用五大数据类型
1、Redis键(key)
2、字符串String
2.1、简介
3.2.2、常用命令
2.3、数据结构(value)
String在Redis内部的数据结构是一个简单的动态字符串(String Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。
3、Redis列表(List)
3.1、简介
单键多值:
- Redis列表是简单的字符串列表,按照插入顺序排列。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
- 他的底层实际上是一个双向链表,对双端的操作性能都很高,通过索引下标的操作中间的节点性能会较差。
3.2、常用命令
- lrange命令中传入-1表示右边第一个。
3.3、数据结构
- List的数据结构为快速链表quicklist。
- 首先在列表元素比较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也就是压缩列表。
- 他将所有的元素紧挨着一起存储,分配的是一块连续的内存。
- 当数据量比较多的时候才会改成quicklist。
- 因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prew和next。
- Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除功能,又不会出现太大的空间冗余。
4、Redis集合(Set)
4.1、简介
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排序的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好地选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
Redis的Set是string类型的无序集合,他底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1).
一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变。
4.2、常用命令
4.3、数据结构
- Set数据结构是dict字典,字典是用哈希表实现的。
- Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向统一内部值。
5、Redis哈希(Hash)
5.1、简介
- Redis hash是一个键值对集合。
- Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里边的Map<String, Object>.
- 用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储。
主要有以下两种存储方式:
- 下面这两种都不建议使用:
- 这种是比较好的存储方式:(不会有前两种的缺点)
5.2、常用命令
- 测试结果:
5.3、数据结构
- Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。
6、Redis有序集合Zset(sorted set)
6.1、简介
- Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
- 不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从低分到高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了。
- 因为元素是有序的,所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。
- 访问有序集合的中间元素也是非常快的,因为你能够使用有序集合作为一个没有重复成员的智能列表。
6.2、常用命令
测试:
6.3、数据结构
6.4、跳跃表(跳表)
简介
实例
(2)跳跃表
- 可以看出跳跃表比链表效率高很多。
2、Redis的发布和订阅
2.1、什么是发布和订阅
- Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
- Redis客户端可以订阅任意数量的频道。
2.2、Redis的发布和订阅
2.3、发布订阅命令行实现
- 打开一个客户端订阅channel1。
subscribe channel1
- 打开另一个客户端,给channel1发布消息hello。
publish channel1 hello
- 返回的1是订阅者数量。
- 打开第一个客户端可以看到发送的信息。
注意:发布的消息没有持久化,如果在订阅的客户端收不到hello,只能收到订阅后发布的消息。
3、Redis6新数据类型
3.1、Bitmaps
3.1.1、简介
3.1.2、常用命令
- setbit
测试:
- getbit
测试结果:
- bitcount
测试:
- bitop
测试结果:
3.1.3、Bitmaps和set对比
3.2、HyperLogLog
3.2.1、简介
3.2.2、常用命令
- pfadd
测试:
- pfcount
测试:
- pfmerge
3.3、Geospatial
3.3.1、简介
3.3.2、常用命令
- geoadd
测试:
- geopos
测试:
- geodist
测试:
- georadius
测试:
4、Redis特殊数据结构
4.1、Redis流(Stream)
是什么
redis5.0之前的痛点:
Redis消息队列的两种方案。
- List实现方式其实就是点对点模式。
- Pub/Sub
Redis5.0版本新增了一个更强大的数据结构----Stream:
一句话:Redis版本的MQ消息中间件+阻塞队列。
能干嘛
- 实现消息队列,它支持消息的持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,让那个消息队列更加的稳定和可靠。
底层结构和原理说明
基本命令理论简介
- 队列相关指令。
- 消费组相关指令。
- 四个特殊符号。
- +
:最小和最大可能出现的ID
$
:表示只消费新的消息,当前流中最大的ID,可用于即将到来的消息
>
:用于XREADGROUP,表示迄今为止还没有发送给组中使用者的消息,会更新消费者组的最后ID
*
:用于XADD命令红,让系统自动生成ID
基本命令代码实操
- 队列相关指令
XADD:添加消息到队列末尾
- 消息ID必须要比上个ID大
- 默认用星号表示自动生成规矩
*
用于XADD命令中,让系统自动生成ID
XADD用于向Stream队列中添加消息,如果指定的Stream队列不存在,则该命令执行会新建一个Stream队列。
*号表示服务器自动生成MessageID(类似mysql里边的主键auto_increment),后面顺序跟着一堆业务key/value。
XRANGE:用于获取消息列表(可以指定范围),忽略删除消息
- start表示开始值,-表示最小值
- end表示结束值,+表示最大值
- count表示最多获取多少个值
XREVRANGE:逆向展示
XDEL:删除流中的内容
- 删除方式指定主键删除
XLEN:用于获取Stream队列的消息的长度
XTRIM:用于对Stream的长度进行截取,如超长会进行截取
MAXLEN
:允许的最大长度,对流进行修剪限制长度MINID
:允许的最小ID,从某个ID值开始比该ID小的值都将会被抛弃
XREAD:用于获取消息(阻塞/非阻塞)
- 只会返回大于制定ID的消息。
- 非阻塞
- 阻塞
添加新数据后立即返回:
- 小总结:类似java中的阻塞队列
XGROUP CREATE:用于创建消费者组
$
:表示从Stream尾部开始消费
0
:表示从Stream头部开始消费
创建消费者组的时候必须指定ID,ID为0从头开始消费,为$表示只消费新的消息,队尾新来。
XREADGROUP GROUP:
>
:表示从第一条尚未被消费的消息开始读取
创建三个消费者组:
消费组groupa内的消费者consumer1从mystream消息队列中读取所有消息
- stream中的消息一旦别消费者组里的一个消费者读取了,就不能再被改消费者组内的其他消费者读取了,即同一个消费组里的消费者不能消费同一条消息。刚才的XREADGROUP 命令再执行一次,读取到的就是空值。
但是,不同消费组的消费者可以消费同一条消息
消费的目的???
- 让组内的多个消费者共同分担读取消息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的。
重点问题
XPENDING:查询每个消费组内所有消费者[已读取,但尚未确认]的消息
- 查看某个消费者具体读取了哪些数据
XACK:向消息队列确认消息处理已完成
XINFO:用于打印stream\consumer\group的详细信息
使用建议
Stream还是不能100%等价于Kafka、RabbitMQ来使用的,生产案例少,慎用。
4.2、Redis位域(bitfield)-了解即可
能干嘛
- 位域修改
- 溢出控制
一句话
将一个Redis字符串看做是一个由二进制位组成的数组,并能对变长位宽和任意没有字节对齐的制定整型位域进行寻址和修改。
命令基本语法
案例
- ASCII码表
BITFIELD key [GET type offset]
BITFIELD key [SET type offset value]
- 设置指定位域的值并返回它的原值
BITFIELD key [INCRBY type offset increment]
溢出控制OVERFLOW [WRAP|SAT|FAIL]
- WRAP:使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况
- SAT:使用饱和计算(saturation arithmetic)方法处理溢出,下溢计算的结果为最小整数值,而上溢计算的结果为最大的整数值
- FAIL:命令将拒绝执行哪些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未被执行