【问题标题】:The architecture of one producer and several consumers in getting market data from Stock Exchange一个生产者和几个消费者从证券交易所获取市场数据的架构
【发布时间】:2019-09-29 21:26:41
【问题描述】:

我有一个场景,我需要使用一个提供市场数据的生产商(证券交易所)。每个市场数据消息都包含(“符号”、“价格”和“时间戳”)。

同时,我有 3 个消费者(服务器),每个消费者都会使用特定的“符号”来消费市场数据。例如,消费者 A 只会消费符号为“AAPL”、“AMZN”的市场数据,消费者 B 将消费符号为“GOOS”等的市场数据。

一个要求是消费者必须接收他们想要的符号的时间戳排序消息。

还有一个要求是消费者可以不时改变他们的偏好。就像消费者 A 可能开始消费带有符号“GOOS”的消息。

我应该如何设计这个架构?我知道我可能需要利用 Kafka MQ,但我不是这方面的专家。有人可以详细说明设计的方式吗?

【问题讨论】:

  • 我很好奇你是怎么敲定卡夫卡的。您是否评估过其他消息传递平台 - queues.io
  • 嗨@Andy,我不必使用Kafka,只是想看看Kafka是否提供了更多功能。你有什么想法吗?
  • 我也遇到了同样的问题。我正在尝试找出一个符合我们业务需求的消息传递平台,这就是我遇到上述链接的地方。根据您的要求,您似乎需要一个基于主题的消息传递平台(而不是基于队列)。您可以检查 AWS SNS 并查看是否适合您的需求。它的优势在于它由 AWS 管理。

标签: architecture apache-kafka message-queue


【解决方案1】:

您的设计可能包含以下组件

数据采集层:一个组件,将从交换中获取数据,并嵌入一个 Kafka 生产者,以便能够将数据发送到 Kafka。

消息层:这将是您的 Kafka 集群(多个代理,假设 3 个以启用复制)。在这个 Kafka 集群上,您需要创建一个具有多个分区的主题(比如说raw-market-data)。例如,如果您总共有 300 个符号,那么您可以选择创建 100 个分区(编号从 0 到 299),每个分区以 3 个符号结尾。

消费层:这是你的消费者运行的地方。您已经提到您将拥有该消费者的 3 个实例。

其他设计注意事项

分区策略

  • 运行在数据采集层的 Kafka 生产者可以将消息构造为{7, { "stockSymbol": "AAPL", "marketPrice": 57.10, "timestamp": "May 13th, 10:03:18 AM "} }。消息开头的数字7,即消息的键,指示该消息应该转到哪个分区。您需要在生产者中编写将特定股票代码映射到专用分区的逻辑。

  • 另一种选择是将消息构造为{"AAPL", { "stockSymbol": "AAPL", "marketPrice": 57.10, "timestamp": "May 13th, 10:03:18 AM "} }。您在消息的键中显式推送股票代码,然后 Kafka 的默认分区器将跳入并计算字符串 AAPL 的哈希值,并对分区数进行取模。然后,此计算的结果将确定此消息最终所在的分区。此选项有一个警告,即跨分区的符号分布可能并不总是均匀的。如果您想自己研究,请参考the actual source code of the default partitioner

  • 第三个选项是编写您自己的自定义分区程序。这是reference article with an example

  • 分区的实际数量将取决于各种其他因素,例如总吞吐量、代理数量、消费者实例数量(即并行单位等)。

消费策略

  • 通常情况下,消费者实例将由 Kafka 自动分配分区 - 默认分配是使用 RangeAssignor 完成的。例如,如果你有 8 个分区(编号从 0 到 7)和 3 个消费者(c1、c2 和 c3),那么 Kafka 会将分区 {0, 1, 2} 分配给 c1{3, 4, 5} 分配给 c2 和 @987654334 @到c3。您可以通过直接调用 assign() 方法将特定分区分配给特定使用者,也可以通过实现 this interface 来编写自定义分配器。

  • 关于您根据时间戳对消息进行排序的要求。现在,这是 Kafka 无法保证的。消息将按照它们到达的顺序推送到主题,因此如果有 2 条消息的时间戳为 t1t2t1 < t2 并且由于某种原因带有 t2 时间戳的消息首先到达,那么这将是在带有t1 时间戳的消息之前使用。因此,您需要在您的消费者应用程序实例中处理此问题 - 我过去曾使用 TreeMap 数据结构,而 timestamp 作为实现此目的的关键。

  • 关于更改消费偏好的要求 - 最好实现自定义分区分配器(在消费策略的第 1 点中提到),这将使您能够处理这个问题,因为这是一个非常具体的要求.

我提到了与您的问题中所述的要求相关的设计注意事项。随着我们深入,会有更多,但这可能会给你一个起点。

我希望这会有所帮助!

【讨论】:

  • 嗨@Lalit,非常感谢您的详细回答。这对我来说很清楚。但是,对于消费者如何在不同的时间过滤出它想要的消息,我仍然有一个问题。想想这个场景:早上 8 点,消费者 A 想要消费 Stock AAPL、AMAN 和 BHP,这三个在分区 0。但是在上午 9 点,消费者 A 想要开始消费 GOOS 和 EDU。如何做到这一点?
  • 嗯,这是一个非常有趣的。我已经考虑了一段时间,但仍在尝试解决一些想法。将其作为一个新问题并征求社区其他成员的意见实际上可能很有用。如果以及何时发布,您能否在此处分享新帖子的链接?我会尝试解决这些想法并回来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2016-09-11
相关资源
最近更新 更多