索引失敗問題分析思路

當發現索引失敗時,一般遵循如下排錯思路:
  • 對於批量索引
    1. 如果 curl 直接返回錯誤,或者不返回,檢查一下輸入檔案格式。或者 curl 加上 -v 參數,觀察REST API的返回情況。
    2. 在 Overlord 頁面觀察作業執行情況,如果失敗,查看頁面上的 logs。
    3. 在很多情況下並沒有產生 logs。如果是 Hadoop 作業,開啟 YARN 頁面查看是否有索引作業產生,並查看作業執行 log。
    4. 如果上述情況都沒有定位到錯誤,需要登入到 Druid 叢集,查看 overlord 的執行日誌(位於 /mnt/disk1/log/druid/overlord—emr-header-1.cluster-xxxx.log),如果是 HA 叢集,查看您提交作業的那個 Overlord。
    5. 如果作業已經被提交到 Middlemanager,但是從 Middlemanager 返回了失敗,則需要從 Overlord 中查看作業提交到了那個 worker,並登入到相應的 worker,查看 Middlemanager 的日誌(位於/mnt/disk1/log/druid/middleManager-emr-header-1.cluster-xxxx.log)。
  • 對於 Tranquility 即時索引

    查看 Tranquility log,查看訊息是否被接收到了或者是否被丟棄(drop)掉了。

    其餘的排查步驟同批量索引的 2~5。

    錯誤多數情況為叢集配置問題和作業問題。叢集配置問題包括:記憶體參數是否合理、跨叢集聯通性是否正確、安全叢集訪問是否通過、principal 是否正確等等,作業問題包括作業描述檔案格式正確、輸入資料是否能夠正常被解析,以及一些其他的作業相關的配置(如ioConfig等)。

常見問題列表

  • 組件啟動失敗

    此類問題多數是由於組件 JVM 運行參數配置問題,例如機器可能沒有很大的記憶體,而配置了較大的 JVM 記憶體或者較多的線程數量。

    解決方案:查看組件日誌並調整相關參數即可解決。JVM 記憶體涉及堆記憶體和直接記憶體。具體可參考http://druid.io/docs/latest/operations/performance-faq.html

  • 索引時 YARN task 執行失敗,顯示諸如Error: class com.fasterxml.jackson.datatype.guava.deser.HostAndPortDeserializer overrides final method deserialize.(Lcom/fasterxml/jackson/core/JsonParser;Lcom/fasterxml/jackson/databind/DeserializationContext;)Ljava/lang/Object; 之類的 jar 包衝突錯誤。

    解決方案:在 indexing 的作業設定檔中加入如下配置:
    "tuningConfig" : {
         ...
         "jobProperties" : {
             "mapreduce.job.classloader": "true"
             或者
             "mapreduce.job.user.classpath.first": "true"
         }
         ...
     }

    其中參數 mapreduce.job.classloader 讓MR job用獨立的 classloader,mapreduce.job.user.classpath.first 是讓MapReduce優先使用使用者的jar包,兩個配置項配置一個即可。 可參考:http://druid.io/docs/0.9.2-rc1/operations/other-hadoop.html

  • indexing作業的日誌中報reduce無法建立segments目錄

    解決方案:

    • 注意檢查 deep storage 的設定,包括 type 和 directory。當 type 為 local 時,注意 directory 的使用權限設定。當 type 為 HDFS 時,directory 盡量用完整的 HDFS 路徑寫法,如 hdfs://:9000/。hdfs_master 最好用 IP,如果用網域名稱,要用完整網域名稱,如 emr-header-1.cluster-xxxxxxxx,而不是 emr-header-1。
    • 用 Hadoop 批量索引時,要將 segments 的 deep storage 設定為 “hdfs”,“local” 的方式會導致 MR 作業處於 UNDEFINED 狀態,這是因為遠端 YARN 叢集無法在 reduce task 下建立 local 的 segments 目錄。(此針對獨立 Druid 叢集)。
  • Failed to create directory within 10000 attempts…

    此問題一般為 JVM 設定檔中 java.io.tmp 設定的路徑不存在。設定該路徑並確保 Druid 賬戶有許可權訪問即可。

  • com.twitter.finagle.NoBrokersAvailableException: No hosts are available for disco!firehose:druid:overlord

    此問題一般是 ZooKeeper 的串連問題。確保 Druid 與 Tranquility 對於 ZooKeeper 有相同的連接字串。注意:Druid 預設的ZooKeeper路徑為 /druid,因此確保 Tranquility 設定中 zookeeper.connect 包含路徑 /druid。(另注意 Tranquility Kafka 設定中有兩個 ZooKeeper 的設定,一個為 zookeeper.connect,串連的 Druid 叢集的 ZooKeeper,一個為 kafka.zookeeper.connect,串連的 Kafka 叢集的 ZooKeeper。這兩個 ZooKeeper 可能不是一個 ZooKeeper 叢集)。

  • 索引時 MiddleManager 報找不到類 com.hadoop.compression.lzo.LzoCodec

    這是因為 EMR 的 Hadoop 叢集配置了 lzo 壓縮。

    解決方案:拷貝 EMR HADOOP_HOME/lib 下的 jar 包和 native 檔案夾到 Druid 的 druid.extensions.hadoopDependenciesDir(預設為 DRUID_HOME/hadoop-dependencies)

  • 索引時報如下錯誤:
    2018-02-01T09:00:32,647 ERROR [task-runner-0-priority-0] com.hadoop.compression.lzo.GPLNativeCodeLoader - could not unpack the binaries
      java.io.IOException: No such file or directory
              at java.io.UnixFileSystem.createFileExclusively(Native Method) ~[?:1.8.0_151]
              at java.io.File.createTempFile(File.java:2024) ~[?:1.8.0_151]
              at java.io.File.createTempFile(File.java:2070) ~[?:1.8.0_151]
              at com.hadoop.compression.lzo.GPLNativeCodeLoader.unpackBinaries(GPLNativeCodeLoader.java:115) [hadoop-lzo-0.4.21-SNAPSHOT.jar:?]

    這個問題還是因為 java.io.tmp 路徑不存在。設定該路徑並確保 Druid 賬戶有許可權訪問。