如何在火花流上保持固定大小

时间:2016-04-19 10:24:01

标签: apache-spark spark-streaming

我正在尝试使用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)做治疗?

1 个答案:

答案 0 :(得分:1)

在Spark Streaming中,persistcache不会为每批数据不断向内存中添加数据。它的作用是指示应该缓存底层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()
  }
}

(*)仅作为指导提供的代码。