一个生产者和几个消费者从证券交易所获取市场数据的架构



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

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

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

还有一项要求是,消费者可以不时改变他们的偏好。像消费者A可能开始消费符号为"GOOS"的消息。

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

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

数据采集层:一个组件,它将从交易所获取数据,并将嵌入一个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的哈希值,并对分区数进行模运算。然后,此计算的结果将确定此消息将结束的分区。此选项有一个警告,即跨分区的符号分布可能并不总是均匀的。如果您想自己研究默认分区程序的实际源代码,请

    在此处引用。
  • 第三个选项是编写自己的自定义分区程序。这是一篇带有示例的参考文章。

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

消费策略

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

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

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

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

我希望这有帮助!

最新更新