我正在尝试使用Spark中的持久性功能将数据保存在内存中并对其进行计算 在我的情况下,我想只保留2GB DStream。这是我的代码:
val conf = new SparkConf()
.setAppName("File Count")
.setMaster("local[2]")
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc, Seconds(10))
val file = ssc.textFileStream("hdfs://192.168.1.31:8020/user/sparkStreaming/input")
var test = file.map(x => (x.split(" ")(0)+";"+x.split(" ")(1), 1)).reduceByKey((x,y) => x+y)
val windowed = test.reduceByKey(((a:Int,b:Int) => (a + b)))
windowed.persist(MEMORY_ONLY_SER)
当我达到2GB时,我会做另一种治疗,并且我会使用unpersist来释放记忆 有人可以帮我知道我有多坚持吗? 如果我知道我坚持了多少,我怎么能用它作为导管(如果PERSISTED == 2 GB)做治疗?
答案 0 :(得分:1)
在Spark Streaming中,persist
或cache
不会为每批数据不断向内存中添加数据。它的作用是指示应该缓存底层RDD,以便对它的进一步操作应用于RDD的记忆计算。所以,这不是一个累积的过程。
如果要累积数据,可以执行以下操作:
var addedRDD = sparkContext.emptyRDD
...
dstream.foreachRDD{ rdd =>
addedRDD = addedRDD union rdd
addedRDD.cache()
}
这最终会让你遇到麻烦,因为这个RDD会随着大小和复杂性而增长(我鼓励你在几次迭代后在Spark UI中检查它)
要获取使用的内存,您应该使用metrics interface。我猜你正在寻找BlockManager.memory.memUsed_MB
,但我可能错了。
那就是说,依靠JVM内存指标来触发一些工作对我来说似乎是一个坏主意,因为内存大小取决于用于保存数据的内部结构,并且不会准确反映数据的实际大小。
我宁愿根据record count x record size
找出指标。
一旦我们有了触发器指标,我们就可以使用以下条件“清除”收集的数据:
var addedRDD = sparkContext.emptyRDD
...
dstream.foreachRDD{ rdd =>
addedRDD = addedRDD union rdd
addedRDD.cache()
if (addedRDD.count() > SomeSize) {
writeToStorage(addedRDD)
addedRDD.unpersist(true)
addedRDD=sparkContext.emptyRDD()
}
}
(*)仅作为指导提供的代码。