Redis Streams简介

1 篇文章 0 订阅
Redis Streams是Redis 5.0引入的新数据类型,模仿日志结构,提供更丰富的操作。它支持仅附加数据,拥有ID来标识条目,允许按时间范围查询。通过XRANGE和XREVRANGE命令可以进行范围查询,XRANGE用于正向遍历,XREVRANGE则用于反向遍历。此外,Redis Streams还支持消费者组,实现消息的分区处理。
摘要由CSDN通过智能技术生成

Stream是Redis 5.0引入的一种新数据类型,它以更抽象的方式模拟日志数据结构,但日志的本质仍然完好无损:像日志文件一样,通常实现为仅附加模式打开的文件, Redis流主要是仅附加数据结构。至少在概念上,因为Redis Streams是一种在内存中表示的抽象数据类型,它们实现了更强大的操作,以克服日志文件本身的限制。

是什么让Redis流式传输最复杂的Redis,尽管数据结构本身非常简单,它实现了额外的非强制性功能:一组阻塞操作允许消费者等待生产者添加到流中的新数据,此外还有一个名为Consumer Groups的概念。

消费者群体最初由称为Kafka(TM)的流行消息系统引入。Redis以完全不同的方式重新实现了类似的想法,但目标是相同的:允许一组客户端合作消费同一消息流的不同部分。

 

认识Streams

为了理解Redis流是什么以及如何使用它们,我们将忽略所有高级功能,而是根据用于操作和访问它的命令来关注数据结构本身。这基本上是大多数其他Redis数据类型共有的部分,如列表,集合,排序集等。但是,请注意,列表还有一个可选的更复杂的阻塞API,由BLPOP等命令导出。因此,流与这方面的列表没有太大的不同,只是附加的API更复杂,更强大。

由于流是仅附加数据结构,因此基本写入命令(称为XADD)会将新条目附加到指定的流中。流条目不仅仅是一个字符串,而是由一个或多个字段 - 值对组成。这样,流的每个条目都已经结构化,就像仅以CSV格式编写的附加文件,其中每行中存在多个分离的字段。

 

> XADD mystream * sensor-id 1234 temperature 19.8
1518951480106-0

上面对XADD命令的调用使用自动生成的条目ID sensor-id: 123, temperature: 19.8在密钥处向流添加条目,该mystream条目ID是命令返回的条目ID,具体而言1518951480106-0。它将键名称作为第一个参数mystream,第二个参数是标识流中每个条目的条目ID。但是,在这种情况下,我们通过了*因为我们希望服务器为我们生成新的ID。每个新ID都会单调增加,因此更简单地说,添加的每个新条目与过去的所有条目相比都会有更高的ID。服务器自动生成ID几乎总是您想要的,并且明确指定ID的原因非常少见。我们稍后会详细讨论这个问题。每个Stream条目具有ID的事实是与日志文件的另一个相似性,其中可以使用行号或文件内的字节偏移来识别给定条目。返回我们的XADD示例,在键名和ID之后,下一个参数是组成我们的流条目的字段 - 值对。

只需使用XLEN命令就可以获取Stream中的项目数:

> XLEN mystream
(integer) 

条目ID

XADD命令返回的条目ID ,以及在给定流中唯一地标识每个条目,由两部分组成:

<millisecondsTime>-<sequenceNumber>

毫秒时间部分实际上是生成流ID的本地Redis节点中的本地时间,但是如果当前毫秒时间恰好小于前一个入口时间,则使用前一个入口时间,因此如果时钟向后跳跃单调递增的ID属性仍然存在。序列号用于以相同毫秒创建的条目。由于序列号是64位宽,实际上在相同的毫秒内可以生成的条目数没有限制。

这些ID的格式最初可能看起来很奇怪,温和的读者可能想知道为什么时间是ID的一部分。原因是Redis通过ID支持范围查询。由于ID与生成条目的时间相关,因此可以基本上免费查询时间范围。在覆盖XRANGE命令时,我们很快就会看到这一点。

如果由于某种原因,用户需要与时间无关但实际上与另一个外部系统ID关联的增量ID,如前所述,XADD命令可以采用显式ID而不是*触发自动生成的通配符ID,如在以下示例中:

> XADD somestream 0-1 field value
0-1
> XADD somestream 0-2 foo bar
0-2

请注意,在这种情况下,最小ID为0-1,并且命令将不接受等于或小于前一个ID的ID:

> XADD somestream 0-1 foo bar
(error) ERR The ID specified in XADD is equal or smaller than the target stream top item

 

从Streams获取数据

