当前位置: 首页 > article >正文

[Redis] Redis中的Hash类型和List类型

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(97平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. Redis中关于Hash相关的操作
    • 1.1 Hash的存储方式
    • 1.2 关于Hash的常见命令
    • 1.3 指令小结
  • 2. Hash的内部编码方式
  • 3. hash的应用场景
    • 3.1 作为缓存
  • 4. Redis中关于List的操作
    • 4.1 概述
    • 4.2 特点
    • 4.3 相关指令
    • 4.4 阻塞版本指令
      • 4.4.1 特点概述
      • 4.4.2 指令
    • 4.5 指令小结
  • 5. list内部编码方式
  • 6. list的应用场景

1. Redis中关于Hash相关的操作

1.1 Hash的存储方式

在我们之前学习数据结构的时候,我们就曾经接触过HashMap等哈希表相关的集合类.我们知道,在哈希表中存储的是键值对的结构.这里Redis中存储数据本身就是以键值对的形式存储的. 其中key是string类型的数据,要是想要在Redis中存储Hash,那么Redis中的value的类型就是Hash类型的数据.也就是在Hash中又存储了一层Hash.
在这里插入图片描述

注意事项: 为了区分Redis中整体的键值对和Hash数据类型的键值对,我们一般把Hash的键值对分别叫做key-field,Redis整体的键值对叫做key-value.

1.2 关于Hash的常见命令

Hash相关操作的命令一般在前面都有一个h开头.

  • hset
    hset key field value [field value...]
    设置Hash中的指定字段和指定值,可以一次性设置多个,也可以一次性设置一个.返回添加字段的个数.
  • hget
    hget key field
    获取某Hash中field的value.一次只可以获取一个.
127.0.0.1:6379> hset key1 field1 value1 field2 value2
(integer) 2
127.0.0.1:6379> hget key1 field1
"value1"
127.0.0.1:6379> hget key1 field2
"value2"
  • hexists
    hexists key field
    判断某个Hash中的某个field是否存在.
127.0.0.1:6379> HEXISTS key1 field1 field2
(error) ERR wrong number of arguments for 'hexists' command
127.0.0.1:6379> HEXISTS key1 field1
(integer) 1

注意: 在hexists命令中,不支持一次性查询多个field,一次只可以查询 一个field.

  • hdel
    hdel key field [field]
    删除Hash中的元素,可以一次删除一个元素,也可以一次删除多个元素.返回的是本次操作成功删除的字段.
127.0.0.1:6379> hdel key1 field1
(integer) 1
127.0.0.1:6379> hget key1 field1
(nil)
  • hkeys
    hkeys key
    查询指定key中的所有字段.
127.0.0.1:6379> hkeys key1
1) "field2"
  • hvals
    hvals key
    查询指定key中的所有值.
127.0.0.1:6379> hvals key1
1) "value2"
  • hgetall
    hgetall key
    获取指定key中的所有的field和value.返回值是Hash中所有的键值对.
127.0.0.1:6379> hgetall key1
1) "field2"
2) "value2"

[注意事项] 以上的三个操作和前面我们提到的string的keys *一样,存在一定的风险,我们不可以确定这个key对应的Hash中是否有很多键值对.
redis中倒是有这么一个命令会避免这些风险,它叫hscan,它属于渐进式遍历的指令,就是敲一次命令,遍历一小部分,再敲一次,在遍历一部分.有点像我们在多线程中学习的ConcurrentHashMap 的扩容机制,扩容复制元素的时候并不是一次性全部把元素全部拷贝过去,新老数组同时存在,之后每对ConcurrentHashMap操作一次,就拷贝一部分,直到把老数组的元素全部拷贝完成,老数组就会被删除.

  • hmget
    hmget key field [field...]
    一次性查询Hash中多个字段的值,返回查询到的value.
127.0.0.1:6379> hset key2 field1 value1 field2 value2 field3 value3
(integer) 3
127.0.0.1:6379> hgetall key2
1) "field1"
2) "value1"
3) "field2"
4) "value2"
5) "field3"
6) "value3"
127.0.0.1:6379> hmget key2 field1 field2 field3
1) "value1"
2) "value2"
3) "value3"

有的人现在就会想到,有没有hmset,用来一次性设置多个Hash中的键值对呢?有,但是没有必要,因为我们之前讲到的hset指令就可以一次性设置多个键值对.

  • hlen
    hlen key
    获取Hash中的元素个数.
