如何确保火花不会从cassandra读取两次相同的数据

时间:2016-02-05 08:12:17

标签: scala apache-spark cassandra datastax

我正在学习火花和卡桑德拉。我的问题如下。 我有cassandra表来记录来自传感器的行数据

CREATE TABLE statistics.sensor_row (
    name text,
    date timestamp,
    value int,
    PRIMARY KEY (name, date)
) 

现在我想通过spark批处理作业(即每日)聚合这些行

所以我可以写

val rdd = sc.cassandraTable("statistics","sensor_row")
//and do map and reduce to get what i want and perhaps write back to aggregated table. 

但我的问题是我将定期运行此代码。我需要确保两次不读相同的数据。

我可以做的一件事是删除我读过的行,看起来很丑,或者使用过滤器

sensorRowRDD.where("date >'2016-02-05 07:32:23+0000'")

第二个看起来更好,但后来我需要记录作业最后运行的时间并从那里继续。但是,根据DataStax驱动程序数据位置,每个工作程序仅在其本地cassandra节点中加载数据。这意味着我需要跟踪每个cassandra / spark节点的日期,而不是跟踪全局日期。仍然看起来不是很优雅。

有没有更好的方法呢?

1 个答案:

答案 0 :(得分:1)

DataFrame过滤器将被推送到Cassandra,因此这是解决问题的有效方法。但你担心一致性问题是正确的。

一种解决方案是不仅设置开始日期,还设置结束日期。当你的工作开始时,它会查看时钟。它是2016-02-05 12:00。也许你在收集迟到的数据方面有几分钟的延迟,而且时钟也不是绝对精确的。您决定使用10分钟的延迟并将结束时间设置为2016-02-05 11:50。您将其记录在文件/数据库中。上次运行的结束时间为2016-02-04 11:48。因此,您的过滤器为date > '2016-02-04 11:48' and date < '2016-02-05 11:50'

由于日期范围涵盖所有时间,因此您只会遗漏在处理完范围后已保存到过去范围内的事件。如果这种情况经常发生,您可以将延迟时间从10分钟增加。