1.6K Views
January 15, 21
スライド概要
ヤフーではApache Hadoopコミュニティにおいて、特にJavaの最新バージョンに追従する取り組みを続けています。最新バージョンに追従していくことで、世界中のHadoop利用者が新たに導入されたGCアルゴリズムを活用したりJava自体の性能向上の恩恵を受けたりすることができます。昨年にはJava 11対応について紹介しましたが、本セッションでは次のLTSとなるJava 17対応に向けた課題について紹介します。
参考: https://www.slideshare.net/techblogyahoo/java11-apache-hadoop-146834504
Yahoo! JAPAN Tech Confernece 2021 は2021年1月22日に開催しました。
https://techconference.yahoo.co.jp/2021/
2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp
巨大OSSプロジェクトにおいてJavaの最新バージョンに追従するための課題 ヤフー株式会社 データ統括本部 / 第9代・第10代黒帯 (Hadoop) 鯵坂 明 ©2021 Yahoo Japan Corporation All rights reserved.
鯵坂 明 第9代・第10代黒帯 (Hadoop) Apache Hadoopの開発に携わりながら、社内利用に向けた検証・開発・トラブルシュートを担当しています 最近の趣味:ボルダリング、競プロ、中国語の勉強 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ©2021 Yahoo Japan Corporation All rights reserved.
このセッションについて ヤフーではApache Hadoopコミュニティにおいて、特にJavaの最新バージョンに追従する取り組みを続けています。本セッションでは次のLTSとなるJava 17対応に向けた課題と、その解決に向けた取り組みについて紹介します。 ©2021 Yahoo Japan Corporation All rights reserved.
HadoopでJavaの最新バージョンを使うモチベーション 性能向上のため • TLS 1.3対応などセキュリティ系の機能はJava 8にもバックポートされていく • GC処理の改善など性能に影響する機能はバージョンを上げないと入らない • 例えばZGCはJava 14まではexperimental 実際、ヤフーのHDFSクラスタでJava 8から11に上げたらG1GCが爆速になった さらにバージョンを新しくすると、さらに性能向上するのでは? ©2021 Yahoo Japan Corporation All rights reserved.
Hadoopの現状 Java 11のランタイムサポートは完了! 3.3.0から利用可能 • Java 8でコンパイル、Java 11で実行 Java11へのマイグレーションガイド ~Apache Hadoopの事例~ 2019年5月18日 鯵坂 明, 浅沼 孝信 Copyright (C) 2019 Yahoo Japan Corporation. All Rights Reserved. ©2021 Yahoo Japan Corporation All rights reserved.
Hadoopの現状(続き)
最新バージョン(Java 15)だとコンパイルは通るが、失敗するunit testがいくつもあって本番ではまだ動かせそうにない
< > TestConfiguredFailoverProxyProvider Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider
2 [ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.451 s <<< FAILURE! - in org.apache.hadoop.hdfs.server
3 [ERROR] testResolveDomainNameUsingDNS(org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider) Time elap
4 java.lang.AssertionError: nn1 wasn't returned: {host02.test/<unresolved>:8020=24, host01.test/<unresolved>:8020=26}
5 at org.junit.Assert.fail(Assert.java:88)
< > TestDataNodeRollingUpgrade Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade
2 [ERROR] Tests run: 6, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 101.938 s <<< FAILURE! - in org.apache.hadoop.hdfs.serv
3 [ERROR] testWithLayoutChangeAndFinalize(org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade) Time elapsed: 11.15
4 java.lang.NoSuchFieldException: modifiers
5 at java.base/java.lang.Class.getDeclaredField(Class.java:2569)
6 at org.apache.hadoop.hdfs.DFSTestUtil.addDataNodeLayoutVersion(DFSTestUtil.java:1961)
7 at org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade.testWithLayoutChangeAndFinalize(TestDataNodeRollin
©2021 Yahoo Japan Corporation All rights reserved.
Hadoopの現状(続き)
最新バージョン(Java 15)だとコンパイルは通るが、失敗するunit testがいくつもあって本番ではまだ動かせそうにない
< > TestConfiguredFailoverProxyProvider Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider
2 [ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.451 s <<< FAILURE! - in org.apache.hadoop.hdfs.server
3 [ERROR] testResolveDomainNameUsingDNS(org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider) Time elap
4 java.lang.AssertionError: nn1 wasn't returned: {host02.test/<unresolved>:8020=24, host01.test/<unresolved>:8020=26}
5 at org.junit.Assert.fail(Assert.java:88)
< > TestDataNodeRollingUpgrade Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade
2 [ERROR] Tests run: 6, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 101.938 s <<< FAILURE! - in org.apache.hadoop.hdfs.serv
3 [ERROR] testWithLayoutChangeAndFinalize(org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade) Time elapsed: 11.15
4 java.lang.NoSuchFieldException: modifiers
5 at java.base/java.lang.Class.getDeclaredField(Class.java:2569)
6 at org.apache.hadoop.hdfs.DFSTestUtil.addDataNodeLayoutVersion(DFSTestUtil.java:1961)
7 at org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade.testWithLayoutChangeAndFinalize(TestDataNodeRollin
©2021 Yahoo Japan Corporation All rights reserved.
APIの挙動の変化
Javaは強力な後方互換性があることで知られているが、たまに挙動が変わる
• 例)Java 14以降、名前解決できない場合は<unresolved>が付く
| Welcome to JShell -- Version 11.0.9
| For an introduction type: /help intro
jshell> new InetSocketAddress("host01.test", 8080).toString()
$1 ==> "host01.test:8080"
| Welcome to JShell -- Version 15
| For an introduction type: /help intro
jshell> new InetSocketAddress("host01.test", 8080).toString()
$1 ==> "host01.test/<unresolved>:8080"
©2021 Yahoo Japan Corporation All rights reserved.
Hadoopの現状(続き)
最新バージョン(Java 15)だとコンパイルは通るが、失敗するunit testがいくつもあって本番ではまだ動かせそうにない
< > TestConfiguredFailoverProxyProvider Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider
2 [ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.451 s <<< FAILURE! - in org.apache.hadoop.hdfs.server
3 [ERROR] testResolveDomainNameUsingDNS(org.apache.hadoop.hdfs.server.namenode.ha.TestConfiguredFailoverProxyProvider) Time elap
4 java.lang.AssertionError: nn1 wasn't returned: {host02.test/<unresolved>:8020=24, host01.test/<unresolved>:8020=26}
5 at org.junit.Assert.fail(Assert.java:88)
< > TestDataNodeRollingUpgrade Raw
1 [INFO] Running org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade
2 [ERROR] Tests run: 6, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 101.938 s <<< FAILURE! - in org.apache.hadoop.hdfs.serv
3 [ERROR] testWithLayoutChangeAndFinalize(org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade) Time elapsed: 11.15
4 java.lang.NoSuchFieldException: modifiers
5 at java.base/java.lang.Class.getDeclaredField(Class.java:2569)
6 at org.apache.hadoop.hdfs.DFSTestUtil.addDataNodeLayoutVersion(DFSTestUtil.java:1961)
7 at org.apache.hadoop.hdfs.server.datanode.TestDataNodeRollingUpgrade.testWithLayoutChangeAndFinalize(TestDataNodeRollin
©2021 Yahoo Japan Corporation All rights reserved.
final変数の上書きが不可能に
Java 11以前はreflectionで上書き可能だが、Java12以降では禁止
public static void addDataNodeLayoutVersion(final int lv, final String description)
throws NoSuchFieldException, IllegalAccessException {
Preconditions.checkState(expression: lv < DataNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
// Override {@link DataNodeLayoutVersion#CURRENT_LAYOUT_VERSION} via reflection.
Field modifiersField = Field.class.getDeclaredField(name: "modifiers");
modifiersField.setAccessible(true);
Field field = DataNodeLayoutVersion.class.getField(name: "CURRENT_LAYOUT_VERSION");
field.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setInt(obj: null, lv);
field = HdfsServerConstants.class.getField(name: "DATANODE_LAYOUT_VERSION");
field.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.setInt(obj: null, lv);
}
©2021 Yahoo Japan Corporation All rights reserved.
これらの問題はまだ氷山の一角にすぎない Hadoop自体10年以上の歴史がありソースコードが巨大なため、こういった細かい挙動の変化にことごとく引っかかり、都度修正していくことになる • 先ほど紹介した問題はいずれも修正済だが、未対応の問題も多い Hadoop Common / HADOOP-17177 Java upstream support Issue Links is a parent of O YARN-10474 [JDK 12] TestAsyncDispatcher fails OPEN O HDFS-15580 [JDK 12] DFSTestUtil#addDataNodeLayoutVersion fails RESOLVED O HDFS-15685 [JDK 14] TestConfiguredFailoverProxyProvider#testRes... RESOLVED ↑ HADOOP-17178 [JDK 13] Javadoc HTML5 support OPEN relates to ↑ HADOOP-16795 Java 11 compile support OPEN Sub-Tasks 1. [JDK 15] TestDNS fails by UncheckedIOException OPEN Unassigned ©2021 Yahoo Japan Corporation All rights reserved.
今後の主な取り組み ビルド・テスト環境の整備 • API非互換に関する問題にいち早く気付けるようにする Jerseyのバージョンアップ Javadoc HTML5対応 ©2021 Yahoo Japan Corporation All rights reserved.
Jerseyのバージョンアップ Jersey: RESTfulなWebサービスを提供するためのライブラリ • Hadoopでは1系を使っているが、1系はJava 11+でコンパイルすると正常動作しないため、2系以上にバージョンアップしなければならない バージョンアップが非常に困難 • classpathに1系と2系を同居させられないので、Hadoopのmodule個別に修正することができない • Hadoop自体のソースコードが巨大なので修正箇所が多数 • APIの移行ガイドは存在しているものの、網羅性がなくて使い物にならない ©2021 Yahoo Japan Corporation All rights reserved.
PR作成から1年以上たってもまだ対応が終わっていない [WIP] HADOOP-15984. Update jersey from 1.19 to 2.x #763 Open aajisaka wants to merge 21 commits into apache:trunk from aajisaka:HADOOP-15984-3 Conversation 30 Commits 21 Checks 0 Files changed 48 aajisaka commented on Apr 24, 2019 • edited JIRA: https://issues.apache.org/jira/browse/HADOOP-15984 TODO list hadoop-common hadoop-hdfs hadoop-mapreduce hadoop-yarn others Sparkなど関連プロジェクトではすでにJersey 2系にバージョンアップされていて、classpathに1系と2系が混在する問題が起こっている ©2021 Yahoo Japan Corporation All rights reserved.
Javadoc HTML5対応 • Java 11ではHTML4でビルドするように指定していた • しかし、このオプションがJava 13で削除されてしまった • 大量のエラーを地道に修正しなければならない JDK11のJavadoc • Java11からJavadocのデフォルト設定がHTML5に変わった(Java10まではHTML4がデフォルト) • そのままJavadocビルドするとまた大量のエラーが発生 • JavadocのオプションでHTML4でビルドするように指定 (HADOOP-15902) 26 ©2021 Yahoo Japan Corporation All rights reserved.
Javadoc HTML5対応
• hadoop-common moduleだけで100件のエラー
[-> hadoop-mirror git:(trunk) x java -version
openjdk version "15" 2020-09-15
OpenJDK Runtime Environment (build 15+36-1562)
OpenJDK 64-Bit Server VM (build 15+36-1562, mixed mode, sharing)
[-> hadoop-mirror git:(trunk) x mvn clean process-sources javadoc:javadoc-no-fork
-pl hadoop-common-project/hadoop-common > error.log 2>&1
[-> hadoop-mirror git:(trunk) x grep "error:" error.log -A1 | head -n2
[ERROR] /Users/aajisaka/git/ghe.corp/hadoop-mirror/hadoop-common-project/hadoop-
common/src/main/java/org/apache/hadoop/util/InstrumentedReadWriteLock.java:31: e
rror: tag not supported in the generated HTML version: tt
[ERROR] * create instrumented <tt>ReadLock</tt> and <tt>WriteLock</tt>.
[-> hadoop-mirror git:(trunk) x grep "error:" error.log | wc -l
100
©2021 Yahoo Japan Corporation All rights reserved.
まとめ • Javaのバージョンアップ対応は他の機能と比較して地道かつ地味ですが、重要な取り組みなので引き続き対応していきます • Hadoopクラスタの性能改善に直接繋がるので、この発表を聞いた、あるいはスライドを見たみなさまが興味をもって開発に参加してくれると非常に助かります • 2021年秋にリリース予定のJava 17 LTSですぐコンパイルできてすぐ動かせるようになるのが目標です ©2021 Yahoo Japan Corporation All rights reserved.
21 Yahoo! JAPAN Tech Conference 2021 ©2021 Yahoo Japan Corporation All rights reserved.