ApacheKafka—一个生产者和几个消费者从证券交易所获取市场数据的体系结构

vktxenjb  于 2021-06-06  发布在  Kafka
关注(0)|答案(1)|浏览(309)

我有一个场景,我需要使用一个生产者(证券交易所)提供市场数据。每个市场数据消息都包含(“符号”、“价格”和“时间戳”)。
同时,我有3个消费者(服务器),每个消费者(服务器)将使用带有特定“符号”的市场数据。例如,消费者a将只消费具有符号“aapl”、“amzn”的市场数据,消费者b将消费具有符号“goos”等的消费者。
一个要求是消费者必须接收他们想要的符号的按时间戳排序的消息。
还有一个要求是,消费者可能会不时改变他们的偏好。与消费者一样,消费者可能会开始消费带有“goos”符号的消息。
我应该如何设计这个架构?我知道我可能需要利用Kafkamq,但我不是这方面的Maven。有人能详细说明一下设计方案吗?

tv6aics1

tv6aics11#

您的设计可以包含以下组件:
数据采集层:一个将从交换中获取数据的组件,它将嵌入一个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 在消息的开头,即消息的键,指示该消息应转到哪个分区。您需要在producer中编写逻辑,将特定的股票符号Map到专用分区。
另一种选择是将消息构造为 {"AAPL", { "stockSymbol": "AAPL", "marketPrice": 57.10, "timestamp": "May 13th, 10:03:18 AM "} } . 显式地将stock符号压入消息的键中,然后kafka的默认分区器将跳入并计算字符串的哈希值 AAPL 对分区数进行模运算。然后,此计算的结果将确定此消息将在其中结束的分区。此选项有一个警告,即跨分区的符号分布可能并不总是一致的。如果您想自己研究的话,这里有一个对默认分区器的实际源代码的参考。
第三种选择是编写自己的自定义分区器。下面是一篇带有示例的参考文章。
分区的实际数量将取决于各种其他因素,如总吞吐量、代理数、使用者示例数(即并行单元)等。
消费策略:
通常,使用者示例将由kafka自动分配分区-默认分配是使用 RangeAssignor . 例如,如果您有8个分区(编号从0到7)和3个使用者(c1、c2和c3),那么kafka将分配分区 {0, 1, 2}c1 , {3, 4, 5}c2 以及 {6, 7}c3 . 您可以通过直接调用 assign() 方法或通过实现此接口编写自定义赋值器。
根据时间戳对消息进行排序的要求。现在,这是Kafka无法保证的。消息将按到达的顺序推送到主题,因此如果有2条带有时间戳的消息 t1 以及 t2t1 < t2 因为某种原因 t2 时间戳首先到达,然后在消息 t1 时间戳。因此,您需要在您的消费者应用程序示例中处理这个问题—我已经使用了 TreeMap 过去的数据结构 timestamp 作为实现这一目标的关键。
关于更改消费首选项的要求-最好实现自定义分区赋值器(在消费策略的第1点中提到),这将使您能够处理这个问题,因为这是一个非常具体的要求。
我提到了与您问题中所述要求相关的设计考虑。随着我们的深入,会有更多的信息,但这可能会给你一个起点。
我希望这有帮助!

相关问题