Readis Streams概念与分组消费

目录

Redis Streams 介绍

Streams命令

1.往stream里写入键值对

2.stream中的条目数

3.查询stream中的最大条目数

4.监听条目

5.消费组与消费者

在SpringBoot中使用

配置类

监听类


Redis Streams 介绍

Stream是Redis 5.0版本引入的一个新的数据类型。

Stream是Redis的数据类型中最复杂的,尽管数据类型本身非常简单,它实现了额外的非强制性的特性:提供了一组允许消费者以阻塞的方式等待生产者向Stream中发送的新消息,此外还有一个名为消费者组的概念。消费者组最早是由名为Kafka(TM)的流行消息系统引入的。

Streams命令

1.往stream里写入键值对

> xadd mystream * testKey testValue
"1603249448596-0"

参数值是*,因为我们希望由Redis服务器为我们自动生成一个新的条目ID。由服务器自动生成条目ID几乎总是我们所想要的,需要显式指定ID的情况非常少见。

条目 ID

条目ID由XADD命令返回,并且可以唯一的标识给定Stream中的每一个条目,由两部分组成:

<millisecondsTime>-<sequenceNumber>
例如"1603249448596-0"

2.stream中的条目数

> xlen mystream
(integer) 2

3.查询stream中的最大条目数

要根据范围查询Stream,我们只需要提供两个条目ID,即startend。返回的区间数据将会包括ID是start和end的元素,因此区间是完全包含的。两个特殊的ID-+分别表示可能的最小ID和最大ID。

> xrange mystream - +
1) 1) "1603249448596-0"
   2) 1) "lgl"
      2) "1"
2) 1) "1603249454137-0"
   2) 1) "lgl"
      2) "1"
3) 1) "1603249814032-0"
   2) 1) "testKey"

获取最近一条的条目

> xrevrange mystream + - COUNT 1
1) 1) "1603249814032-0"
   2) 1) "testKey"
      2) "testValue"

4.监听条目

> xread streams mystream 0

0表示要监听的条目ID必须大于0。

阻塞等待最新的条目

> XREAD BLOCK 0 STREAMS mystream $

指定了新的BLOCK选项,超时时间为0毫秒(意味着永不超时)。

$表示最大条目ID,。

5.消费组与消费者

1)创建一个消费者组

> xgroup create mystream mygroup $

目前只能为存在的Stream创建消费者组。 $表示这个组需要等待新的条目。

2)消费者消费组里的条目

> xreadgroup group mygroup comsumer1 COUNT 1 STREAMS mystream >

表示消费者comsumer1使用消费者组mygroupmystream中读取条目。

>表示最新条目且未被消费过的。

3)例子

comsumer1

> xreadgroup group mygroup comsumer1 COUNT 1 block 0 STREAMS mystream >

comsumer2

> xreadgroup group mygroup comsumer2 block 0 COUNT 1 STREAMS mystream >

往流写条目

 > xadd mystream * testKey testValue

相同组内只有一个消费者消费到消息。

这种拉模式解决了Redis发布/订阅模式(推模式)中,订阅者可能重复消费的问题。

在SpringBoot中使用

配置类

@Component
public class RedisSubscriberConfig {
    @Bean("streamListener")
    RedisAuthTicketStreamListener streamListener() {
        return new RedisAuthTicketStreamListener();
    }
    @Bean("containerOptions")
    StreamMessageListenerContainer.StreamMessageListenerContainerOptions<string, maprecord<string, string, string>&gt; containerOptions() {
        return StreamMessageListenerContainer.StreamMessageListenerContainerOptions.builder()
                                                                                   .pollTimeout(Duration.ofMillis(100)).build();
    }
    @Bean
    StreamMessageListenerContainer<string, maprecord<string, string, string>&gt; streamContainer(RedisConnectionFactory connectionFactory,
        @Qualifier("containerOptions")
        StreamMessageListenerContainer.StreamMessageListenerContainerOptions<string, maprecord<string, string, string>&gt; containerOptions
            ,@Qualifier("streamListener") RedisAuthTicketStreamListener streamListener) {
        StreamMessageListenerContainer<string, maprecord<string, string, string>&gt; container =
                StreamMessageListenerContainer.create(connectionFactory, containerOptions);
        container.start();

        Subscription //subscription = container.receive(StreamOffset.fromStart(Constant.REDIS_CHANNEL_MAKE_TICKET), streamListener);
        subscription = container.receive(Consumer.from("ticket-group", "ticket-customer"),
                          StreamOffset.create(Constant.REDIS_CHANNEL_MAKE_TICKET, ReadOffset.lastConsumed()),
                                                      streamListener);
        return container;
    }
}


监听类

public class RedisAuthTicketStreamListener implements StreamListener<string, maprecord<string, string, string>&gt; {

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    AuthTicketDao authTicketDao;

    @Override
    public void onMessage(MapRecord<string, string, string> record) {
        System.out.println("test");
        AuthTicketEntity authTicketEntity = new AuthTicketEntity();
        try {
            Map<string,string> map = record.getValue();
       authTicketEntity.setTicketSn(Long.parseLong(map.get("ticketSn")));
            authTicketEntity.setTicket(map.get("ticket"));
            
            ...
        } catch (Exception ex) {
           ...
        }
        redisTemplate.opsForStream().acknowledge("ticket-group", record);
    }
}


参考官方教程 http://www.redis.cn/topics/streams-intro.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值