【问题标题】:Hadoop Job fails with Native SimString C code on Large DataHadoop 作业因大数据上的本机 SimString C 代码而失败
【发布时间】:2014-02-11 21:35:27
【问题描述】:

我在使用 SimString Native 库在 hadoop 集群上运行大数据 (~15G) 作业时遇到问题。然而,工作在中/小型数据集(~200M)上运行良好。在作业期间,SimString 首先创建一个基于文件的数据库以匹配字符串,然后对给定的字符串与数据库中的字符串执行匹配。作业完成后,它会删除基于文件的数据库。该作业以多线程(100 个线程)方式运行。

为作业执行创建了大约 22 个映射器,每个映射器运行 ​​100 个线程。总体来说机器内存是4G

错误日志如下:

14/02/12 00:15:53 INFO mapred.JobClient:  map 0% reduce 0%
14/02/12 00:16:13 INFO mapred.JobClient:  map 4% reduce 0%
14/02/12 00:16:24 INFO mapred.JobClient: Task Id : attempt_201402091522_0059_m_000001_0, Status : FAILED
java.lang.Throwable: Child Error
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:271)
Caused by: java.io.IOException: Task process exit with nonzero status of 134.
    at org.apache.hadoop.mapred.TaskRunner.run(TaskRunner.java:258)

attempt_201402091522_0059_m_000001_0: #
attempt_201402091522_0059_m_000001_0: # A fatal error has been detected by the Java Runtime Environment:
attempt_201402091522_0059_m_000001_0: #
attempt_201402091522_0059_m_000001_0: #  SIGSEGV (0xb) at pc=0x00007f6f1cd8827b, pid=21146, tid=140115055609600
attempt_201402091522_0059_m_000001_0: #
attempt_201402091522_0059_m_000001_0: # JRE version: 6.0_45-b06
attempt_201402091522_0059_m_000001_0: # Java VM: Java HotSpot(TM) 64-Bit Server VM (20.45-b01 mixed mode linux-amd64 compressed oops)
attempt_201402091522_0059_m_000001_0: # Problematic frame:
attempt_201402091522_0059_m_000001_0: # C  [libSimString.so+0x6c27b][thread 140115045103360 also had an error]
attempt_201402091522_0059_m_000001_0:   cdbpp::cdbpp_base<cdbpp::murmurhash2>::get(void const*, unsigned long, unsigned long*) const+0x16f
attempt_201402091522_0059_m_000001_0: #
attempt_201402091522_0059_m_000001_0: # An error report file with more information is saved as:
attempt_201402091522_0059_m_000001_0: # /app/hadoop/tmp/mapred/local/taskTracker/hduser/jobcache/job_201402091522_0059/attempt_201402091522_0059_m_000001_0/work/hs_err_pid21146.log
attempt_201402091522_0059_m_000001_0: [thread 140115070318336 also had an error]
attempt_201402091522_0059_m_000001_0: [thread 140114919028480 also had an error]
attempt_201402091522_0059_m_000001_0: [thread 140115089229568 also had an error]
attempt_201402091522_0059_m_000001_0: #
attempt_201402091522_0059_m_000001_0: # If you would like to submit a bug report, please visit:
attempt_201402091522_0059_m_000001_0: #   http://java.sun.com/webapps/bugreport/crash.jsp
attempt_201402091522_0059_m_000001_0: # The crash happened outside the Java Virtual Machine in native code.
attempt_201402091522_0059_m_000001_0: # See problematic frame for where to report the bug.

此问题似乎是由本机代码引起的,如下所示:

cdbpp::cdbpp_base<cdbpp::murmurhash2>::get(void const*, unsigned long, unsigned long*) const+0x16f

但是,我不明白为什么这不会在小数据集中造成任何问题。我正在运行以下 hadoop 命令来执行:

hadoop jar hadoopjobs/job.jar Job -D mapred.child.java.opts=-Xss500k -D mapred.reduce.child.java.opts=-Xmx200m -files file1,file2,/home/hduser/libs/libSim/x64/libSimString.so -libjars /home/hduser/libs/Simstring.jar /datasources/XXX/spool/input datasources/XXX/spool/output

参考资料: SimString 库:http://www.chokkan.org/software/simstring/

cdbpp::cdbpp_base::get(void const*, unsigned long, unsigned long*) const+0x16f: https://gitorious.org/copy-paste/copy-paste/commit/5d9c6b5b29fb2b1b8dd571260e7d50d9c42db9f9的源代码

【问题讨论】:

    标签: java hadoop native-code


    【解决方案1】:

    问题可能不在于您的 Murmur3 散列,而在于本机库及其分配内存的方式。

    我没有使用 JNI 调用的经验,但是在内存使用方面它们是有问题的(每个这样的调用都会分配堆栈和堆空间)。不能确定 GC 是否可以正确触发(阅读the horror stories about GZipInputStream)。

    您说您创建了 22*100 个线程,每个线程都可能为 JNI 调用分配一些堆栈,并且盒子中只有 4Gb 内存。这台机器似乎很拥挤,我猜这里的限制是 CPU/内存访问,而不是长时间的外部等待(只有少数线程真正并行活动)?

    当您从根本上减少线程数量时会发生什么? SimStrings 库是如何使用的?它是否有一个应该被尊重的内部线程模型(即只让一个线程同时进行查询?)。

    恐怕 JNI 是相当单线程的。

    阅读更多关于native calls allocate memory的信息。

    【讨论】:

      【解决方案2】:

      正如我之前指出的,问题在于在 java 中调用以下方法:

       cdbpp::cdbpp_base<cdbpp::murmurhash2>::get(void const*, unsigned long, unsigned long*) const+0x16f
      

      我每个映射器使用 100 个线程,总共有 22 个线程,其中 2 个用于并行运行。由于静态阅读器过去常常在没有“同步”的情况下调用上述方法,因此出现了这个问题。所以用同步块包围这个方法调用解决了这个问题。

      【讨论】:

        猜你喜欢
        • 2014-11-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        • 1970-01-01
        • 2013-11-24
        相关资源
        最近更新 更多