Dr.Elephant實戰常見問題及解決方法

  • 2019 年 12 月 26 日
  • 筆記

通過之前一系列的文章敘述,想必大家都對dr.elephant有了一個較為清晰的了解。通過自己線上經驗的積累,以及和一些讀者的交流,我匯總了一些大家在實戰中遇到的問題和解決方案。

1.常規問題

由於在和讀者交流的過程中,發現大家技術水平參差不齊,本著科普性文章的初衷,這裡先講一些比較基礎的要點,大佬們可以忽略,直接跳過。

  1. 在打包時,需要對照自己的Hadoop或者Spark版本,修改compile.conf文件中的版本號。否則有可能出現採集不到集群作業資訊的情況。
  2. 最好將自己Hadoop集群的相關配置文件都拷貝到dr.elephantapp-conf目錄下。
  3. 統一自己Hadoop集群的環境變數。

2.資料庫問題

2.1.Database 『default』 is in an inconsistent state!

啟動失敗並出現這個報錯,一般是play框架的evolution問題,解決方法如下:

  1. 停止dr.elephant並確保進程已kill
  2. 刪除原來的資料庫並重新建庫
  3. 配置app-conf/elephant.confjvm_props="-Devolutionplugin=enabled -DapplyEvolutions.default=true",開啟evolution,使其能夠自動初始化表結構。

2.2.Specified key was too long; max key length is 767 bytes [ERROR:1071, SQLSTATE:42000]

這是一個較為常見的錯誤了,官方的歷史遺留問題導致,根據報錯可以看出是由於索引長度超過mysql允許的最大長度導致。解決方法如下:

  1. conf/evolutions/default目錄下的1.sql5.sql中,增加索引長度的截取為 100。 evolutions/default/1.sql create index yarn_app_result_i4 on yarn_app_result (flow_exec_id(100)); create index yarn_app_result_i5 on yarn_app_result (job_def_id(100)); create index yarn_app_result_i6 on yarn_app_result (flow_def_id(100)); evolutions/default/5.sql — flow_definition table change to UNIQUE KEY flow_def_id (flow_def_id(100)) — job_definition table change to UNIQUE KEY job_def_id (job_def_id(100)) — job_execution table change the index length like below: create index index_je_job_exec_id on job_execution (job_exec_id(100)); create index index_je_job_exec_url on job_execution (job_exec_url(100));
  2. 或者修改mysqlmy.cnf配置文件,添加innodb_large_prefix=1,然後重啟MySQL,使其自身支援較大索引
  3. 此外,建議mysql直接使用 5.6 及以上的版本,避免一些不必要的問題

3.作業資訊採集問題

dr.elephant的核心原理就是通過採集作業資訊日誌,來進行一系列的分析,演算法推薦等功能。主要分為hadoopMapReduce,和spark作業資訊採集。

3.1.hadoop

3.1.1.採集原理

MapReduce作業資訊有兩種拉取方式可選,在app-conf/FetcherConf.xml進行配置。

<fetcher>    <applicationtype>mapreduce</applicationtype>    <classname>com.linkedin.drelephant.mapreduce.fetchers.MapReduceFetcherHadoop2</classname>     <params>      <sampling_enabled>false</sampling_enabled>     </params>  </fetcher>    <fetcher>  <applicationtype>mapreduce</applicationtype>    <classname>com.linkedin.drelephant.mapreduce.fetchers.MapReduceFSFetcherHadoop2</classname>      <params>      <sampling_enabled>false</sampling_enabled>       <history_log_size_limit_in_mb>500</history_log_size_limit_in_mb>       <history_server_time_zone>PST</history_server_time_zone>      </params>  </fetcher>

