如需转载,请标明原文出处以及作者

陈锐 RuiChen @kiwik

2019/07/04 17:02:17


背景

我们已经在aarch64上编译测试了 Hadoop、Spark、HBase 和 Hive,今天开始在aarch64上编译 验证 Storm

Storm 85%的代码由 Java 组成,7%是 Python,另外有 HTML,Clojure 和 JavaScript,还有 0.4%是 C 语言。

编译环境

编译环境的配置请参考我的另一篇博客《在ARM64上编译Hadoop》, 在这里仅列出基本的编译环境信息:

  • OS: CentOS 7.6
  • Arch: aarch64
  • Host: 华为云 ARM 公测实例
  • Storm: git commit b4f9eb1dc7284fa7f3a28368c1538dd901c5dd6f (2019-06主干)
  • Java: 1.8.0
  • Maven: 3.6.1
  • Python: 2.7 and 3.6
  • rvm: 2.4.2
  • nvm: 8.9.3

执行编译

Storm 的官方开发文档 还要求安装rvmnvm,根据文档要求的前置步骤配置环境之后,开始正式的编译。

mvn clean package -DskipTests
[INFO] --- maven-antrun-plugin:1.8:run (prepare) @ storm-metrics ---
[WARNING] Parameter tasks is deprecated, use target instead
[INFO] Executing tasks

main:
     [echo] Downloading sigar native binaries...
      [get] Getting: https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/magelan/hyperic-sigar-1.6.4.zip
      [get] To: /root/.m2/repository/org/fusesource/sigar/1.6.4/hyperic-sigar-1.6.4.zip
      [get] Error getting https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/magelan/hyperic-sigar-1.6.4.zip to /root/.m2/repository/org/fusesource/sigar/1.6.4/hyperic-sigar-1.6.4.zip
[INFO] ------------------------------------------------------------------------

遇到第一个问题,Storm 用到了一个收集系统信息的工具 sigar, 需要从 Google 的地址下载,我使用的华为云公测 ARM 实例是在国内的 Region,下载不了。替换成 一个 SourceForge 的地址如下,可以编译成功:

mvn clean package -DskipTests -Dsigar.download.url=https://nchc.dl.sourceforge.net/project/sigar/sigar/1.6/hyperic-sigar-1.6.4.zip
...
[INFO] storm-pmml-examples ................................ SUCCESS [  1.505 s]
[INFO] storm-jms-examples ................................. SUCCESS [ 16.925 s]
[INFO] storm-rocketmq-examples ............................ SUCCESS [  1.869 s]
[INFO] Storm Perf ......................................... SUCCESS [ 32.079 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  09:51 min
[INFO] Finished at: 2019-06-29T16:52:58+08:00
[INFO] ------------------------------------------------------------------------

编译完成之后,查了一下sigar的二进制版本是打包在storm-metrics模块的 jar 包里的,但是 展开 jar 之后,发现并没有对应的aarch64的版本,所以虽然编译通过了,但是实际执行的时候应该 会有运行时异常。查了一下sigar上确实也有一个 Open Issue, 希望对于aarch64提供支持。

[root@arm-chenrui target]# jar xvf storm-metrics-2.0.1-SNAPSHOT.jar | grep resources
  created: resources/
 inflated: resources/sigar-x86-winnt.dll
 inflated: resources/libsigar-universal-macosx.dylib
 inflated: resources/sigar-x86-winnt.lib
 inflated: resources/libsigar-sparc-solaris.so
 inflated: resources/libsigar-sparc64-solaris.so
 inflated: resources/libsigar-x86-freebsd-5.so
 inflated: resources/libsigar-universal64-macosx.dylib
 inflated: resources/libsigar-pa-hpux-11.sl
 inflated: resources/libsigar-s390x-linux.so
 inflated: resources/libsigar-amd64-solaris.so
 inflated: resources/libsigar-amd64-linux.so
 inflated: resources/libsigar-ppc64-linux.so
 inflated: resources/libsigar-ia64-hpux-11.sl
 inflated: resources/sigar-amd64-winnt.dll
 inflated: resources/libsigar-x86-solaris.so
 inflated: resources/libsigar-ppc-aix-5.so
 inflated: resources/libsigar-ia64-linux.so
 inflated: resources/libsigar-x86-freebsd-6.so
 inflated: resources/libsigar-ppc-linux.so
 inflated: resources/libsigar-amd64-freebsd-6.so
 inflated: resources/libsigar-ppc64-aix-5.so
 inflated: resources/libsigar-x86-linux.so

Unit Tests

编译成功,尝试执行 UT 测试。由于 Storm 通过模块storm-shaded-deps将很多第三方依赖包的 包名进行了修改并重新打包,导致直接执行mvn test会找不到依赖包,例如: org.apache.storm.shade.com.google.common.collect.Lists。 需要首先执行mvn install将 storm-shaded-deps.jar 安装到本地 Maven 仓库中,解决依赖问题。

mvn clean install -DskipTests

由于某些模块依赖没有在 Storm 项目根目录下的pom.xml中声明,所以直接在根目录下执行mvn test, 会遇到 NoClassDefFoundError,这一点官方的开发者文档描述有误,需要使用-pl参数显示 指定要执行的模块测试,如下:

mvn test -pl 'storm-client,storm-server,storm-webapp,storm-core'

storm-clientstorm-webapp模块可以测试成功,但是storm-serverstorm-core测试失败, 原因相同,测试依赖的组件RocksDB包含二进制执行文件,但是没有对aarch64提供支持,导致初始化 RocksDB失败。

<dependency>
    <groupId>org.rocksdb</groupId>
    <artifactId>rocksdbjni</artifactId>
    <version>5.18.3</version>
</dependency>
[root@arm-chenrui test]# jar xvf rocksdbjni-5.18.3.jar | grep librocksdbjni
 inflated: librocksdbjni-linux32.so
 inflated: librocksdbjni-linux64.so
 inflated: librocksdbjni-osx.jnilib
 inflated: librocksdbjni-linux-ppc64le.so
 inflated: librocksdbjni-win64.dll
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.609 s <<< FAILURE! - in org.apache.storm.TickTupleTest
[ERROR] testTickTupleWorksWithSystemBolt  Time elapsed: 0.609 s  <<< ERROR!
java.lang.UnsatisfiedLinkError: /tmp/librocksdbjni8914565631636894594.so: /tmp/librocksdbjni8914565631636894594.so: cannot open shared object file: No such file or directory (Possible cause: can't load AMD 64-bit .so on a AARCH64-bit platform)
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
        at java.lang.Runtime.load0(Runtime.java:809)
        at java.lang.System.load(System.java:1086)
        at org.rocksdb.NativeLibraryLoader.loadLibraryFromJar(NativeLibraryLoader.java:78)
        at org.rocksdb.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:56)
        at org.rocksdb.RocksDB.loadLibrary(RocksDB.java:64)
        at org.rocksdb.RocksDB.<clinit>(RocksDB.java:35)
        at org.apache.storm.metricstore.rocksdb.RocksDbStore.prepare(RocksDbStore.java:67)
        at org.apache.storm.metricstore.MetricStoreConfig.configure(MetricStoreConfig.java:33)
        at org.apache.storm.daemon.nimbus.Nimbus.<init>(Nimbus.java:533)
        at org.apache.storm.LocalCluster.<init>(LocalCluster.java:244)
        at org.apache.storm.LocalCluster.<init>(LocalCluster.java:126)
        at org.apache.storm.LocalCluster$Builder.build(LocalCluster.java:1234)
        at org.apache.storm.TickTupleTest.testTickTupleWorksWithSystemBolt(TickTupleTest.java:64)
...

RocksDB社区的 issue 列表 来看,aarch64的支持工作正在进行中,还有部分 PR 没有合入,肯定要等到 6.0.1 以后的版本才能 提供支持了,但是很幸运开源社区已经有了一些工作基础,感谢开源开发者。

查看了一下RocksDB Java 部分的代码,Jar 中的二进制代码是在最后一步加载的,所以还有一个 规避方案,就是在环境上提供自己编译的aarch64的二进制包,这个还没有验证过,过两天试一下。

public synchronized void loadLibrary(String var1) throws IOException {
    try {
        System.loadLibrary(sharedLibraryName);
    } catch (UnsatisfiedLinkError var5) {
        try {
            System.loadLibrary(jniLibraryName);
        } catch (UnsatisfiedLinkError var4) {
            this.loadLibraryFromJar(var1);
        }
    }
}

问题

想要推动一个大型软件支持 ARM,例如:Storm,绝对不是增加一个 ARM CI 就可以完成的工作, CI 仅仅是发现问题,解决问题还是要靠在开源社区长时间的工作积累。举一个简单的例子,支持 ARM 可能需要替换第三方库,例如:leveldbjni,随之而来的就大量的重构和重新测试的工作,增加一个 ARM 版本还需要后续持续的支持和问题跟进,而 ARM 的客户需求又不是特别广泛,想要找到一起工作的 开源开发者是比较难的,因此很多开源项目是比较犹豫的。在这种情况下,长期持久的战略投入是 必要条件,构建 ARM 软件生态没有捷径



Published

04 July 2019

Category

ARM

Tags