现在我们终于可以通过XADD在我们的流中添加条目了。但是,虽然将数据附加到流中非常明显,但是为了提取数据而查询流的方式并不那么明显。如果我们继续对日志文件进行类比,一种显而易见的方法是模仿我们通常使用Unix命令做的事情tail -f,也就是说,我们可能会开始监听以获取附加到流的新消息。请注意,与Redis的阻止列表操作不同,其中给定元素将到达在BLPOP流行样式操作中阻塞的单个客户端,我们希望多个消费者可以看到附加到流的新消息,如许多tail -f进程可以查看添加到日志的内容。使用传统术语,我们希望流能够将消息扇出到多个客户端。

但是,这只是一种潜在的访问模式。我们还可以以完全不同的方式看到流:不是作为消息传递系统,而是作为时间序列存储。在这种情况下,也许附加新消息也很有用,但另一种自然查询模式是按时间范围获取消息,或者使用游标迭代消息以逐步检查所有历史记录。这绝对是另一种有用的访问模式。

最后,如果我们从消费者的角度看到流,我们可能希望以另一种方式访问​​流,即,作为可以分区到处理此类消息的多个消费者的消息流,以便消费者群体只能看到到达单个流的消息的子集。通过这种方式,可以跨不同的消费者扩展消息处理,而不需要单个消费者处理所有消息:每个消费者只需要处理不同的消息。这基本上是Kafka(TM)与消费者群体的关系。通过消费者组阅读消息是另一种从Redis流中读取的有趣模式。

Redis流通过不同的命令支持上述三种查询模式。接下来的部分将展示所有它们,从最简单和更直接的使用:范围查询开始。

按范围查询:XRANGE和XREVRANGE

要按范围查询流,我们只需要指定两个ID,即开始结束。返回的范围将包括具有ID的开头或结尾的元素,因此范围是包含的。这两种特殊标识-,并+分别意味着最小和最大的ID可能。

> XRANGE mystream - +
1) 1) 1518951480106-0
   2) 1) "sensor-id"
      2) "1234"
      3) "temperature"
      4) "19.8"
2) 1) 1518951482479-0
   2) 1) "sensor-id"
      2) "9999"
      3) "temperature"
      4) "18.2"

返回的每个条目都是两个项目的数组:ID和字段 - 值对列表。我们已经说过条目ID与时间有关系,因为在-创建条目的那一刻,字符左边的部分是创建流条目的本地节点的Unix时间(以毫秒为单位)(但请注意使用完全指定的XADD命令复制流,因此从属服务器将具有与主服务器相同的ID。这意味着我可以使用XRANGE查询一系列时间。但是,为了做到这一点,我可能想要省略ID的序列部分:如果省略,则在范围的开头将假设为0,而在最后部分,它将被假定为最大值序列号可用。这样,使用仅两毫秒Unix时间查询,我们以包含的方式获得在该时间范围内生成的所有条目。例如,我可能想查询我可以使用的两毫秒时间:

> XRANGE mystream 1518951480106 1518951480107
1) 1) 1518951480106-0
   2) 1) "sensor-id"
      2) "1234"
      3) "temperature"
      4) "19.8"

我在这个范围内只有一个条目,但是在实际数据集中,我可以查询小时数范围,或者在两毫秒内可能有很多项目,并且返回的结果可能很大。因此,XRANGE最后支持可选的COUNT选项。通过指定计数,我可以获得前N个项目。如果我想要更多,我可以获得最后一个ID,逐个递增序列,然后再次查询。让我们在下面的例子中看到这一点。我们开始用XADD添加10个项目(我没有说明,已经假设流mystream中填充了10个项目)。要开始我的迭代,每个命令获得2个项目,我从全范围开始,但计数为2。

> XRANGE mystream - + COUNT 2
1) 1) 1519073278252-0
   2) 1) "foo"
      2) "value_1"
2) 1) 1519073279157-0
   2) 1) "foo"
      2) "value_2"

为了继续使用接下来的两个项目进行迭代,我必须选择返回的最后一个ID,即将1519073279157-01添加到ID的序列号部分。请注意,序列号为64位,因此无需检查溢出。1519073279157-1在这种情况下,生成的ID 现在可以用作下一个XRANGE调用的新起始参数:

> XRANGE mystream 1519073279157-1 + COUNT 2
1) 1) 1519073280281-0
   2) 1) "foo"
      2) "value_3"
2) 1) 1519073281432-0
   2) 1) "foo"
      2) "value_4"

等等。由于XRANGE复杂度为O(log(N))要寻找,然后O(M)返回M个元素,所以命令具有对数时间复杂度,这意味着迭代的每一步都很快。因此XRANGE也是事实上的流迭代器,不需要XSCAN命令。

命令XREVRANGE相当于XRANGE但是以反转顺序返回元素,因此XREVRANGE的实际用途是检查Stream中的最后一项是什么:

> XREVRANGE mystream + - COUNT 1
1) 1) 1519073287312-0
   2) 1) "foo"
      2) "value_10"

请注意,XREVRANGE命令以相反的顺序获取startstop参数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值