Dr.Elephant實戰常見問題及解決方法
- 2019 年 12 月 26 日
- 筆記

通過之前一系列的文章敘述,想必大家都對dr.elephant
有了一個較為清晰的了解。通過自己線上經驗的積累,以及和一些讀者的交流,我匯總了一些大家在實戰中遇到的問題和解決方案。
1.常規問題
由於在和讀者交流的過程中,發現大家技術水平參差不齊,本著科普性文章的初衷,這裡先講一些比較基礎的要點,大佬們可以忽略,直接跳過。
- 在打包時,需要對照自己的
Hadoop
或者Spark
版本,修改compile.conf
文件中的版本號。否則有可能出現採集不到集群作業資訊的情況。 - 最好將自己
Hadoop
集群的相關配置文件都拷貝到dr.elephant
的app-conf
目錄下。 - 統一自己
Hadoop
集群的環境變數。
2.資料庫問題
2.1.Database 『default』 is in an inconsistent state!
啟動失敗並出現這個報錯,一般是play
框架的evolution
問題,解決方法如下:
- 停止
dr.elephant
並確保進程已kill
- 刪除原來的資料庫並重新建庫
- 配置
app-conf/elephant.conf
中jvm_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
允許的最大長度導致。解決方法如下:
conf/evolutions/default
目錄下的1.sql
和5.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));- 或者修改
mysql
的my.cnf
配置文件,添加innodb_large_prefix=1
,然後重啟MySQL
,使其自身支援較大索引 - 此外,建議
mysql
直接使用 5.6 及以上的版本,避免一些不必要的問題
3.作業資訊採集問題
dr.elephant
的核心原理就是通過採集作業資訊日誌,來進行一系列的分析,演算法推薦等功能。主要分為hadoop
的MapReduce
,和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:通過
API
從yarn history server
獲取作業資訊日誌 - MapReduceFSFetcherHadoop2:通過讀取
HDFS
和YARN
的配置文件,讀取mapreduce.jobhistory.done-dir
等相關配置,直接讀取HDFS
上YARN
的歷史作業資訊日誌。每個作業對應.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.問題點
- 為什麼採集不到作業資訊,介面上沒有任何顯示?
- 注意
dr.elephant
打包前Hadoop version
配置和被採集集群的版本資訊是否對應上了,否則會出現採集不到的情況。 - 查看
history_log_size_limit_in_mb
配置大小是否小於實際單個日誌文件大小,導致無法拉取日誌。 - 檢查
drelephant.analysis.fetch.initial.windowMillis
配置時間,這個配置為初始化時間拉取時間窗口,即拉取當前時間之前多久的歷史作業。如果當前時間到時間窗口之前沒有歷史作業,則會出現無作業資訊的情況。 drelephant.analysis.retry.interval
配置為拉取間隔時間,這個配置過大,也會導致長時間不拉取作業,而無作業資訊。
- 注意
- 運行一段時間後,為什麼作業資訊延遲嚴重?
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
拉取spark
的eventlogs
,需要spark
版本在 1.5.0 以上。此外還可以支援backfill
功能,但僅適用於 2.3.0 以上版本。
3.2.2.問題點
MapReduce
作業正常採集並分析,為什麼spark
作業沒有分析數據?- 首先參照上面
hadoop
版本打包問題檢查,打包前是否同樣在配置文件中修改為正確的spark
版本 - 檢查
hdfs
上spark 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>
- 首先參照上面
- 為什麼部分
spark
作業缺失,dr.elephant
沒有顯示所有作業?- 同上
Hadoop
問題點,可能出現了延遲問題 SHS
可能沒有配好spark
日誌聚合,解決辦法另行找SHS
日誌聚合資料,這裡不再多說
- 同上
以上是個人在實戰中遇到的一些問題及解決方法,後續如果還有其他問題我也會及時更新,或者大家還遇上啥坑了也可以和我交流討論。