通過源碼分析,由於源碼過長,這裡就不貼出來了,直接講源碼邏輯,發現兩個Fetcher類分別是:

  • MapReduceFetcherHadoop2:通過APIyarn history server獲取作業資訊日誌
  • MapReduceFSFetcherHadoop2:通過讀取HDFSYARN的配置文件,讀取mapreduce.jobhistory.done-dir等相關配置,直接讀取HDFSYARN的歷史作業資訊日誌。每個作業對應.jhist.xml兩個文件 # *.xml文件裡面記錄的是相應作業運行時候的完整參數配置 hdfs dfs -cat /mr-history/done/2019/11/01/000000/job_1477464172237_0052_conf.xml # *.jhist文件里存放的是具體Hadoop作業運行的詳細資訊 hdfs dfs -cat /mr-history/done/2019/11/01/000000/job_1477464172237_0052-1477984365827-ocdp-QuasiMonteCarlo-1477984395977-4-1-SUCCEEDED-default-1477984370174.jhist

3.1.2.問題點

  1. 為什麼採集不到作業資訊,介面上沒有任何顯示?
    • 注意dr.elephant打包前Hadoop version配置和被採集集群的版本資訊是否對應上了,否則會出現採集不到的情況。
    • 查看history_log_size_limit_in_mb配置大小是否小於實際單個日誌文件大小,導致無法拉取日誌。
    • 檢查drelephant.analysis.fetch.initial.windowMillis配置時間,這個配置為初始化時間拉取時間窗口,即拉取當前時間之前多久的歷史作業。如果當前時間到時間窗口之前沒有歷史作業,則會出現無作業資訊的情況。
    • drelephant.analysis.retry.interval配置為拉取間隔時間,這個配置過大,也會導致長時間不拉取作業,而無作業資訊。
  2. 運行一段時間後,為什麼作業資訊延遲嚴重?
    • drelephant.analysis.thread.count作業分析執行緒數影響著分析效率,設置的過小很容易延遲
    • 以上採集不到作業資訊問題的幾個排查點,也比較容易造成延遲情況,需要自己根據作業數量,進行一個評估設置

3.2.spark

3.2.1.採集原理

Spark作業資訊同樣有兩種拉取方式可選,在app-conf/FetcherConf.xml進行配置。

<fetcher>      <applicationtype>spark</applicationtype>      <classname>com.linkedin.drelephant.spark.fetchers.FSFetcher</classname>      <params>        <event_log_size_limit_in_mb>500</event_log_size_limit_in_mb>        <event_log_location_uri>webhdfs://localhost:50070/system/spark-history</event_log_location_uri>      </params>  </fetcher>    <fetcher>      <applicationtype>spark</applicationtype>      <classname>com.linkedin.drelephant.spark.fetchers.SparkFetcher</classname>      <params>        <use_rest_for_eventlogs>true</use_rest_for_eventlogs>        <should_process_logs_locally>true</should_process_logs_locally>      </params>  </fetcher>

通過源碼分析,由於源碼過長,這裡就不貼出來了,直接講源碼邏輯,發現兩個 Fetcher 類分別是:

  • FSFetcher:直接通過hdfs拉取spark的歷史日誌
  • SparkFetcher:通過SHS REST API拉取sparkeventlogs,需要spark版本在 1.5.0 以上。此外還可以支援backfill功能,但僅適用於 2.3.0 以上版本。

3.2.2.問題點

  1. MapReduce作業正常採集並分析,為什麼spark作業沒有分析數據?
    • 首先參照上面hadoop版本打包問題檢查,打包前是否同樣在配置文件中修改為正確的spark版本
    • 檢查hdfsspark eventlogs存放目錄是否產生了日誌文件,以及程式是否有相應的操作許可權
    • 如果使用了老版本的dr.elephant,則還需要注意spark是否開啟了spark.eventLog.compress,導致產生的spark日誌為snappy格式,使得dr.elephant無法識別。老版本可以通過增加配置進行識別<event_log_dir>/spark- history</event_log_dir> <spark_log_ext>.snappy</spark_log_ext>
  2. 為什麼部分spark作業缺失,dr.elephant沒有顯示所有作業?
    • 同上Hadoop問題點,可能出現了延遲問題
    • SHS可能沒有配好spark日誌聚合,解決辦法另行找SHS日誌聚合資料,這裡不再多說

以上是個人在實戰中遇到的一些問題及解決方法,後續如果還有其他問題我也會及時更新,或者大家還遇上啥坑了也可以和我交流討論。