第三章_Redis的十大数据类型

which 10

官网:https://redis.io/docs/data-types/

第三章_Redis的十大数据类型_第1张图片

第三章_Redis的十大数据类型_第2张图片一图说明

第三章_Redis的十大数据类型_第3张图片

提前声明

这里说的数据类型是value的数据类型,key的类型都是字符串

十大数据类型分别是

  1. redis字符串(String)
     

    String(字符串)。

    string是redis最基本的类型,一个key对应一个value。

    string类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象 。

    string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。

  2. redis列表(List)
     

    List(列表)。

    Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

    它的底层实际是个双端链表,最多可以包含 2^32 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。

  3. redis哈希表(Hash)
     

    Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。

    Redis 中每个 hash 可以存储 2^32 - 1 键值对(40多亿)。

  4. redis集合(Set)
     

    Set(集合)。

    Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,集合对象的编码可以是 intset 或者 hashtable。

    Redis 中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

    集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。

  5. redis有序集合(ZSet)
     

    Zset(sorted set:有序集合)。

    Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。

    不同的是每个元素都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大的排序。

    zset的成员是唯一的,但分数(score)却可以重复。

    zset集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 2^32 - 1

  6. redis地理空间(GEO)
     

    Redis GEO 主要用于存储地理位置信息,并对存储的信息进行操作,包括:

    添加地理位置的坐标。

    获取地理位置的坐标。

    计算两个位置之间的距离。

    根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。

  7. redis基数统计(HyperLogLog)
     

    HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的。

    在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

    但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

  8. redis位图(bitmap)

    第三章_Redis的十大数据类型_第4张图片
     
  9. redis位域(bitfield)
     

    通过bitfield命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果。

    说白了就是通过bitfield命令我们可以一次性对多个比特位域进行操作。

  10. redis流(Stream)
     

    Redis Stream 是 Redis 5.0 版本新增加的数据结构。

    Redis Stream 主要用于消息队列(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。

    简单来说发布订阅 (pub/sub) 可以分发消息,但无法记录历史消息。

    而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。

 哪里去获得redis常见数据类型操作命令

官网英文
中文文档

Redis 键(key)

常用

第三章_Redis的十大数据类型_第5张图片

案例

keys *

查看当前库所有的key

exists key

判断某个key是否存在

type key

查看key是什么类型

del key

删除指定的key数据

unlink key

非阻塞删除,仅仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作

ttl key

查看还有多少秒过期,-1表示永不过期,-2表示已过期

expire key 秒钟

为给定的key设置过期时间

设置 Key 过期时间,默认-1表示永不过期,-2表示已过期

Redis 的过期时间设置有四种形式:

• EXPIRE 秒——设置指定的过期时间(秒),表示的是时间间隔。

• PEXPIRE 毫秒——设置指定的过期时间,以毫秒为单位,表示的是时间间隔。

• EXPIREAT 时间戳-秒——设置指定的 Key 过期的 Unix 时间,单位为秒,表示的是时间/时刻。

• PEXPIREAT 时间戳-毫秒——设置指定的 Key 到期的 Unix 时间,以毫秒为单位,表示的是时间/时刻。

expire key seconds [NX|XX|GT|LT]

move key dbindex【0-15】

将当前数据库的 key移动到给定的数据库 db 当中

select dbindex

切换数据库【0-15】,默认为0

dbsize

查看当前数据库key的数量

flushdb

清空当前库

flushall

通杀全部库

数据类型命令及落地运用

官网命令大全网址 

英文官网命令大全

中文官网命令大全

备注

命令不区分大小写,而key是区分大小写的

永远的帮助命令,help @类型

help @string

help @list

help @hash

help @hyperloglog

。。。。。。

Redis字符串(String)

常用

第三章_Redis的十大数据类型_第6张图片

第三章_Redis的十大数据类型_第7张图片

单值单value 

案例

最常用

set key value

keepttl(重新设置保持过期时间

第三章_Redis的十大数据类型_第8张图片

 get key

同时设置/获取多个键值

MSET key value [key value ....]

MGET key [key ....]

mset/mget/msetnx

mset:同时设置一个或多个 key-value 对。

第三章_Redis的十大数据类型_第9张图片

mget:获取所有(一个或多个)给定 key 的值。

第三章_Redis的十大数据类型_第10张图片

msetnx:同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。

第三章_Redis的十大数据类型_第11张图片 获取指定区间范围内的值

getrange/setrange

getrange:获取指定区间范围内的值,类似between......and的关系

从零到负一表示全部

第三章_Redis的十大数据类型_第12张图片

setrange设置指定区间范围内的值,格式是setrange key值 具体值

第三章_Redis的十大数据类型_第13张图片 数值增减

一定要是数字才能进行加减

递增数字

INCR key

增加指定的整数

INCRBY key increment

递减数值

DECR key

减少指定的整数

DECRBY key decrement

获取字符串长度和内容追加

STRLEN key

APPEND key value

分布式锁实现命令

setnx key value

setex(set with expire)键秒值/setnx(set if not exist)

setex:设置带过期时间的key,动态设置。

setex 键 秒值 真实值

第三章_Redis的十大数据类型_第14张图片

setnx:只有在 key 不存在时设置 key 的值。

第三章_Redis的十大数据类型_第15张图片

 getset(先get再set)

getset:将给定 key 的值设为 value ,并返回 key 的旧值(old value)。

简单一句话,先get然后立即set

第三章_Redis的十大数据类型_第16张图片

应用场景

 比如抖音无限点赞某个视频或者商品,点一下加一次

第三章_Redis的十大数据类型_第17张图片

是否喜欢的文章

 阅读数:只要点击了rest地址,直接可以使用incr key 命令增加一个数字1,完成记录数字。

第三章_Redis的十大数据类型_第18张图片

Redis列表(List) 

常用

第三章_Redis的十大数据类型_第19张图片

单key多value

简单说明

一个双端链表的结构,容量是2的32次方减1个元素,大概40多亿,主要功能有push/pop等,一般用在栈、队列、消息队列等场景。

left、right都可以插入添加;

如果键不存在,创建新的链表;

如果键已存在,新增内容;

如果值全移除,对应的键也就消失了。

  • 它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。

第三章_Redis的十大数据类型_第20张图片

案例

lpush/rpush/lrange 

lpop/rpop

第三章_Redis的十大数据类型_第21张图片

lindex,按照索引下标获得元素(从上到下)

通过索引获取列表中的元素 lindex key index

第三章_Redis的十大数据类型_第22张图片

llen 获取列表中元素的个数

lrem key 数字N 给定值v1    解释(删除N个值等于v1的元素)

 * 从left往right删除2个值等于v1的元素,返回的值为实际删除的数量

 *  LREM list3 0 值,表示删除全部给定的值。零个就是全部值

第三章_Redis的十大数据类型_第23张图片

ltrim key 开始index 结束index,截取指定范围的值后再赋值给key

ltrim:截取指定索引区间的元素,格式是ltrim list的key 起始索引 结束索引

第三章_Redis的十大数据类型_第24张图片

rpoplpush 源列表 目的列表 

移除列表的最后一个元素,并将该元素添加到另一个列表并返回

第三章_Redis的十大数据类型_第25张图片

 lset key index value

第三章_Redis的十大数据类型_第26张图片

 linsert key  before/after 已有值 插入的新值

在list某个已有值的前后再添加具体值

第三章_Redis的十大数据类型_第27张图片

应用场景 

微信公众号订阅的消息

1 大V作者李永乐老师和CSDN发布了文章分别是 11 和 22

2 张三关注了他们两个,只要他们发布了新文章,就会安装进我的List

   lpush likearticle:张三id  11 22

3 查看张三自己的号订阅的全部文章,类似分页,下面0~10就是一次显示10条

  lrange likearticle:张三id 0 9

第三章_Redis的十大数据类型_第28张图片

Redis哈希(Hash) 

常用

第三章_Redis的十大数据类型_第29张图片

KV模式不变,但V是一个键值对

相当于Map>

案例

hset/hget/hmset/hmget/hgetall/hdel

第三章_Redis的十大数据类型_第30张图片

第三章_Redis的十大数据类型_第31张图片

 hlen

获取某个key内的全部数量

hexists key 在key里面的某个值的key

hkeys/hvals

第三章_Redis的十大数据类型_第32张图片

hincrby/hincrbyfloat

第三章_Redis的十大数据类型_第33张图片

hsetnx 

不存在赋值,存在了无效。

第三章_Redis的十大数据类型_第34张图片

 应用场景

JD购物车早期 设计目前不再采用,当前小中厂可用

新增商品 → hset shopcar:uid1024 334488 1

新增商品 → hset shopcar:uid1024 334477 1

增加商品数量 → hincrby shopcar:uid1024 334477 1

商品总数 → hlen shopcar:uid1024

全部选择 → hgetall shopcar:uid1024

第三章_Redis的十大数据类型_第35张图片

Redis集合(Set) 

常用

第三章_Redis的十大数据类型_第36张图片

单值多value,且无重复 

案例

添加元素:SADD key member [member ...]

遍历集合中的所有元素:SMEMBERS key

判断元素是否在集合中:SISMEMBER key member

删除元素:SREM key member [member ...]

scard,获取集合里面的元素个数

获取集合里面的元素个数

第三章_Redis的十大数据类型_第37张图片

SRANDMEMBER key [数字]

 *   从set集合里面随机取出2个

 *   如果超过最大数量就全部取出,

 *   如果写的值是负数,比如-3 ,表示需要取出3个,但是可能会有重复值。

从集合中随机展现设置的数字个数元素,元素不删除

第三章_Redis的十大数据类型_第38张图片

 SPOP key [数字]

第三章_Redis的十大数据类型_第39张图片

从集合中随机弹出一个元素,出一个删一个

smove key1 key2 在key1里已存在的某个值

第三章_Redis的十大数据类型_第40张图片

将key1里已存在的某个值赋给key2

集合运算 

A、B两个集合

集合A:abc12

集合B:123ax

集合的差集运算 A-B

属于A但不属于B的元素构成的集合

SDIFF key [key ...]

集合的并集运算 A ∪ B

属于A或者属于B的元素合并后的集合

SUNION key [key ...]

集合的交集运算 A∩B

属于A同时也属于B的共同拥有的元素构成的集合

SINTER key [key ...]

SINTERCARD numkeys key [key ...] [LIMIT limit](redis7新命令

它不返回结果集,而只返回结果的基数。返回由所有给定集合的交集产生的集合的基数

案例

第三章_Redis的十大数据类型_第41张图片

应用场景 

微信抽奖小程序

第三章_Redis的十大数据类型_第42张图片

                                                                   微信抽奖小程序

1 用户ID,立即参与按钮
sadd key 用户ID
2 显示已经有多少人参与了,上图23208人参加
SCARD key
3 抽奖(从set中任意选取N个中奖人)
SRANDMEMBER key 2       随机抽奖2个人,元素不删除
SPOP  key 3                         随机抽奖3个人,元素 会删除

微信朋友圈点赞查看同赞朋友

第三章_Redis的十大数据类型_第43张图片

                                                                    微信朋友圈点赞

1 新增点赞
sadd pub:msgID  点赞用户ID1  点赞用户ID2
2 取消点赞
srem pub:msgID  点赞用户ID
3 展现所有点赞过的用户
SMEMBERS  pub:msgID
4 点赞用户数统计,就是常见的点赞红色数字
scard  pub:msgID
5 判断某个朋友是否对楼主点赞过
SISMEMBER pub:msgID 用户ID

QQ内推可能认识的人

第三章_Redis的十大数据类型_第44张图片

Redis有序集合Zset(sorted set) 

多说一句

Zset在set基础上,每个val值前加一个score分数值。之前set是k1 v1 v2 v3,现在zset是k1 score1 v1 score2 v2

常用

第三章_Redis的十大数据类型_第45张图片

第三章_Redis的十大数据类型_第46张图片

案例 

向有序集合中加入一个元素和该元素的分数

添加元素:ZADD key score member [score member ...]

第三章_Redis的十大数据类型_第47张图片

 ZRANGE key start stop [WITHSCORES]

按照元素分数从小到大的顺序

返回索引从start到stop之间的所有元素

zrevrange

第三章_Redis的十大数据类型_第48张图片

获取指定分数范围的元素:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

第三章_Redis的十大数据类型_第49张图片

withscores

( 不包含

limit 作用是返回限制

limit 开始下标步 多少步

ZSCORE key member

zcard :获取集合中元素个数

第三章_Redis的十大数据类型_第50张图片

zcount :获取分数区间内元素个数,zcount key 开始分数区间 结束分数区间

第三章_Redis的十大数据类型_第51张图片

zrank: 获取value在zset中的下标位置 

第三章_Redis的十大数据类型_第52张图片

zscore:按照值获得对应的分数

第三章_Redis的十大数据类型_第53张图片

获取集合中元素的数量:ZCARD key

zrem key 某score下对应的value值,作用是删除元素

删除元素,格式是zrem zset的key 项的值,项的值可以是多个

zrem key score某个对应值,可以是多个值

第三章_Redis的十大数据类型_第54张图片

增加某个元素的分数:ZINCRBY key increment member 

获得指定分数范围内的元素个数:ZCOUNT key min max

ZMPOP

从键名列表中的第一个非空排序集中弹出一个或多个元素,它们是成员分数对

第三章_Redis的十大数据类型_第55张图片

zrank key values 值,作用是获得下标值

zrevrank key values 值,作用是逆序获得下标值

第三章_Redis的十大数据类型_第56张图片

 应用场景

根据商品销售对商品进行排序显示

思路:定义商品销售排行榜(sorted set集合),key为goods:sellsort,分数为商品销售数量。

商品编号1001的销量是9,商品编号1002的销量是15
zadd goods:sellsort 9 1001 15 1002
有一个客户又买了2件商品1001,商品编号1001销量加2
zincrby goods:sellsort 2 1001
求商品销量前10名
ZRANGE goods:sellsort 0 9 withscores

第三章_Redis的十大数据类型_第57张图片

Redis位图(bitmap) 

由0和1状态表现的二进制位的bit数组

一句话

由0和1状态表现的二进制位的bit数组

看需求

用户是否登陆过Y、N,比如京东每日签到送京豆

电影、广告是否被点击播放过

钉钉打卡上下班,签到统计

。。。。。。

是什么

第三章_Redis的十大数据类型_第58张图片

说明:用String类型作为底层数据结构实现的一种统计二值状态的数据类型

位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引)。

Bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(2^32 = 4294967296)

能做什么

用于状态统计

Y、N,类似AtomicBoolean

基本命令

第三章_Redis的十大数据类型_第59张图片

setbit

setbit key offset value 

第三章_Redis的十大数据类型_第60张图片

setbit 键   偏移位  只能零或者1​

Bitmap的偏移量是从零开始算的 

getbit

getbit key offset

strlen

第三章_Redis的十大数据类型_第61张图片

不是字符串长度而是占据几个字节,超过8位后自己按照8位一组一byte再扩容

统计字节数占用多少

bitcount

全部键里面含有1的有多少个?

第三章_Redis的十大数据类型_第62张图片

bitop 

连续2天都签到的用户

加入某个网站或者系统,它的用户有1000W,做个用户id和位置的映射

比如0号位对应用户id:uid-092iok-lkj

比如1号位对应用户id:uid-7388c-xxx

。。。。。。  

第三章_Redis的十大数据类型_第63张图片

 setbit和getbit案例说明

按照天

第三章_Redis的十大数据类型_第64张图片

应用场景 

一年365天,全年天天登陆占用多少字节

第三章_Redis的十大数据类型_第65张图片

按照年

按年去存储一个用户的签到情况,365 天只需要 365 / 8 ≈ 46 Byte,1000W 用户量一年也只需要 44 MB 就足够了。

假如是亿级的系统,

每天使用1个1亿位的Bitmap约占12MB的内存(10^8/8/1024/1024),10天的Bitmap的内存开销约为120MB,内存压力不算太高。

此外,在实际使用时,最好对Bitmap设置过期时间,让Redis自动删除不再需要的签到记录以节省内存开销。

Redis基数统计(HyperLogLog)

第三章_Redis的十大数据类型_第66张图片

 看需求

统计某个网站的UV、统计某个文章的UV

什么是UV

Unique Visitor,独立访客,一般理解为客户端IP

需要去重考虑

用户搜索网站关键词的数量

统计用户每天搜索不同词条个数

是什么

去重复统计功能的基数估计算法-就是HyperLogLog

第三章_Redis的十大数据类型_第67张图片

基数 

是一种数据集,去重复后的真实个数

案例Case

第三章_Redis的十大数据类型_第68张图片

基数统计

用于统计一个集合中不重复的元素个数,就是对集合去重复后剩余元素的计算 

一句话

去重脱水后的真实数据

基本命令

 案例见最下:

第三章_Redis的十大数据类型_第69张图片

第三章_Redis的十大数据类型_第70张图片

第三章_Redis的十大数据类型_第71张图片

 应用场景

天猫网站首页亿级UV的Redis统计方案(后面编码实战)

Redis地理空间(GEO)

简介

移动互联网时代LBS应用越来越多,交友软件中附近的小姐姐、外卖软件中附近的美食店铺、高德地图附近的核酸检查点等等,那这种附近各种形形色色的XXX地址位置选择是如何实现的?

地球上的地理位置是使用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],只要我们确定一个点的经纬度就可以名取得他在地球的位置。

例如滴滴打车,最直观的操作就是实时记录更新各个车的位置,

然后当我们要找车时,在数据库中查找距离我们(坐标x0,y0)附近r公里范围内部的车辆

使用如下SQL即可:

select taxi from position where x0-r < x < x0 + r and y0-r < y < y0+r

但是这样会有什么问题呢?

1.查询性能问题,如果并发高,数据量大这种查询是要搞垮数据库的

2.这个查询的是一个矩形访问,而不是以我为中心r公里为半径的圆形访问。

3.精准度的问题,我们知道地球不是平面坐标系,而是一个圆球,这种矩形计算在长距离计算时会有很大误差

原理

核心思想就是将球体转换为平面,区块转换为一点

第三章_Redis的十大数据类型_第72张图片

地理知识说明

Redis在3.2版本以后增加了地理位置的处理

命令

GEOADD  多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

GEOPOS  从键里面返回所有给定位置元素的位置(经度和纬度)。

GEODIST 返回两个给定位置之间的距离。

GEORADIUS 以给定的经纬度为中心, 返回与中心的距离不超过给定最大距离的所有位置元素。

GEORADIUSBYMEMBER 跟GEORADIUS类似。

GEOHASH返回一个或多个位置元素的 Geohash 表示。

命令实操

如何获得某个地址的经纬度

GEOADD添加经纬度坐标

第三章_Redis的十大数据类型_第73张图片

命令如下:

GEOADD city 116.403963 39.915119 "天安门" 116.403414 39.924091 "故宫" 116.024067 40.362639 "长城"

中文乱码如何处理

第三章_Redis的十大数据类型_第74张图片

GEOPOS返回经纬度

第三章_Redis的十大数据类型_第75张图片 GEOHASH返回坐标的geohash表示

第三章_Redis的十大数据类型_第76张图片

geohash算法生成的base32编码值

3维变2维变1维

第三章_Redis的十大数据类型_第77张图片

GEODIST 两个位置之间距离

第三章_Redis的十大数据类型_第78张图片

GEODIST city 天安门 故宫 km

后面参数是距离单位:

m 米

km 千米

ft 英尺

mi 英里

GEORADIUS(以半径为中心,查找附近的XXX)

georadius 以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

GEORADIUS city 116.418017 39.914402 10 km withdist withcoord count 10 withhash desc

GEORADIUS city 116.418017 39.914402 10 km withdist withcoord withhash count 10 desc

WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
WITHCOORD: 将位置元素的经度和维度也一并返回。
WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大
COUNT 限定返回的记录数。

 当前位置(116.418017 39.914402),张三在北京王府井

第三章_Redis的十大数据类型_第79张图片

 GEORADIUSBYMEMBER​

第三章_Redis的十大数据类型_第80张图片

应用场景

美团地图位置附近的酒店推送(后面编码实战)

高德地图附近的核酸检查点 (后面编码实战)

Redis流(Stream)

是什么

redis5.0之前痛点

Redis 消息队列的2种方案

List 实现消息队列

按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。 

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

LPUSH、RPOP 左进右出    RPUSH、LPOP 右进左出 

第三章_Redis的十大数据类型_第81张图片

List 实现方式其实就是点对点的模式

(Pub/Sub)

第三章_Redis的十大数据类型_第82张图片 Redis 发布订阅 (pub/sub) 有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。而且也没有 Ack 机制来保证数据的可靠性,假设一个消费者都没有,那消息就直接被丢弃了。

Redis5.0版本新增了一个更强大的数据结构-----Stream

一句话

Redis版的MQ消息中间件+阻塞队列

能做什么

实现消息队列,它支持消息的持久化、支持自动生成全局唯一 ID、支持ack确认消息的模式、支持消费组模式等,让消息队列更加的稳定和可靠

底层结构和原理说明

stream结构

第三章_Redis的十大数据类型_第83张图片

一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的 ID 和对应的内容 

1
Message Content
消息内容
2
Consumer group
消费组,通过XGROUP CREATE 命令创建,同一个消费组可以有多个消费者
3
Last_delivered_id
游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
4
Consumer
消费者,消费组中的消费者
5
Pending_ids
消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为 PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理

基本命令理论简介

队列相关指令

第三章_Redis的十大数据类型_第84张图片

 消费组相关指令

第三章_Redis的十大数据类型_第85张图片

四个特殊符号

- +

最小和最大可能出现的Id

$

$ 表示只消费新的消息,当前流中最大的 id,可用于将要到来的信息

>

用于XREADGROUP命令,表示迄今还没有发送给组中使用者的信息,会更新消费者组的最后 ID

*

用于XADD命令中,让系统自动生成 id

基本命令代码实操

Redis流实例演示

队列相关指令

XADD

添加消息到队列末尾

XADD 用于向Stream 队列中添加消息,如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列

//* 号表示服务器自动生成 MessageID(类似mysql里面主键auto_increment),后面顺序跟着一堆 业务key/value

第三章_Redis的十大数据类型_第86张图片

信息条目指的是序列号,在相同的毫秒下序列号从0开始递增,序列号是64位长度,理论上在同一毫秒内生成的数据量无法到达这个级别,因此不用担心序列号会不够用。millisecondsTime指的是Redis节点服务器的本地时间,如果存在当前的毫秒时间戳比以前已经存在的数据的时间戳小的话(本地时间钟后跳),那么系统将会采用以前相同的毫秒创建新的ID,也即redis 在增加信息条目时会检查当前 id 与上一条目的 id, 自动纠正错误的情况,一定要保证后面的 id 比前面大,一个流中信息条目的ID必须是单调增的,这是流的基础。
客户端显示传入规则:
Redis对于ID有强制要求,格式必须是 时间戳-自增Id这样的方式,且后续ID不能小于前一个ID
Stream的消息内容,也就是图中的Message Content它的结构类似Hash结构,以key-value的形式存在。

消息ID必须要比上个 ID 大

第三章_Redis的十大数据类型_第87张图片

默认用星号表示自动生成规矩

* 用于XADD命令中,让系统自动生成 id 

XRANGE

第三章_Redis的十大数据类型_第88张图片

用于获取消息列表(可以指定范围),忽略删除的消息

start 表示开始值,-代表最小值 

end 表示结束值,+代表最大值

count 表示最多获取多少个值

XREVRANGE

第三章_Redis的十大数据类型_第89张图片

与XRANGE 的区别在于,获取消息列表元素的方向是相反的,end在前,start在后

XDEL

第三章_Redis的十大数据类型_第90张图片

XLEN

第三章_Redis的十大数据类型_第91张图片用于获取Stream 队列的消息的长度

XTRIM​

用于对Stream的长度进行截取,如超长会进行截取

MAXLEN

允许的最大长度,对流进行修剪限制长度

第三章_Redis的十大数据类型_第92张图片

MINID

允许的最小id,从某个id值开始比该id值小的将会被抛弃

第三章_Redis的十大数据类型_第93张图片

 XREAD​

 用于获取消息(阻塞/非阻塞),只会返回大于指定ID的消息

第三章_Redis的十大数据类型_第94张图片

非阻塞

$代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil
0-0代表从最小的ID开始获取Stream中的消息,当不指定count,将会返回Stream中的所有消息,注意也可以使用0(00/000也都是可以的……)

第三章_Redis的十大数据类型_第95张图片

 阻塞

请redis-cli启动第2个客户端连接上来 

第三章_Redis的十大数据类型_第96张图片

小总结(类似java里面的阻塞队列)

Stream的基础方法,使用xadd存入消息和xread循环阻塞读取消息的方式可以实现简易版的消息队列,交互流程如下

第三章_Redis的十大数据类型_第97张图片

 消费组相关指令

XGROUP CREATE

用于创建消费者组

第三章_Redis的十大数据类型_第98张图片

$表示从Stream尾部开始消费

0表示从Stream头部开始消费

创建消费者组的时候必须指定 ID, ID 为 0 表示从头开始消费,为 $ 表示只消费新的消息,队尾新来

XREADGROUP GROUP

“>”,表示从第一条尚未被消费的消息开始读取

消费组groupA内的消费者consumer1从mystream消息队列中读取所有消息

第三章_Redis的十大数据类型_第99张图片

但是,不同消费组的消费者可以消费同一条消息

第三章_Redis的十大数据类型_第100张图片

 消费组的目的??

让组内的多个消费者共同分担读取消息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的

第三章_Redis的十大数据类型_第101张图片

重点问题

问题
基于 Stream 实现的消息队列,如何保证消费者在发生故障或宕机再次重启后,仍然可以读取未处理完的消息?
1
Streams 会自动使用内部队列(也称为 PENDING List)留存消费组里每个消费者读取的消息保底措施,直到消费者使用 XACK 命令通知 Streams“消息已经处理完成”。
2
消费确认增加了消息的可靠性,一般在业务处理完成之后,需要执行 XACK 命令确认消息已经被消费完成

第三章_Redis的十大数据类型_第102张图片

XPENDING

查询每个消费组内所有消费者「已读取、但尚未确认」

第三章_Redis的十大数据类型_第103张图片

查看某个消费者具体读取了哪些数据

第三章_Redis的十大数据类型_第104张图片

下面抓图所示:consumer2已读取的消息的 ID是1659430293537-0

一旦消息1659430293537-0被consumer2处理了consumer2就可以使用  XACK 命令通知 Streams,然后这条消息就会被删除
第三章_Redis的十大数据类型_第105张图片

XACK

向消息队列确认消息处理已完成

第三章_Redis的十大数据类型_第106张图片

 XINFO 用于打印Stream\Consumer\Group的详细信息

第三章_Redis的十大数据类型_第107张图片

使用建议

Stream还是不能100%等价于Kafka、RabbitMQ来使用的,生产案例少,慎用

仅仅代表本人愚见,不权威

Redis位域(bitfield)

了解即可

是什么

官网

第三章_Redis的十大数据类型_第108张图片

能做什么

第三章_Redis的十大数据类型_第109张图片

位域修改

溢出控制

 一句话

将一个Redis字符串看作是一个由二进制位组成的数组并能对变长位宽和任意没有字节对齐的指定整型位域进行寻址和修改

命令基本语法

第三章_Redis的十大数据类型_第110张图片

案例

Ascii码表

基本命令代码实操

BITFIELD key [GET type offset]

第三章_Redis的十大数据类型_第111张图片

hello 等价于 0110100001100101011011000110110001101111

第三章_Redis的十大数据类型_第112张图片

BITFIELD key [SET type offset value] 

第三章_Redis的十大数据类型_第113张图片

BITFIELD key  [INCRBY type offset increment]

第三章_Redis的十大数据类型_第114张图片

默认情况下, INCRBY 使用 WRAP 参数

溢出控制OVERFLOW [WRAP|SAT|FAIL]

WRAP: 使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况 

第三章_Redis的十大数据类型_第115张图片

 SAT: 使用饱和计算(saturation arithmetic)方法处理溢出,下溢计算的结果为最小的整数值,而上溢计算的结果为最大的整数值

第三章_Redis的十大数据类型_第116张图片

 FAIL: 命令将拒绝执行那些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未被执行

第三章_Redis的十大数据类型_第117张图片

第三章_Redis的十大数据类型_第118张图片 

  • A

你可能感兴趣的:(#,redis,redis,数据库,缓存)