Java 版本冲突,当前版本[2]与提供的版本[1]不同
我有一个卡夫卡主题和一个Spark应用程序。Spark应用程序从Kafka主题获取数据,预聚合数据并将其存储在弹性搜索中。听起来很简单,对吧 一切正常,但当我设置“spark.cores”属性而不是1时,我开始得到Java 版本冲突,当前版本[2]与提供的版本[1]不同,java,apache-spark,
elasticsearch,apache-kafka,Java,Apache Spark,
elasticsearch,Apache Kafka,我有一个卡夫卡主题和一个Spark应用程序。Spark应用程序从Kafka主题获取数据,预聚合数据并将其存储在弹性搜索中。听起来很简单,对吧 一切正常,但当我设置“spark.cores”属性而不是1时,我开始得到 version conflict, current version [2] is different than the one provided [1] 经过一点研究,我认为错误是因为多个核心可以同时拥有相同的文档,因此,当一个核心完成聚合并试图写回文档时,它会得到这个错误 TBH
version conflict, current version [2] is different than the one provided [1]
经过一点研究,我认为错误是因为多个核心可以同时拥有相同的文档,因此,当一个核心完成聚合并试图写回文档时,它会得到这个错误
TBH,我对这种行为感到有点惊讶,因为我认为Spark和ES会自己处理这个问题。这让我相信,也许我的方法有问题
我怎样才能解决这个问题?我是否需要遵循某种“同步”或“锁定”的概念
干杯 听起来队列中有多条消息都更新了相同的ES文档,并且这些消息正在同时处理。有两种可能的解决方案: 首先,可以使用Kafka分区来确保按顺序处理更新同一ES文档的所有消息。这假设您的消息中有一些属性,Kafka可以使用这些属性来确定消息如何映射到ES文档 另一种方法是处理乐观并发冲突的标准方法:重试事务。如果您需要将卡夫卡消息中的某些数据添加到ES文档中,并且ES中的当前文档为版本1,则可以尝试更新它并保存回版本2。但是,如果其他人已经编写了版本2,您可以使用版本2作为起点,添加新数据并保存版本3来重试
如果这些方法中的任何一种都破坏了您期望从卡夫卡和Spark获得的并发性,那么您可能需要重新考虑您的方法。您可能需要引入一个新的处理阶段,该阶段会执行一些繁重的操作,但实际上不会写入ES,然后在单独的步骤中执行ES更新。我想回答我自己的问题。在我的用例中,我正在更新文档计数器。所以,我所要做的就是在发生冲突时重试,因为我只需要聚合计数器 我的用例是: 对于部分更新的许多用途,文档是否已更改并不重要。例如,如果两个进程都在递增页面视图计数器,那么它以什么顺序发生并不重要;如果发生冲突,我们唯一需要做的就是重新尝试更新 这可以通过将重试\u on_conflict参数设置为更新失败前应重试的次数来自动完成;它默认为0
多亏了Willis和blog,我才能够配置弹性搜索设置,现在我一点问题都没有了谢谢Willis。这正是我所想的;中间有一个从所有内核获取结果,然后聚合它们并写入ES(更像一个reduce作业)。然而,Spark不应该自己处理这个问题吗?另外,你认为哪种方法听起来更好?我有一个主题,其中包含事件,我想每小时聚合一次事件。这些事件由不同的内核处理。如果我遇到冲突,我应该再次查询该文档的ES,添加来自另一个核心的结果并再次保存它,这有意义吗。就像你提到的