127.0.0.1:6379> hmget key2 field1 field2 field3
1) "value1"
2) "value2"
3) "value3"
127.0.0.1:6379> hlen key2
(integer) 3
  • hsetnx
    hsetnx key field value
    类似与string操作中的setnx,如果Hash中不存在对应的键值对的话,才可以创建成功,如果存在,就创建失败.
127.0.0.1:6379> hsetnx key2 field4 value4
(integer) 1
127.0.0.1:6379> hgetall key2
1) "field1"
2) "value1"
3) "field2"
4) "value2"
5) "field3"
6) "value3"
7) "field4"
8) "value4"
127.0.0.1:6379> hsetnx key2 field2 value2
(integer) 0
  • hincrby
    hincrby key field increment
    给指定的Hash中的字段对应的值加上指定的值.返回的值是加上指定值之后的值.
127.0.0.1:6379> hset key2 field5 1
(integer) 1
127.0.0.1:6379> HINCRBY key2 field5 2
(integer) 3
127.0.0.1:6379> hget key2 field5
"3"
  • hincrbyfloat
    hincrbyfloat key field incrment
    给指定的Hash中的字段对应的值加上指定的小数.返回加上指定值之后的值.
127.0.0.1:6379> HINCRBYFLOAT key2 field5 0.7
"3.7"
127.0.0.1:6379> hget key2 field5
"3.7"

[注意] 在Redis中并没有对Hash提供像string那样的incr,decr,decrby类似的命令,我们想要对Hash对应字段的值+1,只可以使用hincrby key field 1这样的命令,想要-1,就需要hincrby key field -1这样的指令来代替,想要减指定的值,比如-2,就只能使用hincrby key field -2这样的指令来代替.其他的一些操作与上同理.

127.0.0.1:6379> hget key2 field5
"3.7"
127.0.0.1:6379> hincrbyfloat key2 field5 -0.2
"3.5"
127.0.0.1:6379> hset key2 field6 8
(integer) 1
127.0.0.1:6379> HINCRBY key2 field6 -2
(integer) 6

1.3 指令小结

在这里插入图片描述

2. Hash的内部编码方式

Hash内部编码的方式有两种,一种是hashtable,一种是ziplist.

  • ziplist
    在Hash内部元素比较少(默认阈值512个)而且字段对应的值字节数都比较短(默认阈值64字节)的时候,我们一般使用ziplist.
    ziplist会对Hash表进行一定的压缩,会占用比较少的空间.但是也有一定的代价.就是在读写元素的时候,速度是比较慢的,如果元素个数较少,慢一点也不明显,但是如果元素比较多,读写慢就会让Hash雪上加霜.
  • hashtable
    在hash中的元素个数比较多,或者是某一个元素对应的值的字节数比较长,就会让hash的编码方式从原来的ziplist转变为hashtable.
    *其中转变阈值可以在Redis(/etc/redis/redis.conf)的配置文件中设置.*一个属性是hash-max-ziplist-entries,用于配置限制hash中元素的个数,一个属性是hash-max-ziplist-value,用于配置hash中每个value中的长度限制.
    下面对编码方式的转换进行验证:
127.0.0.1:6379> hset key3 field1 value1 field2 value2
(integer) 2
127.0.0.1:6379> OBJECT encoding key3
"ziplist"
127.0.0.1:6379> hset key3 field3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
(integer) 1
127.0.0.1:6379> OBJECT encoding key3
"hashtable"
127.0.0.1:6379> hmset hashkey f1 v1 h2 v2 f3 v3 ... 省略 ... f513 v513
OK
127.0.0.1:6379> object encoding hashkey
"hashtable"

3. hash的应用场景

3.1 作为缓存

