我们目前有一个数据管道设置,我们使用Logstash从单个Kafka主题读取原始数据并将其写入ElasticSearch。 本主题中的数据采用JSON格式,但每行可以属于完全不同的业务域,因此它可能具有完全不同的架构。例如:
记录1:" {" id":1,"型号":"型号2","更新":& #34; 2017-01-1T00:00:00.000Z""结构域":" A"}
记录2:" {" id":" some_compound_key","结果":" PASS",&#34结构域":" B"}
您可以看到,不仅架构不同,而且实际上是冲突的(id是第一条记录中的整数,第二条记录中是字符串)。
只有两个保证 - 每个记录都是一个有效的JSON记录,每个记录都有一个"域"领域。即使具有相同域值的记录有时也可能具有不同的模式。
我们现在需要在数据通过管道时对其进行丰富和转换(而不是稍后使用ETL),我们正在研究几种实现它的方法。需要注意的是,由于数据没有统一的模式,因此需要逐行进行转换:
1)继续使用Logstash - 可以使用一组Logstash过滤器和条件为每个域建模我们需要的转换管道。
由于Logstash在运行时定期重新加载配置,因此也很容易维护和部署,因此要更改/添加转换逻辑,我们只需要在conf目录中删除新的配置文件。
然而,缺点是很难用来自外部源的Logstash来丰富数据。
2)使用Kafka Streams - 这似乎是一个明显的选择,因为它与Kafka很好地集成,允许从多个流(或外部源)加入数据并且没有架构要求 - 可以很容易地逐行转换数据。
这里的缺点是难以在运行时修改转换逻辑 - 我们需要重新编译和重新部署应用程序,或者使用一些可以在运行时生成和编译Java代码的API或其他复杂的解决方案来包装它。
3)使用Spark Streaming - 我们已经在使用Spark进行批处理,所以如果我们可以将它用于流式传输以保持我们的堆栈尽可能简单,那将会很棒。
但是,我不确定Spark是否甚至可以支持不具有单一模式的流数据,也不确定是否可以按行执行转换。
我所见过的所有示例(以及我们自己的Spark批处理经验)都假设数据具有良好定义的模式,这不是我们的用例。
任何人都可以了解我们对Spark Streaming(或Structured Streaming)我们需要的是什么,还是我们应该坚持使用Logstash / Kafka Streams?
答案 0 :(得分:1)
免责声明:我是Kafka Streams的积极撰稿人。
我对Logstash并不熟悉,但从您所描述的内容来看,它似乎是最不具吸引力的解决方案。
关于Spark Streaming。即使我不是它的忠实粉丝,我相信你可以做你想做的处理。结构化流不能理解,因为它需要一个固定的模式,但Spark Streaming应该更灵活。但是,与Kafka Streams相比,使用Spark Streaming不会简化它(但最有可能更难)。我没有在生产中运行Spark Streaming的个人经验,但我听到很多关于不稳定等的抱怨。
关于"缺点"你指出的Kafka Streams (1)我不确定你为什么需要代码生成等。(2),为什么Spark Streaming会有什么不同?您需要在两种情况下编写转换逻辑,如果您想要更改它,则需要重新部署。我也相信,通过"滚动弹跳更新Kafka Streams应用程序"与Spark Streaming相比,它更容易实现零停机时间,您需要在其间停止处理。
了解运行时的代码修改是什么有用的"你想做什么才能在这里给出更详细的答案。