我有一个Kafka主题和一个Spark应用程序。 Spark应用程序从Kafka主题获取数据,对其进行预聚合并将其存储在Elastic Search中。听起来很简单,对吧?
一切正常,但在我将“ spark.cores”属性设置为1之外的那一刻,我开始获得
version conflict, current version [2] is different than the one provided [1]
经过一些研究,我认为错误是因为多个内核可以同时具有相同的文档,因此,当一个内核完成聚合并尝试写回文档时,会收到此错误
TBH,我对此行为感到有些惊讶,因为我认为Spark和ES会自己处理。这使我相信,也许我的方法有问题。
我该如何解决?我需要遵循某种“同步”或“锁定”概念吗?
干杯!
答案 0 :(得分:3)
听起来您队列中有几条消息都更新了同一ES文档,并且这些消息正在同时处理。有两种可能的解决方案:
首先,您可以使用Kafka分区来确保按顺序处理所有更新同一ES文档的消息。假设您的邮件中有一些属性,Kafka可以使用该属性来确定邮件如何映射到ES文档。
另一种方法是处理乐观并发冲突的标准方法:重试事务。如果您需要从Kafka消息中获取一些数据,并且需要将它们添加到ES文档中,并且ES中的当前文档为版本1,则可以尝试对其进行更新并保存回版本2。但是,如果其他人已经编写了版本2, ,您可以通过以版本2为起点重试,添加新数据并保存版本3。
如果这些方法都破坏了您期望从Kafka和Spark获得的并发性,那么您可能需要重新考虑您的方法。您可能必须引入一个新的处理阶段,该阶段虽然繁重但实际上并未写入ES,然后在单独的步骤中进行ES更新。
答案 1 :(得分:0)