Redis中存储用户信息的方式不同于MySQL数据库,Redis是一种非关系型数据库,MySQL是一种关系型数据库,Redis中存储数据是以键值对的方式(映射关系)存储的,MySQL中存储数据是以表的方式存储的.
比如我们想要在Redis和MySQL中存储用户信息.
关系型数据表存储结构如下:
在这里插入图片描述
映射关系存储结构如下:
在这里插入图片描述

  1. 从上述的数据存储的方式中,我们可以看出,使用hash的方式存储数据在读写的时候更加的直观高效.
  2. 哈希类型是稀疏的,而关系型数据库是完全结构化的,例如哈希类型每个键可以有不同的field,而关系型数据库⼀旦添加新的列,所有行都要为其设置值,即使为null.
  3. 但是Redis也相对于MySQL有一定的缺点,Redis付出一些空间的代价.这是因为hash在编码转换的时候,需要消耗一定的内存空间.其次,关系数据库可以做复杂的关系查询,而Redis去模拟关系型复杂查询,例如联表查询、聚合查询等基本不可能,维护成本高.
    在这里插入图片描述

上述这种数据的存储使用json字符串的方式也可以存储.
如果我们使用json字符串的话,只读取某一个字段的时候,需要先把json读取出来,之后解析为对象,之后对想要操作的指端进行操作,之后再重写为json字符串,之后再重新写回去.
如果使用hash的凡是来表示的时候,就可以直接使用字段中相应的值,此时就可以非常方便的修改和获取一个属性的值了.避免了对象和字符串之间来回解析的工作.

我们还可以使用原生字符串的形式表示,*使用Redis中的字符串类型,每个属性一个键值对.

set user:1:name James
set user:1:age 23
set user:1:city Beijing

这种表示方式,相当于把同一个数据给分散开表示了,这样的表现方式就是低内聚的表现方式.而使用hash来存储数据,就会把同一个对象的所有数据都保存在一起.这样的表现方式就是高内聚的.我们在编程的时候,一般使用的是高内聚的表现方式.

4. Redis中关于List的操作

4.1 概述

提到list我们会想到java中的List集合,这样的List就相当于数组或者是顺序表.
但是Redis中的List并非是一个简单的数组,更接近于双端队列(deque).因为Redis中的list支持头插,头删,尾插,尾删,还可以获取指定范围之内的元素和指定下表的元素(和python一样,支持负数下标).它可以充当栈和队列的角色.在实际开发中的应用场景非常广泛.
在这里插入图片描述

4.2 特点

  • 列表中的元素是有序的
    这里的有序,指的是list中的元素可以通过下标来访问.这里的下标可以是正数下表,可以是负数下标.和python一样,正数下标从0开始,负数下标从-1开始.正数表示的是第n+1个元素,负数表示的是倒数第n个元素.
  • 区分删除和获取的区别
    这里之所以要区分,是因为删除和获取的返回值都是指定下标的值.容易混淆.
  • 列表中的元素允许重复
    -在这里插入图片描述
    在这里插入图片描述

4.3 相关指令

  • lpush
    lpush key element [element...]
    从list的左端插入指定的元素,(lpush中的l就是left的缩写). 可以一次插入多个元素,也可以一次插入一个元素.这里需要注意的是,并不是把这些所有的元素整体进行头插,而是按照顺序依次头插.比如我们要在一个list中插入1234,插入完成之后,list的头部是4321的顺序.如果key不存在,创建列表,如果已经创建了key,key对应的value必须是列表类型,否则报错.
  • lrange
    lrange key start stop
    查询列表中指定范围的所有元素.这个指令支持负数下标.其中start区间和stop区间都是闭区间.(这里的l和上面的l意义不一样,这里的l指的是list),如果想要查询list中所有元素的值,就需要使用lrange key 0 -1这个指令.
127.0.0.1:6379> lpush key1 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange key1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

谈到下标,我们往往就会关注下标越界的情况,在java中,要是数组或者线性表下表越界,就会抛出下表越界的异常.但是Redis中并没有采取上述的方案.Redis中的做法,==是直接尽可能的获取到给定区间的元素.==如果给定区间不合法,就会尽可能在不合法的区域中获取元素.此处对于下表的处理方式,类似与python中的列表切片.

127.0.0.1:6379> lrange key1 0 100
1) "4"
2) "3"
3) "2"
4) "1"

比如我们给出的范围是0~100,在这个区间内只有4321,那么Redis也只能获取4321这4个元素.

  • lpushx
    lpushx key element [element...]
    在指定的list的左边插入元素,这个指令和lpush最大的区别就是,如果这个key不存在的时候,不会自动创建key,只可以在已经存在的key的list中头插元素.
