讓 Spark Streaming 程式在 YARN 叢集上長時間執行(二)—— 日誌、監控、Metrics
前段時間看到了外國朋友寫的一篇文章,覺得還不錯,於是就把他翻譯一下,供大家參考和學習。
如果沒看過第一篇文章,建議先去看一下上一篇文章哈,這裡是接著上一篇文章來寫的哈~
日誌
訪問 Spark 應用程式日誌的最簡單方法是配置 Log4j 控制檯 appender,等待應用程式終止並使用 yarn logs -applicationId [applicationId]
命令。 不幸的是,終止長時間執行的 Spark Streaming 作業來訪問日誌是不可行的。
我建議安裝和配置 Elastic,Logstash 和 Kibana(ELK棧)。 ELK 的安裝和配置不在此部落格文章範圍內,但請記住記錄以下上下文欄位:
- YARN application id
- YARN container hostname
- Executor id (Spark driver 一直是 000001, Spark executors 從 000002 開始)
- YARN attempt (檢查 Spark Driver 程式重啟的次數)
具有 Logstash 特定 appender 和佈局定義的 Log4j 配置應傳遞給 spark-submit命令:
spark-submit --master yarn --deploy-mode cluster \
--conf spark.yarn.maxAppAttempts=4 \
--conf spark.yarn .am.attemptFailuresValidityInterval=1h \
--conf spark.yarn.max.executor.failures={8 * num_executors} \
--conf spark.yarn.executor.failuresValidityInterval=1h \
--conf spark.task.maxFailures=8 \
--queue realtime_queue \
--conf spark.speculation=true \
--principal user/[email protected] \
--keytab /path/to/foo.keytab \
--conf spark.hadoop.fs.hdfs.impl.disable.cache=true \
--conf spark.driver.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties \
--conf spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties \
--files /path/to/log4j.properties
最後,Spark Job 的 Kibana 儀表板可能如下所示:
監控
長時間執行的作業 7*24 小時執行,因此瞭解歷史指標非常重要。 Spark UI 只對有限數量的 batch 保持統計資訊,並且在重新啟動後,所有 metrics 都消失了。 所以需要外部工具。 我建議安裝 Graphite 來收集度量標準,Grafana 則用於構建儀表板。
首先,需要配置 Spark 以將 metrics 報告到 Graphite,準備如下metrics.properties
檔案:
*.sink.graphite.class=org.apache.spark.metrics.sink.GraphiteSink
*.sink.graphite.host=[hostname]
*.sink.graphite.port=[port]
*.sink.graphite.prefix=some_meaningful_name
driver.source.jvm.class=org.apache.spark.metrics.source.JvmSource
executor.source.jvm.class=org.apache.spark.metrics.source.JvmSource
然後配置 spark-submit 命令:
spark-submit --master yarn --deploy-mode cluster \
--conf spark.yarn.maxAppAttempts=4 \
--conf spark.yarn.am.attemptFailuresValidityInterval=1h \
--conf spark.yarn.max.executor.failures={8 * num_executors} \
--conf spark.yarn.executor.failuresValidityInterval=1h \
--conf spark.task.maxFailures=8 \
--queue realtime_queue \
--conf spark.speculation=true \
--principal user/[email protected] \
--keytab /path/to/foo.keytab \
--conf spark.hadoop.fs.hdfs.impl.disable.cache=true \
--conf spark.driver.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties \
--conf spark.executor.extraJavaOptions=-Dlog4j.configuration=file:log4j.properties \
--files /path/to/log4j.properties:/path/to/metrics.properties
Metrics
Spark 會從 Driver 和 executors 生成大量指標。 如果我選擇最重要的一個,那將是最後收到的 batch 的資訊。 當StreamingMetrics.streaming.lastReceivedBatch_records == 0
時,這可能意味著 Spark Streaming 作業已停止或失敗。
下面列出了其他重要的 metrics:
- 當總延遲大於批處理間隔時,處理延遲將會增加。
driver.StreamingMetrics.streaming.lastCompletedBatch_totalDelay
- 當執行的 task 數低於
number of executors * number of cores
時,YARN 分配的資源未充分利用。
executor.threadpool.activeTasks
- RDD的快取使用了多少記憶體。
driver.BlockManager.memory.memUsed_MB
- 當 RDD 快取沒有足夠的記憶體時,有多少資料 spilled 到磁碟。 你應該增加executor 記憶體或更改
spark.memory.fraction
的Spark引數以避免效能下降。
driver.BlockManager.disk.diskSpaceUsed_MB
- Spark Driver 上的 JVM 記憶體利用率是多少
driver.jvm.heap.used
driver.jvm.non-heap.used
driver.jvm.pools.G1-Old-Gen.used
driver.jvm.pools.G1-Eden-Space.used
driver.jvm.pools.G1-Survivor-Space.used
- 在Spark Driver上的 GC 花費了多少時間
driver.jvm.G1-Old-Generation.time
driver.jvm.G1-Young-Generation.time
- Spark executors 上的 JVM 記憶體利用率是多少
[0-9]*.jvm.heap.used
[0-9]*.jvm.non-heap.used
[0-9]*.jvm.pools.G1-Old-Gen.used
[0-9]*.jvm.pools.G1-Survivor-Space.used
[0-9]*.jvm.pools.G1-Eden-Space.used
- 在Spark executors上的 GC 花費了多少時間
[0-9]*.jvm.G1-Old-Generation.time
[0-9]*.jvm.G1-Young-Generation.time