Apache spark 如何在使用Spark streaming传输kafka时消除重复消息?

Apache spark 如何在使用Spark streaming传输kafka时消除重复消息?,apache-spark,duplicates,apache-kafka,spark-streaming,Apache Spark,Duplicates,Apache Kafka,Spark Streaming,我有一个案例,卡夫卡制作人每天发送两次数据。这些生产者从数据库/文件中读取所有数据并发送给卡夫卡。所以这些信息每天都会被发送,这是重复的。我需要使用Spark Streaming消除消息的重复数据,并写入一些持久性存储。在这种情况下,删除重复邮件的最佳方法是什么 发送的重复消息是一个json字符串,时间戳字段仅更新 注意:我无法将Kafka Producer更改为仅发送新数据/消息,它已安装在客户端计算机中并由其他人编写。对于重复数据消除,您需要将已处理的信息(例如消息的唯一ID)存储在某个位置

我有一个案例,卡夫卡制作人每天发送两次数据。这些生产者从数据库/文件中读取所有数据并发送给卡夫卡。所以这些信息每天都会被发送,这是重复的。我需要使用Spark Streaming消除消息的重复数据,并写入一些持久性存储。在这种情况下,删除重复邮件的最佳方法是什么

发送的重复消息是一个json字符串,时间戳字段仅更新


注意:我无法将Kafka Producer更改为仅发送新数据/消息,它已安装在客户端计算机中并由其他人编写。

对于重复数据消除,您需要将已处理的信息(例如消息的唯一ID)存储在某个位置

要存储邮件,您可以使用:

  • 火花检查站。优点:开箱即用。缺点:如果你更新应用程序的源代码,你需要清理检查点。因此,您将丢失信息。如果对重复数据消除的要求不严格,该解决方案可以工作

  • 任何数据库。例如,如果在hadoop环境上运行,则可以使用Hbase。对于您确实“收到”的每一条消息(检查它之前是否未发送),并在实际发送时在DB sent中进行标记


  • 您可以将主题配置更改为
    compact
    模式。通过压缩,具有相同密钥的记录将在Kafka日志中被覆盖/更新。在那里,您只能从卡夫卡获得密钥的最新值


    您可以阅读有关压缩的更多信息。

    您可以尝试使用。检查我的。

    一个更简单的方法是在卡夫卡端解决这个问题。看看卡夫卡的日志压缩功能。如果记录具有相同的唯一密钥,它将为您消除重复记录


    您可以使用键值数据存储,其中您的键值将是不包括时间戳字段和实际json值的字段组合

    轮询记录时,创建密钥和值对写入数据存储,该数据存储处理UPSERT(插入+更新)或检查数据存储中是否存在密钥,然后删除消息

    if(Datastore.get(key)){ 
         // then drop
     }else { 
        //write to the datastore
        Datastore.put(key)
    }
    
    我建议您检查HBase(处理Upsert)和Redis(用于查找的内存KV数据存储)

    您研究过以下内容吗:

    您可以尝试使用dropDuplicates()方法。
    如果需要使用多个列来确定重复项,则可以使用dropDuplicates(String[]colNames)传递它们。

    感谢您的回复,检查id是不正确的,因为有时数据会用相同的id更新。生成并检查has而不是id是否是一个好主意。@ShankarKoirala您可以存储id+时间戳。或整个消息的md5哈希。这个逻辑不太取决于你选择的解决方案。我没有使用。但我看不出它为什么不起作用。确保在消息真正存储时标记消息发送。这可能会导致重复(例如重新启动时),但不会导致数据丢失。使用选项2,如果数据已更新且我们检查的id相同,该怎么办。在这种情况下,数据将丢失。据我所知,要启用代理范围的压缩,必须在server.properties中设置log.cleanup.policy=compact-对吗?是的,没错。但有一个问题:一旦设置了清理策略压缩,retention.ms将不会被接受。这是因为kafka清理线程要么根据用户设置的保留策略执行日志清理,要么执行兼容(重复数据消除)。