go - NATS Jetstream 是否通过密钥提供消息排序?
问题描述
我是 NATS Jetstream 的新手,我一直在阅读他们的官方文档 ( https://docs.nats.io/jetstream/jetstream ) 以了解其概念并将其与 Kafka 进行比较。我拥有的主要用例之一是解决基于特定 id 的消息/事件排序(如partition key
Kafka 世界中的 a )。
例如,一个实体有几个更新事件,我的系统需要以相同的顺序Order
使用特定的事件。Order
在这种情况下,我会order-id
在发布到 Kafka 主题时将其用作分区键。我如何在 Jetstream 中做到这一点?
我在 Jetstream 中遇到过重复数据删除键 ( Nats-Msg-Id
),但我认为此功能更类似于 Kafka 中的主题压缩。我对吗?
尽管如此,我还是用 Golang 编写了以下代码进行发布:
order = Order{
OrderId: orderId,
Status: status,
}
orderJson, _ := json.Marshal(order)
dedupKey := nats.MsgId(order.OrderId)
_, err := js.Publish(subjectName, orderJson, dedupKey)
我这样做对吗?特定 orderId 的所有订单是否会转到 Jetstream 世界中消费者组内的同一消费者,从而保持顺序?
编辑 1
这是我从@tbeets 的建议中得到的。例如,我预定义了 10 个流主题,例如ORDER.1
, ORDER.2
, ORDER.3
....ORDER.10
在发布方面,我可以order-id%10+1
找到我想要发布的确切流主题。所以在这里,我们已经实现了相同 orderId 的所有更新事件每次都将转到相同的流主题。
现在,在订阅者方面,我有 10 个消费者组(每个消费者组中有 10 个消费者),每个消费者都从一个特定的流主题中消费,比如consumerGroup-1
从消费来源ORDER.1
、consumerGroup-2
消费来源ORDER.2
等等......
比如说,order-id
111 有 2 个订单更新事件,这将被映射到ORDER.1
流主题,并相应地consumerGroup-1
消耗这 2 个事件。但是在这个consumerGroup中,两个更新事件可以去到不同的消费者,如果其中一个消费者有点忙或有点慢,那么在整体层面上,订单更新事件消费可能不同步或乱序.
Kafka 使用分区键的概念解决了这个问题,因为消费者组的消费者被分配到特定的分区。因此,同一个 orderId 的所有事件都被同一个消费者消费,从而保持订单更新事件消费的顺序。如何在 Jetstream 中解决此问题?
解决方案
在 NATS 中,您的发布主题可以包含多个分隔标记。因此,例如,您的 Order 事件可以发布到 ORDER.{store}.{orderid} ,其中最后两个令牌特定于每个事件,并提供您的用例所需的任何切片和骰子维度。
然后为 ORDER.> 定义一个 JetStream(即所有事件)。可以在 JetStream 上创建 N 个消费者(临时的或持久的),每个消费者都有一个可选的过滤器定义,以满足您的用例需求(例如 ORDER.Store24.>)在底层流的消息上。JetStream 保证消息(过滤或未过滤)按接收顺序传递。
推荐阅读
- javascript - 移动视图菜单问题?
- c# - 为许多实现抽象类的类创建一个 DTO 是一种不好的做法吗?
- ios - UIGestureRecognizer 不向其他类发送操作
- c# - AleaGPU 适用于矩形内的点
- django-models - DRF - 在 SlugRelatedField 上使用包含字段查找的查询集过滤器
- mysql - 如果我 console.log 我的结果会显示,但如果我返回它不会
- testng - TestNG 如何处理子类中测试方法的重复优先级?
- node.js - 检查数组中是否存在未知字段
- java - 使用套接字打印原始文本
- go - 有没有办法在golang的一个进程中运行多个命令“os/exec”?