========================== 2017/3/31更新=======================
redisson实现了分布式和可扩展的java数据结构,支持的数据结构有:List, Set, Map, Queue, SortedSet, ConcureentMap, Lock, AtomicLong, CountDownLatch。并且是线程安全的,底层使用Netty 4实现网络通信。和jedis相比,功能比较简单,不支持排序,事务,管道,分区等redis特性,可以认为是jedis的补充,不能替换jedis。
redission.getQueue支持队列
==============================================================
在redis支持的数据结构中,有一个是集合list. 对List的操作常见的有lpush lrange等。在这种常见的操作时,我们是把集合当做典型意义上的‘集合’来使用的。往往容易被忽视的是List作为“队列”的使用情况。
反编译redis的jar包,会发现:
public String rpop(String key) { checkIsInMulti(); this.client.rpop(key); return this.client.getBulkReply(); } public String rpoplpush(String srckey, String dstkey) { checkIsInMulti(); this.client.rpoplpush(srckey, dstkey); return this.client.getBulkReply(); } public String lpop(String key) { checkIsInMulti(); this.client.lpop(key); return this.client.getBulkReply(); }
pop意为“弹”,是队列里的取出元素。rpop意为"right pop"意思就是从队列的右边取元素,lpop就是"left pop"当然就是从队列的左边取元素了。对应取元素,我们往队列里面Push元素同样有2个方向:
public Long lpush(String key, String[] strings) { checkIsInMulti(); this.client.lpush(key, strings); return this.client.getIntegerReply(); } public Long rpush(String key, String[] strings) { checkIsInMulti(); this.client.rpush(key, strings); return this.client.getIntegerReply(); }
好了,下面正式开始测试下redis中List数据结构作为队列的使用方法:
假设我需要往队列里面Push map,该怎么做呢? push String值的话比价简单,这里不再研究了……
往队列里push map的话,有以下2种方式:
第一种:
往队列里push一个map:
class PushThread implements Runnable { @Override public void run() { Jedis jedis = null; try{ jedis = JedisPoolUtils.getJedis(); for(int i=0; i<10; i++) { Map map = new HashMap(); map.put("test", "test" + i); map.put("ok", "ok" + i); jedis.lpush("test".getBytes(), ObjectUtils.objectToBytes(map));//Object对象转换成byte数组的方法,这里省略 } } catch(Exception e) { e.printStackTrace(); } finally{ JedisPoolUtils.returnRes(jedis); } } }
从队列里取出map:
class PopThread implements Runnable { @Override public void run() { Jedis jedis = null; try{ jedis = JedisPoolUtils.getJedis(); for(int i=0; i<10; i++) { byte[] key = jedis.rpop("test".getBytes()); System.out.println("弹出:" + ObjectUtils.bytesToObject(key));//byte数组转换为Object对象的方法,这里省略 } } catch(Exception e) { e.printStackTrace(); } finally{ JedisPoolUtils.returnRes(jedis); } }
依次启动Push线程和pop线程,可在pop线程端看到打印结果:
弹出:{ok=ok0, test=test0}
弹出:{ok=ok1, test=test1}
弹出:{ok=ok2, test=test2}
弹出:{ok=ok3, test=test3}
弹出:{ok=ok4, test=test4}
弹出:{ok=ok5, test=test5}
弹出:{ok=ok6, test=test6}
弹出:{ok=ok7, test=test7}
弹出:{ok=ok8, test=test8}
弹出:{ok=ok9, test=test9}
第二种方式:
因为第一种方式毕竟需要在byte数组和Object对象之间来回转换,效率上可能存在一定影响。所以我们加以改进。不妨只把map的key放在一个队列中,取队列元素时,只取key,然后根据key取map即可。
push:
class PushThread implements Runnable { @Override public void run() { Jedis jedis = null; try{ jedis = JedisPoolUtils.getJedis(); for(int i=0; i<10; i++) { Map map = new HashMap(); map.put("test", "test" + i); map.put("ok", "ok" + i); String key = "map" + i; jedis.lpush("test", key);//把所有map的key放入一个队列test中 jedis.hmset(key, map); } } catch(Exception e) { e.printStackTrace(); } finally{ JedisPoolUtils.returnRes(jedis); } }
pop元素:
class PopThread implements Runnable { @Override public void run() { Jedis jedis = null; try{ jedis = JedisPoolUtils.getJedis(); for(int i=0; i<10; i++) { String key = jedis.rpop("test"); System.out.println("弹出:" + jedis.hgetAll(key)); } } catch(Exception e) { e.printStackTrace(); } finally{ JedisPoolUtils.returnRes(jedis); } } }
依次启动Push线程和pop线程,可在pop线程端看到打印结果:
弹出:{test=test0, ok=ok0}
弹出:{test=test1, ok=ok1}
弹出:{test=test2, ok=ok2}
弹出:{test=test3, ok=ok3}
弹出:{test=test4, ok=ok4}
弹出:{test=test5, ok=ok5}
弹出:{test=test6, ok=ok6}
弹出:{test=test7, ok=ok7}
弹出:{test=test8, ok=ok8}
弹出:{test=test9, ok=ok9}
两种方式效果一样,只不过第二种效率上更好一些。
注:当你依次从队列里取出元素后,队列在redis中就不存在了,所以当你pop完元素,再尝试pop的话,会报异常:
redis.clients.jedis.exceptions.JedisDataException: value sent to redis cannot be null
同时,redis中这个队列也不复存在了!
利用redis作为队列的性质我们可以用它来达到类似ZMQ的作用。。
相关推荐
在本场景中,Redis作为消息队列使用,替代了传统的Kafka队列,以实现顺序消费和防止高并发时的内存溢出问题。 Redis支持多种数据结构,如字符串、哈希、列表、集合和有序集合等,这些数据结构可以巧妙地应用于消息...
【微服务SpringBoot整合Redis基于Redis的Stream消息队列实现异步秒杀下单】这篇文章主要讲解了如何在微服务架构中使用SpringBoot整合Redis来构建一个基于Redis Stream的消息队列,以此来实现实时、高效的异步秒杀...
2. **创建消息队列**:在Redis中,可以使用`LPUSH`命令将消息推入列表,作为队列的后端。当消费者处理消息时,使用`RPOP`或`BLPOP`命令取出并删除消息。如果希望避免消息丢失,可以使用`LPOP`配合阻塞操作,当队列为...
标题中的“Redis延时消息队列基于swoole实现的多进程消费端”是指使用Redis作为消息队列,结合Swoole的多进程特性来构建一个高效、可扩展的延迟消息处理系统。在这个系统中,Redis作为一个可靠的键值存储,用于暂存...
博文a 中的老师,提供了Redis 实现消息队列...整体思路在博文a 中老师已经介绍,及依靠 mvc 框架,通过web端用户提交事件,实现消息入列,通过定时器(Timer)实现按照时间间隔的消息出列,Redis 作为存储媒介,存储消
基于Redis的消息队列之发布订阅模式是指使用Redis作为消息队列的中间件,实现消息的发布和订阅。该模式下,消息的生产者将消息发布到Redis中,而消费者则可以从Redis中订阅和消费消息。该模式可以实现消息的异步处理...
Redis作为一款高性能的键值数据库,常被用于构建消息队列,因为它提供了丰富的数据结构(如列表、集合、通道等)和原子操作,非常适合于实现消息的发布与订阅、入队与出队等操作。 在PHP中,我们可以使用Predis或...
标题中的“基于redis实现的消息队列”指的是使用Redis这一开源数据结构存储系统来构建消息队列(Message Queue, MQ)的解决方案。Redis以其高性能、丰富的数据结构和内存存储特性,常被用作构建消息队列的底层技术。...
1. 队列结构:Redis 中的消息队列通常使用 List 或 Stream 数据结构实现。List 可以看作是先进先出(FIFO)的数据结构,而 Stream 提供了更丰富的消息管理功能,包括时间戳和消息ID。 2. 生产者:生产者通过 `LPUSH...
`Redis`作为队列驱动,提供了可靠的消息传输和存储。 整合以上技术,我们可以这样实现聊天系统: 1. 用户通过客户端与`GatewayWorker`建立长连接,`GatewayWorker`记录用户的连接状态。 2. 用户发送消息到服务器,...
Redis作为一个内存数据库,具有高并发、低延迟的特性,非常适合做消息队列的存储。Go-Delayer通过Redis的有序集合(Sorted Set)数据结构来存储延迟消息,其中每个消息都有一个时间戳作为分数,这样可以方便地按时间...
消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器。在目前广泛的Web应用中,都会出现一种场景:在某一个时刻,网站会迎来一个用户请求的高峰期(比如:淘宝的双十一购物狂欢节,12306的春运抢票...
Redis作为消息代理,其丰富的数据结构(如字符串、列表、哈希表等)和丰富的操作命令为实现消息队列提供了便利。例如,我们可以利用Redis的`LPUSH/RPOP`命令来构建一个FIFO(先进先出)的消息队列。消息生产者通过`...
同时,为了保证数据的一致性,可以使用Channel作为队列的同步原语,确保消息被正确且唯一的消费。 2. **Topic与Group注册**:在消息队列设计中,Topic通常用于消息分类,允许生产者将不同类型的事件发送到不同的...
本文将详细介绍如何使用Python的redis库来操作Redis以及处理消息队列。 首先,我们需要导入`redis`库,然后创建一个连接池`redisPool`,通过指定Redis服务器的IP地址、端口和数据库编号。例如: ```python import ...
3. **Redis**: Redis作为内存数据库,适用于高速读写场景。面试时会测试对键值对数据结构的理解(如字符串、哈希、列表、集合、有序集合),以及Redis持久化机制(RDB和AOF)、事务、发布订阅、主从复制和哨兵系统等...
本文将深入探讨Redis作为消息队列的实现及其相关知识点。 1. **Redis消息队列的基础概念** - **发布/订阅(Pub/Sub)模式**:Redis提供了简单的消息发布订阅功能,允许一个或多个客户端订阅特定的频道,当有其他...
Redis作为一个内存数据库,具有快速读写的能力,因此非常适合用作消息队列的底层存储。 在构建基于Redis的消息队列时,我们需要引入一系列的依赖。从提供的`pom.xml`文件中可以看出,项目继承自`common-parent`,并...
总结起来,使用Redis作为任务队列分发子任务,能够充分利用其高性能和丰富的特性,提升分布式系统中任务处理的效率和可靠性。在实际项目中,结合业务需求,合理设计任务队列的架构和策略,可以进一步优化系统性能,...