RDD相同的密钥应按顺序处理

时间:2016-12-11 22:17:38

标签: spark-streaming

我有一个Dstream(K,V)。我的用例需要按顺序处理具有相同键的所有元组。这个过程就像吼叫:

val filestream=//..
fileStream.foreachRDD(r=>
{
    r.foreachparttion(p=>
   {

 p.foreach(x=>
{
 //x get the sate from Hbase
 //updates Hbase state for the key=k using the v and the retrieved state
})})})

因为对于每个元组和相应的密钥,我在HBase中都有状态,所以我需要确保所有具有相同密钥的元组每次都由一个CPU核心在一个分区中处理,因此每个元组都获得有效状态(不是过时和无效的)..流应用程序的并发性是1。

现在我想知道上面的代码是否足以满足我的上述要求,或者我是否需要进一步对键值进行分组(例如,使用combinebykey in this thread)?

我想知道是否访问每个分区中RDD中的每个元组(对于每个批处理间隔 - 如下所示)

p.foreach(x=>
{
 //x get the sate from Hbase
 //updates Hbase state for the key=k using the v and the retrieved state
})

可以是顺序的,也可以是并行的?

1 个答案:

答案 0 :(得分:1)

一般情况下,在Spark Streaming中,对于哪个键接收器没有保证。特定的接收器实现可能提供保修或实现它的可能性。 例如,Kafka消费者将为您提供保证,即在一个执行程序上使用来自一个分区的所有数据,因此将相同的密钥放在同一分区中将实现预期目标。

在一般情况下,为了确保相同的密钥位于同一个Spark分区中,我们需要重新分区数据。但是为了确保按顺序处理来自一个密钥的数据,我们需要更进一步,将每个密钥的数据放在一起。可以使用groupByKey来完成这两个步骤的组合。一旦我们以key -> [data1, ..., datan]的形式获得数据,我们只需要从db请求当前(k,v)来完成该过程。

就代码而言,我们会有类似的内容:

fileStream.foreachRDD{rdd =>
    val dataPerKey = rdd.map(entry => (key(entry),value(entry))).groupByKey()
    dataPerKey.forEachPartition{iter =>
        val dataMap = iter.toMap
        val keys = dataMap.keys
        // val dbState = HBase.get(keys)
        // val newData = process dataMap + dbState
        HBase.write(newData)
    }
}