很明显,火花流中的开箱即用连接功能不会影响很多现实生活中的用例。原因是它只加入微批RDD中包含的数据。
用例是从两个kafka流中连接数据,并使用spark2中stream2中相应的对象丰富stream1中的每个对象,并将其保存到HBase。
实施
从stream2中的对象维护内存中的数据集,在收到对象时添加或替换对象
对于stream1中的每个元素,访问缓存以从stream2中查找匹配的对象,如果找到匹配则保存到HBase,否则将其放回到kafka流中。
这个问题是关于探索Spark流媒体及其寻找实现上述方法的API。
答案 0 :(得分:1)
您可以将传入的RDD
加入其他RDD
- 而不仅仅是该微批中的RDD
。基本上你保持"运行总量" var globalRDD1: RDD[...] = sc.emptyRDD
var globalRDD2: RDD[...] = sc.emptyRDD
dstream1.foreachRDD(rdd => if (!rdd.isEmpty) globalRDD1 = globalRDD1.union(rdd))
dstream2.foreachRDD(rdd => if (!rdd.isEmpty) {
globalRDD2 = globalRDD2.union(rdd))
globalRDD1.join(globalRDD2).foreach(...) // etc, etc
}
你填写的内容如下:
"$_.Name"
答案 1 :(得分:0)
一个良好的开端是研究mapWithState
。这是updateStateByKey
的更有效替代品。这些是在PairDStreamFunction
上定义的,因此假设您在stream2中的V
类型的对象由K
类型的某个键标识,那么您的第一个点就是这样:
def stream2: DStream[(K, V)] = ???
def maintainStream2Objects(key: K, value: Option[V], state: State[V]): (K, V) = {
value.foreach(state.update(_))
(key, state.get())
}
val spec = StateSpec.function(maintainStream2Objects)
val stream2State = stream2.mapWithState(spec)
stream2State
现在是一个流,其中每个批处理包含(K, V)
对,其中包含每个键的最新值。您可以在此流上加入stream1
以执行第二点的进一步逻辑。