web-dev-qa-db-ja.com

データソースがなくなったときにストリーミングを停止する方法spark

sparkストリーミングジョブがあり、5秒ごとにKafkaから読み取り、受信データに対して何らかの変換を行ってから、ファイルシステムに書き込みます。

これは実際にはストリーミングジョブである必要はありません。実際には、1日に1回実行して、メッセージをファイルシステムに排出したいと考えています。でも、どうやって仕事をやめるのかわかりません。

StreamingContext.awaitTerminationにタイムアウトを渡しても、プロセスは停止しません。ストリームを反復処理するときに、プロセスがエラーを生成するだけです(以下のエラーを参照)。

私がやろうとしていることを達成するための最良の方法は何ですか

これは、PythonでSpark 1.6

編集:

@mariosのおかげで、解決策は次のようになりました。

ssc.start()
ssc.awaitTermination(10)
ssc.stop()

スクリプトを10秒間実行してから、停止します。

簡略化されたコード:

conf = SparkConf().setAppName("Vehicle Data Consolidator").set('spark.files.overwrite','true')
sc = SparkContext(conf=conf)
ssc = StreamingContext(sc, 5)
stream = KafkaUtils.createStream(
    ssc,
    kafkaParams["zookeeper.connect"],
    "vehicle-data-importer",
    topicPartitions,
    kafkaParams)

stream.saveAsTextFiles('stream-output/kafka-vehicle-data')

ssc.start()
ssc.awaitTermination(10)

エラー:

16/01/29 15:05:44 INFO BlockManagerInfo: Added input-0-1454097944200 in memory on localhost:58960 (size: 3.0 MB, free: 48.1 MB)
16/01/29 15:05:44 WARN BlockManager: Block input-0-1454097944200 replicated to only 0 peer(s) instead of 1 peers
16/01/29 15:05:44 INFO BlockGenerator: Pushed block input-0-1454097944200
16/01/29 15:05:45 ERROR JobScheduler: Error generating jobs for time 1454097945000 ms
py4j.Py4JException: Cannot obtain a new communication channel
    at py4j.CallbackClient.sendCommand(CallbackClient.Java:232)
    at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.Java:111)
    at com.Sun.proxy.$Proxy14.call(Unknown Source)
    at org.Apache.spark.streaming.api.python.TransformFunction.callPythonTransformFunction(PythonDStream.scala:92)
    at org.Apache.spark.streaming.api.python.TransformFunction.apply(PythonDStream.scala:78)
    at org.Apache.spark.streaming.api.python.PythonTransformedDStream.compute(PythonDStream.scala:230)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1$$anonfun$1$$anonfun$apply$7.apply(DStream.scala:352)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1$$anonfun$1$$anonfun$apply$7.apply(DStream.scala:352)
    at scala.util.DynamicVariable.withValue(DynamicVariable.scala:57)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1$$anonfun$1.apply(DStream.scala:351)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1$$anonfun$1.apply(DStream.scala:351)
    at org.Apache.spark.streaming.dstream.DStream.createRDDWithLocalProperties(DStream.scala:426)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1.apply(DStream.scala:346)
    at org.Apache.spark.streaming.dstream.DStream$$anonfun$getOrCompute$1.apply(DStream.scala:344)
    at scala.Option.orElse(Option.scala:257)
    at org.Apache.spark.streaming.dstream.DStream.getOrCompute(DStream.scala:341)
    at org.Apache.spark.streaming.dstream.ForEachDStream.generateJob(ForEachDStream.scala:47)
    at org.Apache.spark.streaming.DStreamGraph$$anonfun$1.apply(DStreamGraph.scala:115)
    at org.Apache.spark.streaming.DStreamGraph$$anonfun$1.apply(DStreamGraph.scala:114)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251)
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47)
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251)
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105)
    at org.Apache.spark.streaming.DStreamGraph.generateJobs(DStreamGraph.scala:114)
    at org.Apache.spark.streaming.scheduler.JobGenerator$$anonfun$3.apply(JobGenerator.scala:248)
    at org.Apache.spark.streaming.scheduler.JobGenerator$$anonfun$3.apply(JobGenerator.scala:246)
    at scala.util.Try$.apply(Try.scala:161)
    at org.Apache.spark.streaming.scheduler.JobGenerator.generateJobs(JobGenerator.scala:246)
    at org.Apache.spark.streaming.scheduler.JobGenerator.org$Apache$spark$streaming$scheduler$JobGenerator$$processEvent(JobGenerator.scala:181)
    at org.Apache.spark.streaming.scheduler.JobGenerator$$anon$1.onReceive(JobGenerator.scala:87)
    at org.Apache.spark.streaming.scheduler.JobGenerator$$anon$1.onReceive(JobGenerator.scala:86)
    at org.Apache.spark.util.EventLoop$$anon$1.run(EventLoop.scala:48)
16/01/29 15:05:45 INFO MemoryStore: Block input-0-1454097944800 stored as bytes in memory (estimated size 3.0 MB, free 466.1 MB)
16/01/29 15:05:45 INFO BlockManagerInfo: Added input-0-1454097944800 in memory on localhost:58960 (size: 3.0 MB, free: 45.1 MB)
14
lostinplace

呼び出す正しいメソッドは awaitTerminationOrTimeout (self、timeout)のようです。

ストリーミングコンテキストも停止するかどうかはわかりません。したがって、タイムアウトが終了した直後にssc.stop()を呼び出すことができます。

ssc.start()
ssc.awaitTerminationOrTimeout(10)
ssc.stop()

注:同様の質問については ここ をご覧ください。

5
marios

Kafka "consumer.timeout.ms"パラメーターを試してみてください。これにより、KafkaReceiverが正常に終了します。(from kafka 0.8 configuration

指定された間隔の後に消費できるメッセージがない場合は、コンシューマーにタイムアウト例外をスローします

HDF = KafkaUtils.createStream(ssc, topics={strLoc : 1}, kafkaParams={"consumer.timeout.ms":"20000" }, zkQuorum='xxx:2181', groupId='xxx-consumer-group')

現在のストリーミング実行では、新しいkafkaメッセージを受信できず、常に空のRDDを取得します。
そして、DSteam.foreachRDD(func)で空のRDDの数を確認します。空のRDDを継続的に取得する場合は、ストリーミング実行を終了します。

1
Shawn Guo

ここでの問題spark 1.6以降、Dstream処理スレッドと同じスレッドでのssc.stop呼び出しは、stopがポーラースレッドの作成が完了するのを待つため、デッドロックを作成します。別のスレッドから

0
Ajith Kannan