0

TLDR:有一个请求/响应模式。当前请求通过 activemq 队列完成,响应通过 memcached 键值存储(由前端轮询)完成。由于各种原因想迁移到 kafka,想知道我们是否可以重新设计响应路径以不使用 memcached。

我试图了解以下问题的最佳实践系统设计。

我们有一个生成需要大量处理的请求的前端。该应用程序需要响应才能前进。有时我们需要撤消/后退(这会让你回到之前的状态)。有一组后端可以执行繁重的处理步骤。

在我们当前的设置中,前端将请求推送到队列中(当前为 activemq),后端尽可能处理队列中的项目并将结果存储在键值存储(memcached)中,键是来自消息的 UUID队列(它本身就是一个唯一的会话 id + 非唯一的步骤 id)。前端正在轮询存储以获取消息的 UUID。这样做的好处是前端可能会丢失连接/等,但只要保留会话 ID,我们就可以 ping 键值存储以获得我们需要的结果。我们有时还需要后退/撤消操作,我们可以在键值存储中返回结果(因为每个步骤都有自己的 UUID 并且所有 UUID 都是已知的)。

然而,在未来,我们希望能够至少部分通过队列进行响应,这样我们就可以拥有一些分析工具作为请求和响应的消费者。“最小的改变”是让响应生产者推入队列并让 memcached 成为消费者之一。但也许有更好的方法。我们也在考虑从 activemq 切换到 Kafka,因为这会给我们带来可重玩性(但我们没有使用 kafka 的经验)。

看看 Kafka,它看起来像是要获得一条特定的消息,您需要扫描整个分区,有没有更简单的方法来检索特定的消息?我们是否为每个交互序列生成一个主题?如果我们想重播但不知道偏移量,我们有什么办法(除了查看很多消息)?我们的负载非常小(约 1 百万条消息/天),所以我想任何方法都可以,但最佳实践是什么(臭名昭著,如果我们扩大规模会怎样)?

4

1 回答 1

2

据我了解您的用例,您没有一种有效的方式通过推送将响应传递给应用程序,这就是为什么您让应用程序可以通过 id(键)拉取响应。您可以切换各种组件,例如用于 Kafka 的 ActiveMQ,用于任何其他 KV 存储的 memcached,但最终,如果您的限制是应用程序需要从服务器中提取结果,您将始终必须使用异步的响应传输并使它们在服务器上可用。例如,如果您切换到 Kafka,您可以将您的消费者实现为 Kafka Streams 中的 [global] KTable 并以这种方式提供响应,但这仍然只是一个带有额外步骤的 KV 存储。没有直接从 Kafka 主题获取特定消息/偏移量的好方法,这并不是它的真正用途。

在不了解更多细节的情况下,将异步传​​输组件(ActiveMQ、Kakfa 等)与服务组件分开似乎是明智的,以便能够单独扩展或交换它们。例如,如果您扩展到不再适合单个 memcached 实例的内存的大小,您可以直接迁移到任意数量的分布式 KV 存储,如 Redis、Couchbase、DynamoDB 等。

于 2019-07-31T08:25:56.220 回答