127.0.0.1:6379> lpushx key1 4 3 2 1
(integer) 8
127.0.0.1:6379> lrange key1 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "4"
6) "3"
7) "2"
8) "1"
127.0.0.1:6379> lpushx key2 4 3 2 1
(integer) 0
127.0.0.1:6379> get key2
(nil)

我们从上面的代码中可以看出,如果key不存在的时候,会返回0,而且不会主动创建key.

  • rpush
    rpush key element [element...]
    在list的右边插入指定的元素(这里的r就是right的缩写),可以一次插入多个元素,也可以一次插入一个元素.如果key不存在,创建列表,如果已经创建了key,key对应的value必须是列表类型,否则报错.
127.0.0.1:6379> rpush key 1 2 3 4 
(integer) 4
127.0.0.1:6379> lrange key 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
  • rpushx
    在指定的list的右边插入元素,这个指令和rpush最大的区别就是,如果这个key不存在的时候,不会自动创建key,只可以在已经存在的key的list中头插元素.
127.0.0.1:6379> rpushx key3 1 2 3 4
(integer) 0
127.0.0.1:6379> get key3
(nil)
127.0.0.1:6379> rpushx key 1 2 3 4
(integer) 8
127.0.0.1:6379> lrange key 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "1"
6) "2"
7) "3"
8) "4"
  • lpop
    lpop key
    从list的最左边取出元素,即头删.
127.0.0.1:6379> lpop key
"1"
127.0.0.1:6379> lpop key
"2"
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "4"
3) "1"
4) "2"
5) "3"
6) "4"
  • rpop
    从list的右边取出元素,即尾删
127.0.0.1:6379> rpop key
"4"
127.0.0.1:6379> rpop key
"3"
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "4"
3) "1"
4) "2"

在Redis5的版本中,没有设置count参数,即一次可以pop元素的个数,但是从6.2开始,新增了一个count参数,可以指定pop元素的个数.比如 rpop key [count].

Redis中的list相当于一个双端队列,从两头插入/删除元素都非常高效,搭配使用rpush和lpop就相当于队列,搭配使用rpush和rpop就相当于栈.

  • lindex
    lindex key index
    获取指定位置的元素.如果下标是非法的,返回的就是nil
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "4"
3) "1"
4) "2"
127.0.0.1:6379> lindex key 2
"1"
127.0.0.1:6379> lindex key 100
(nil)
  • linsert
    linsert key <before|after> pivot element
    在list中指定元素的位置插入指定的元素.可以在指定元素的左边插入,也可以在指定元素的右边插入.在查找list中指定元素的时候,如果在list中找到了多个基准值,值插入第一个.返回值是插入之后得到的心得list长度.
127.0.0.1:6379> rpush key 4 4 
(integer) 6
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "4"
3) "1"
4) "2"
5) "4"
6) "4"
127.0.0.1:6379> linsert key before 4 22
(integer) 7
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "4"
4) "1"
5) "2"
6) "4"
7) "4"
127.0.0.1:6379> linsert key after 4 22
(integer) 8
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "4"
4) "22"
5) "1"
6) "2"
7) "4"
8) "4"
  • llen
    llen key
    获取list的长度
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "4"
4) "22"
5) "1"
6) "2"
7) "4"
8) "4"
127.0.0.1:6379> llen key
(integer) 8
  • lrem
    lrem key count element
    删除list中指定的值,其中count是要删除的个数,element是要删除的元素.
    其中,count > 0的时候,从list的左边开始删除指定个数的元素,count = 0的时候,将指定的元素全部删除.当count < 0的时候,从list的右边开始删除指定个数的元素.
127.0.0.1:6379> lrem key 1 4
(integer) 1
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "22"
4) "1"
5) "2"
6) "4"
7) "4"
127.0.0.1:6379> lrem key -2 4
(integer) 2
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "22"
4) "1"
5) "2"
127.0.0.1:6379> lpush key 4 4 4
(integer) 8
127.0.0.1:6379> lrem key 0 4
(integer) 3
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "22"
4) "1"
5) "2"
  • ltrim
    itrim key start stop
    保留指定区间(闭区间)之内的元素,其他元素全部删除.
127.0.0.1:6379> lrange key 0 -1
1) "3"
2) "22"
3) "22"
4) "1"
5) "2"
127.0.0.1:6379> ltrim key 1 3
OK
127.0.0.1:6379> lrange key 0 -1
1) "22"
2) "22"
3) "1"
  • lset
    lset key index element
    将指定下标的元素修改为指定元素.
    注意: 这里不像lrange那样下标可以越界,这里的下标如果越界了,会报错.
