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)。
  • 对于 Tranquility 实时索引

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

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

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

常见问题列表

  • 组件启动失败

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

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

  • 索引时 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 包,两个配置项配置一个即可。 可参见 Apache Druid 官方文档

  • 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 目录。(此针对独立 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。这两个 ZooKeeper 可能不是一个 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 账户有权限访问。