我有一个案例,Kafka制作人每天发送两次数据。这些生产者从数据库/文件中读取所有数据并发送给Kafka。所以每天发送的这些消息都是重复的。我需要对消息进行重复数据删除,并使用Spark Streaming在一些持久存储中写入。在这种情况下,删除重复邮件的最佳方法是什么?
发送的重复消息是一个json字符串,时间戳字段仅更新。
注意: 我无法更改Kafka Producer只发送新数据/消息,它已经安装在客户端中机器和其他人写的。
答案 0 :(得分:1)
对于重复数据删除,您需要存储有关已处理内容的信息(例如,消息的唯一ID)。
存储可以使用的消息:
火花检查站。优点:开箱即用。缺点:如果您更新应用程序的源代码,则需要清理检查点。结果,您将丢失信息。如果重复数据删除的要求不严格,解决方案可以正常工作。
任何数据库。例如,如果您在hadoop env上运行,则可以使用Hbase。对于每条消息,您都会“获取”(检查之前是否已发送过),并在真正发送时发送的数据库中标记。
答案 1 :(得分:1)
您可以将主题配置更改为compact
模式。通过压缩,具有相同密钥的记录将在Kafka日志中被覆盖/更新。你只能获得Kafka钥匙的最新价值。
您可以阅读有关压缩here的更多信息。
答案 2 :(得分:0)
您可以尝试使用mapWithState
。检查我的answer。
答案 3 :(得分:0)
一种更简单的方法是在kafka端解决此问题。看一下kafka的Log压缩功能。如果记录具有相同的唯一密钥,它将为您删除重复记录。
答案 4 :(得分:0)
您可以使用键值数据存储区,其中的键将是除timestamp字段之外的其他字段的组合,并为实际json赋值。
在轮询记录时,将密钥和值对写入到数据存储中,该数据存储处理UPSERT(Insert + Update)或检查数据存储中是否存在该密钥,然后删除消息
if(Datastore.get(key)){
// then drop
}else {
//write to the datastore
Datastore.put(key)
}
我建议您检查HBase(用于处理UPSERTS)和Redis(用于查找的内存KV数据存储)
答案 5 :(得分:0)
您是否调查过以下内容: https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html#streaming-deduplication
您可以尝试使用dropDuplicates()方法。 如果需要使用多个列来确定重复项,则可以使用dropDuplicates(String [] colNames)传递它们。