127.0.0.1:6379> lrange key 0 -1
1) "22"
2) "22"
3) "1"
127.0.0.1:6379> lset key 1 44
OK
127.0.0.1:6379> lset key 5 55
(error) ERR index out of range
127.0.0.1:6379> lrange key 0 -1
1) "22"
2) "44"
3) "1"

4.4 阻塞版本指令

4.4.1 特点概述

  • 阻塞指的就是: 当前线程的代码不会继续执行,会在满足一定条件之后唤醒.但是只有当前客户端表现为阻塞状态,不会影响到其他客户端的Redis指令的执行.
  • 如果list中存在元素,blpop,brpop的效果和不加b(这里的b就是block的缩写)完全一样.如果list不存在元素,blpop,brpop就会阻塞等待,一直阻塞到list不为空或者是超时为止.

说到这里,我们可以回忆一下我们java中的BlockingQueue.java中的阻塞队列主要用于生产者消费者模型.它一方面主要用于生产者和消费者的削峰填谷,另一方面用于解除生产者和消费者的强耦合.

  • Redis这里的list与阻塞相关的指令也是一样.只是这里的线程安全是通过单线程来实现的,阻塞只支持"队列为空"的情况,不支持"队列为满"的情况,和阻塞相关的指令只有pop相关的操作.
  • 这里的阻塞等待也不是无休止的阻塞等待,我们可以自定义阻塞等待的时间.
  • 命令中如果设置了多个键,会从头到尾遍历所有的键,一旦有个一键对应的列表中可以弹出元素,命令立即返回.也就是blpop和brpop都可以同时尝试获取多个key的列表元素,多个key对应多个list,哪个list中有元素,就返回哪个元素.
  • 如果有多个客户端同时对一个键执行pop,则最先执行命令的客户端会得到弹出的元素.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

4.4.2 指令

  • blpop
    blpop key [key...] timeout
    指定要弹出元素的list对应的key,这个key可以有多个,可以只有一个,命令中如果设置了多个键,会从头到尾遍历所有的键,一旦有个一键对应的列表中可以弹出元素,命令立即返回.可以指定阻塞等待的时间,如果在等待时间之内list中新增了元素,则立即返回.如果超时,则返回nil.如果获取到元素,返回的值是一个二元组,分别是得到返回值的key(也就是告诉我们当前数据来自于哪个key)和list中弹出的值(数据是什么).
127.0.0.1:6379> lpush key2 100
(integer) 1
127.0.0.1:6379> blpop key2 5
1) "key2"
2) "100"//有元素立即弹出,无需等待
127.0.0.1:6379> lpush key3 100
(integer) 1
127.0.0.1:6379> lpush key4 100
(integer) 1
127.0.0.1:6379> blpop key2 key3 key4 5
1) "key3"//弹出第一个获取到元素的key中的元素
2) "100"
127.0.0.1:6379> blpop key3 5
(nil)
(5.04s)//如果指定的key中没有元素,阻塞等待,最后返回nil
//客户端1
127.0.0.1:6379> blpop key3 100
1) "key3"
2) "1"
(33.40s)
//客户端2
127.0.0.1:6379> lpush key3 1
(integer) 1//在一个客户端阻塞的期间,不影响其他客户端的命令执行
//在等待期间,在客户端2中对key3插入元素,只要key3中有了元素,客户端1中阻塞等待的命令就会立即返回
  • brpop
    和blpop是同样的道理,只不过是尾删.

4.5 指令小结

在这里插入图片描述

5. list内部编码方式

在旧版本的Redis中,Redis中的编码方式分为了两种,一种是ziplist,一种是linkedlist.

  • ziplist
    这个ziplist的编码方式和hash中的ziplist的编码方式的限制条件是一样的,在list中的元素较少的时候(默认512个),或者是list中每个元素很短(默认不超过64字节).按照这种编码方式可以节省一定的空间,但是缺点就是读取的时候是比较慢的.
  • linkedlist
    在list内部的元素个数和每个元素的字节长度超过阈值的时候,就会转换为linkedlist.

