本文介绍E-MapReduce Druid使用过程中遇到的一些常见问题以及解决方法。

索引失败问题分析思路

当发现索引失败时,一般遵循如下排错思路:
  • 对于批量索引
    1. 如果curl直接返回错误,或者不返回,检查一下输入文件格式。或者curl加上-v参数,观察REST API的返回情况。
    2. 在Overlord页面观察作业执行情况,如果失败,查看页面上的logs。
    3. 在很多情况下并没有生成logs。如果是Hadoop作业,打开YARN页面查看是否有索引作业生成,并查看作业执行log。
    4. 如果上述情况都没有定位到错误,需要登录到E-MapReduce 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)。
  • 对于Kafka Indexing Service和SLS Indexing Service
    1. 首先查看Overlord的Web页面:http://emr-header-1:18090,查看Supervisor的运行状态,检查payload是否合理。
    2. 查看失败task的log。
    3. 如果不能从task log定位出失败原因,则需要从Overlord log排查问题。
  • 对于Tranquility实时索引

    查看Tranquility log,查看消息是否被接收到了或者是否被丢弃(drop)掉了。

    其余的排查步骤同批量索引的2~5。

    错误多数情况为集群配置问题和作业问题。集群配置问题包括:内存参数是否合理、跨集群联通性是否正确、安全集群访问是否通过、principal是否正确等等,作业问题包括作业描述文件格式是否正确、输入数据是否能够正常被解析,以及一些其他的作业相关的配置(例如ioConfig)。

问题汇总

  • 组件启动失败

    此类问题多数是由于组件JVM运行参数配置问题,例如机器可能没有很大的内存,而配置了较大的JVM内存或者较多的线程数量。

    解决方法:查看组件日志并调整相关参数即可解决。JVM内存涉及堆内存和直接内存。具体可参见Basic cluster tuning

  • 索引时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包,两个配置项配置一个即可。 请参见 Working with different versions of Apache Hadoop

  • indexing作业的日志中报reduce无法创建segments目录。

    解决方法:
    • 注意检查deep storage的设置,包括type和directory。当type为local时,注意directory的权限设置。当type为HDFS时,directory尽量用完整的HDFS路径写法,例如hdfs://hdfs_master:9000/path。hdfs_master最好用IP,如果用域名,要用完整的域名,例如emr-header-1.cluster-xxxxxxxx,而不是emr-header-1。
    • 用Hadoop批量索引时,要将segments的deep storage设置为hdfs,local的方式会导致MR作业处于UNDEFINED状态,这是因为远程的YARN集群无法在reduce task下创建local的segments目录。(此针对独立E-MapReduce Druid集群)。
  • 错误提示Failed to create directory within 10000 attempts…

    此问题一般为JVM配置文件中java.io.tmp设置的路径不存在的问题。设置该路径并确保E-MapReduce Druid账户有权限访问即可。

  • 错误提示com.twitter.finagle.NoBrokersAvailableException: No hosts are available for disco!firehose:druid:overlord
    此问题一般是ZooKeeper的连接问题。确保E-MapReduce Druid与Tranquility对于ZooKeeper有相同的连接字符串。E-MapReduce Druid默认的ZooKeeper路径为/druid,因此确保Tranquility设置中zookeeper.connect包含路径/druid
    说明 Tranquility Kafka设置中有两个ZooKeeper的设置,一个为zookeeper.connect,连接E-MapReduce Druid集群的ZooKeeper,一个为kafka.zookeeper.connect,连接Kafka集群的ZooKeeper。
  • 索引时MiddleManager提示找不到类com.hadoop.compression.lzo.LzoCodec

    这是因为EMR的Hadoop集群配置了lzo压缩。

    解决方法:拷贝EMR $HADOOP_HOME/lib下的JAR包和native文件夹到E-MapReduce 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路径不存在的问题。设置该路径并确保E-MapReduce Druid账户有权限访问。