我发现这是一个很好的问题,我可以在spark-kafka-streaming源代码中找到答案,如果没有人能回答这个问题,我会这样做。
想象这样的场景:
import Plyr from 'plyr';
(function() {
document.addEventListener('DOMContentLoaded', function() {
const plyr = new Plyr('#player', {
autoplay: true,
controls: [''],
fullscreen: {
enabeled: false
},
loop: {
active: true }
});
});
})()
在上面的示例代码中,我们可以看到我们正在从dstream获取微批次,并且对于每个批次我们都会触发2个操作。
根据Spark的懒惰评估行为,这两个动作都将追溯到数据源的起源(这是kafka主题),并且因为我们没有任何持久性()或广泛的变换,我们的代码逻辑中没有办法让spark缓存从kafka读取的数据。
所以这就是问题所在。火花会从卡夫卡读两次还是只读一次?这是非常相关的,因为从卡夫卡读取涉及netIO并可能给卡夫卡经纪人带来更多压力。因此,如果spark-kafka-streaming lib不能缓存它,我们绝对应该在多行动之前缓存()/ persist()它。
欢迎任何讨论。感谢。
修改
刚刚在spark官方网站上找到了一些文档,看起来像执行器接收器正在缓存数据。但我不知道这是否仅适用于单独的接收器。因为我读到spark kafka流式lib并没有使用单独的接收器,它接收数据并处理同一核心上的数据。
http://spark.apache.org/docs/latest/streaming-programming-guide.html#data-serialization
输入数据:默认情况下,通过Receiver接收的输入数据通过StorageLevel.MEMORY_AND_DISK_SER_2存储在执行程序的内存中。也就是说,数据被序列化为字节以减少GC开销,并且为了容忍执行器故障而被复制。此外,数据首先保存在内存中,并且仅在内存不足以保存流式计算所需的所有输入数据时才溢出到磁盘。这种序列化显然有开销 - 接收器必须反序列化接收的数据并使用Spark的序列化格式重新序列化。
答案 0 :(得分:0)
使用DStreams
时没有隐式缓存,因此,除非您明确缓存,否则每次评估都会遇到Kafka经纪人。
如果您多次评估,并且代理与Spark节点不在同一个位置,那么您一定要考虑缓存。
答案 1 :(得分:0)
根据Spark的官方文档: http://spark.apache.org/docs/latest/streaming-programming-guide.html#data-serialization
输入数据:默认情况下,通过Receiver接收的输入数据通过StorageLevel.MEMORY_AND_DISK_SER_2存储在执行程序的内存中。也就是说,数据被序列化为字节以减少GC开销,并且为了容忍执行器故障而被复制。此外,数据首先保存在内存中,并且仅在内存不足以保存流式计算所需的所有输入数据时才溢出到磁盘。这种序列化显然有开销 - 接收器必须反序列化接收的数据并使用Spark的序列化格式重新序列化。