但是在新版本中的Redis中,list的编码方式并不是采用这样的方式,它采用的是quicklist的方式.
关于quicklist,它相当于结合了ziplist和linkedlist两者的优点.整体还是一个链表,但是每个链表的结点是一个压缩链表.每个压缩列表都不是很大,这些研所列表是通过链式结构连接起来的.
在这里插入图片描述
在之前配置文件中的list-max-ziplist-entries和list-max-ziplist-value这两个属性由于list底层编码方式的改变,现在都不再使用了.

6. list的应用场景

  • 用list作为想数组这样的结构来存储数据
    假如我们有这样两种数据,一种是班级,一种是学生.
    在Redis中,我们存储学生信息的时候使用的是hash的方式来存储的,中存储的是学生的id,value中的hash中存储的是学生的各种不同的信息.存储班级信息的时候,key中存储的是class的id,value中存储的是该班级中有多少人.但是我们想要存储class中有哪些学生,我们就需要list存储,在key中存储的是class的id,在value中使用list存储的是学生的id.
    在这里插入图片描述

由于Redis只能存储键值对,并不像MySQL中使用表存储数据,并提供了丰富的查询功能,所以在Redis中如何组织数据,就要根据实际的业务场景来决定.

  • 用作消息队列
    list中的阻塞命令可以为Redis作为消息队列提供很好的支持.和java一样,Redis作为消息队列的时候,一般也是用于生产者消费者模型.
    在这里插入图片描述
    这里我们假如生产者只有一个,那么生产者就会把信息交给Redis中的列表,其中列表就是消息队列,消费者有好多个.==这里消费者在获取信息的时候,是通过轮训的方式来获取信息.==谁先执行的drpop,谁就可以先获取到信息,此消费者获取完信息之后,假如还想要使用brpop获取信息,就会到达消费者优先级的末尾.比如消费者执行的顺序是123,在1消费者执行完成之后,1消费者想要再次获取消息队列中的元素,这时候就要排到消费者优先级的末尾,也就是按照231的方式执行的.消费者2也是同样的道理.

具体说明: 买包子
假如滑稽老铁有一天想吃包子,他要去包子摊买包子,轮到他的时候,他买了2个包子,刚一出队列,一想到自己还没有给女票带早饭,又想返回头去再买一个包子,这时候滑稽老铁一定是不可以插回原来的位置的,他只能到队尾再次进行排队.
在这里插入图片描述

  • 分频道的消息队列
    我们在Redis中,可能不止一个列表在作为消息队列,可能有多个消息队列,不同的消息队列中保存的是不同主题的消息.一个消费者可以从多个频道中获取信息.每一个消息队列都和上面我们提到的消息队列的特点是一样的.这样搞成多个频道的消息队列,可以在某种主题的数据发生问题的时候,不会对其他的频道造成影响.
    在这里插入图片描述

http://www.kler.cn/a/307260.html

相关文章:

  • go T 泛型
  • mysql 快速解决死锁方式
  • 微服务电商平台课程三:搭建后台服务
  • [HNCTF 2022 Week1]ret2shellcode-好久不见12
  • AI 大模型如何赋能电商行业,引领变革
  • 数据库管理-第260期 业务向前,数据库向后(20241111)
  • 29 线性表 · 队列
  • 【人工智能】Transformers之Pipeline(十八):文本生成(text-generation)
  • C语言实现贪吃蛇小游戏
  • 【技术科普】揭秘图像处理:从零开始的计算机视觉之旅!
  • 海量数据查找最大K个值:数据结构与算法的选择
  • 【Node.js】初识微服务
  • CANopen协议的理解
  • 不用禁用 iptables 来解决 UFW 和 Docker 的安全问题
  • 智汇创想pytest接口自动化测试框架
  • 通俗地类比计算机视觉中各种层或操作的作用
  • 自动曝光算法
  • IDEA 常用插件推荐,美观又实用!
  • Vue生命周期;Vue路由配置;vue网络请求;vue跨域处理
  • vue3+ts 使用amCharts展示地图,1.点击左侧国家,可以高亮并放大右侧地图对应的国家。 2.展示数据球。
  • python tkinter
  • 物联网智能项目
  • Android Tools | 如何使用Draw.io助力Android开发:从UI设计到流程优化
  • 腾讯云使用
  • 将jar包作为lib导入和maven依赖导入有什么区别?
  • seafaring靶场渗透测试