redis streams
Roshan Kumar是Redis Labs的高级产品经理。
Redis Streams是Redis 5.0中引入的新数据结构,可让您创建和管理数据流。 在上一篇文章中 ,我展示了如何向流中添加数据,以及如何以多种方式读取数据。 在本文中,我将解释如何在Redis Streams中使用使用者组。 消费者组是一种在多个客户端之间分配消息流以加快处理速度或减轻较慢的消费者负担的方法。
在一个理想的世界中,数据生产者和消费者都以相同的速度工作,并且没有数据丢失或数据积压。 不幸的是,在现实世界中并非如此。 在几乎所有实时数据流处理用例中,生产者和消费者的工作速度都不同。 此外,有不止一种类型的消费者,每种消费者都有自己的要求和处理速度。 Redis Streams的功能集可极大地支持消费者,从而满足了这一需求。 其最重要的功能之一是消费群体。
何时使用Redis Streams消费者组
消费者组的目的是扩大您的数据使用过程。 让我们考虑一个示例-图像处理应用程序。 该解决方案需要三个主要组件:
- 捕获并存储图像的生产者(也许有一个或多个照相机);
- Redis Stream按到达顺序保存图像(在流数据存储中); 和
- 处理每个图像的图像处理器。
假设您的制作人每秒保存500张图像,并且图像处理器以其最大容量每秒仅处理100张图像。 这种速率差异将导致积压,您的图像处理器将永远无法追上。 解决此问题的一种简单方法是运行五个图像处理器(如图2所示),每个处理器处理一组互斥的图像。 您可以通过使用者组实现此目的,该使用者组使您能够划分工作负载并将其路由到其他使用者。
消费者组所做的不只是数据分区-它可以确保数据安全并支持灾难恢复。
Redis Streams消费群体的工作方式
使用者组是Redis流中的数据结构。 如图3所示,您可以将消费者组视为列表的集合。 可以想象的另一件事是没有任何消费者消费的物品清单-在我们的讨论中,我们称其为“未消费清单”。 当数据到达流中时,它会立即被推送到未使用的列表。
消费者组为每个消费者维护一个单独的列表,通常会附加一个应用程序。 在图3中,我们的解决方案有N个相同的应用程序(应用程序1,应用程序2,...。应用程序n),分别通过消费者1,消费者2,...消费者n读取数据。
当应用程序使用XREADGROUP命令读取数据时,将从未使用的列表中删除特定的数据条目,并将其推入属于各个使用者的未决条目列表中。 因此,没有两个使用者将使用相同的数据。
最后,当应用程序使用XACK命令通知流时,它将从使用者的未决条目列表中删除该项目。
现在,我已经解释了消费者组的基本知识,让我们更深入地研究数据生命周期的工作原理。
创建一个Redis Streams消费者组
您可以使用命令XGROUP CREATE创建一个新的使用者组,如下所示。
XGROUP CREATE mystream mygroup $ MKSTREAM
与XREAD一样,命令末尾的$符号指示流仅从该时间点开始传递新数据。 替代选项是0或流条目中的另一个ID。 当使用0时,流将从流的开始传送所有数据。
MKSTREAM创建一个新的流,在这种情况下为mystream(如果尚不存在)。
读取和管理Redis Stream数据
假设您有一个Redis Stream(mystream),并且已经创建了一个使用者组(mygroup),如上所示。 您现在可以添加名称为a,b,c,d和e的项目,如以下示例所示。
XADD mystream * name a
为名称a到e运行此命令将填充Redis Stream,mystream和使用者组mystream的未消费列表。 如图4所示。
在这里,您可以看到消费者Alice和Bob尚未开始工作。 应用程序A通过使用者Alice消费数据,而应用程序B通过Bob消费数据。
消耗Redis Streams数据
从组读取数据的命令是XREADGROUP。 在我们的示例中,当App A开始处理数据时,它调用使用者(Alice)来获取数据,如下所示:
XREADGROUP GROUP mygroup COUNT 2 Alice STREAMS mystream >
同样,应用B通过Bob读取数据,如下所示:
XREADGROUP GROUP mygroup COUNT 2 Bob STREAMS mystream >
最后的特殊字符>告诉Redis Streams仅获取未传递给任何其他使用者的数据条目。 还要注意,没有两个使用者将使用相同的数据,这将导致将数据从未使用的列表移至Alice和Bob,如图5所示。
从待处理条目列表中删除已处理的消息
使用者的未决条目列表中的数据将保留在那里,直到App A和App B向Redis Stream确认他们已成功使用了数据为止。 这是使用命令XACK完成的。 例如,应用A在消费了d和e之后会分别确认如下,它们的ID为1526569411111-0和1526569411112-0。
XACK mystream mygroup 1526569411111-0 1526569411112-0
XREADGROUP和XACK的组合类似于启动事务并提交它,从而确保数据安全。
运行XACK之后,假设App A执行了XREADGROUP,如下所示。 现在,数据结构类似于图6。
XREADGROUP GROUP mygroup COUNT 2 Alice STREAMS mystream >
从故障中恢复
如果App B在处理b和c时由于失败而终止,那么数据结构将如图7所示。
现在您有两个选择:
1.重新启动App B并从使用者(Bob)重新加载数据。
在这种情况下,应用B必须使用XREADGROUP命令从使用者(鲍勃)读取数据,但要有所不同。 App B会传递0(或ID低于已处理的上一个数据条目)而不是最后的>。 请记住,>将新数据从未消耗列表发送到使用者。
XREADGROUP GROUP mygroup COUNT 2 Bob STREAMS mystream 0
上面的命令将检索已经存储在消费者Bob列表中的数据条目。 它不会从未使用的列表中获取新数据。 App B可以在获取新数据之前遍历使用者Bob中的所有数据。
2.强制Alice从Bob索取所有数据,并通过App A处理它们。
如果由于节点,磁盘或网络故障而无法恢复App B,这将特别有用。 在这种情况下,任何其他使用者(例如Alice)都可以声明Bob的数据并继续处理该数据,从而防止服务中断。 要声明Bob的数据,必须运行两组命令:
XPENDING mystream mygroup - + 10 Bob
这将获取Bob的所有未决数据条目。 选项-和+获取整个范围。 如果b和c分别具有ID 1526569411113-0和1526569411114-0,则将Bob的数据移至Alice的命令如下:
XCLAIM mystream mygroup Alice 0 1526569411113-0 1526569411114-0
消费者组维护消耗列表中数据的运行时钟。 例如,当应用B读取b时,时钟开始计时,直到鲍勃收到ACK。 使用XCLAIM命令中的时间选项,您可以告诉使用者组仅移动闲置时间超过指定时间的数据。 您还可以通过传递0来忽略它,如上例所示。 这些命令的结果如图8所示。当您的使用者处理器之一速度较慢时,XCLAIM也会派上用场,从而导致未处理数据的积压。
在上一篇文章中 ,我们介绍了如何使用Redis Streams的基础知识。 我们在本文中进行了更深入的介绍,并解释了何时使用消费者组及其工作方式。 在管理数据分区,生命周期和数据安全方面,Redis Streams中的使用者组减轻了您的负担。 此外,消费者群体的横向扩展功能可以使许多实时应用受益。
在即将发表的有关Redis Streams的第三篇文章中,我将演示如何使用Redis Streams和Lettuce(一个基于Java的Redis开源库)开发实时分类应用程序。 同时,您可以通过在Redis项目网站上阅读Redis Streams教程来了解更多信息。
Roshan Kumar是 Redis Labs 的高级产品经理 。 他在软件开发和技术营销方面拥有丰富的经验。 Roshan曾在惠普和许多成功的硅谷初创公司工作,包括ZillionTV,Salorix,Alopa和ActiveVideo。 作为一个热情的程序员,他设计和开发了mindzeal.com,这是一个为年轻学生提供计算机编程课程的在线平台。 Roshan拥有计算机科学学士学位,并拥有圣塔克拉拉大学的MBA学位。
-
新技术论坛提供了一个以前所未有的深度和广度探索和讨论新兴企业技术的场所。 选择是主观的,是基于我们选择的技术,我们认为这些技术对InfoWorld读者来说是重要的,也是他们最感兴趣的。 InfoWorld不接受发布的营销担保,并保留编辑所有贡献内容的权利。 将所有查询发送到 newtechforum@infoworld.com 。
翻译自: https://www.infoworld.com/article/3321938/how-to-use-redis-streams.html
redis streams