© 2019 NTT DATA Corporation
2019/6/24 日本Springユーザ会主催 Spring I/O 2019報告会
株式会社NTTデータ システム技術本部 高須隼太
GraalVMの概要と、Native-Image化による
Spring Boot爆速化の夢
© 2019 NTT DATA Corporation 2
名前:高須 隼太(たかす はやた)
所属:株式会社NTTデータ
システム技術本部 インテグレーション技術センタ
仕事:Struts → Springのマイグレーションを専門として
様々な更改プロジェクトを支援しています
その他:JSUG 初参加
CodeZineにSpring I/O 2019参加レポートを寄稿予定!
誰?
© 2019 NTT DATA Corporation 3
Spring I/O 2019の講演内容を元に、
GraalVMって何?すごいの?
Springで使えそう?
をかいつまんで説明します
何しに来たの?
© 2019 NTT DATA Corporation 4
1. GraalVMってなに?
2. GraalVMを支える技術
– Graalコンパイラ
– Truffle
– Native Image
3. GraalVMをSpring Bootで使うには
– 起動JDKとしての利用
– Native Image化の現状と課題
– 今後の対応予定
もくじ
※1,2の引用元:『GraalVM for Java developers』 Oleg Šelajev – Oracle
© 2019 NTT DATA Corporation 5
• Oracleが開発した多言語対応の仮想マシン
• JVM言語のネイティブコンパイルに対応
• 2019年5月に本番運用可能バージョン「GraalVM 19.0」リリース
GraalVMってなに?
© 2019 NTT DATA Corporation 6
GraalVMの主要技術
GraalVM
Graal
コンパイラ
Truffle
Native
Image
© 2019 NTT DATA Corporation 7
GraalVMの主要技術
GraalVM
Graal
コンパイラ
Truffle
Native
Image
© 2019 NTT DATA Corporation 8
GraalVM従来のJVM
• JIT(Just-In-Time)コンパイラ
• Javaで実装されているため、維持保守や改良が容易
• 最適化技術に改良が加えられ、パフォーマンスが向上
Graalコンパイラ
HotSpot VM
Compiler Interface
C1コンパイラ C2コンパイラ
HotSpot VM
Compiler
Interface
C1コンパイラ
Graal
コンパイラ
JVMCI
C++
Java
© 2019 NTT DATA Corporation 9
JVMベンチマーク(Renaissance Benchmark Suite)
https://renaissance.dev/
• 従来のOpenJDKに比べて、様々なベンチマークで速度が向上!
© 2019 NTT DATA Corporation 10
Stream APIベンチマーク
private double[] values
= new double[2000000];
public double mapReduce() {
return Arrays.stream(values)
.map(x -> x + 1)
.map(x -> x * 2)
.map(x -> x + 5)
.reduce(0, Double::sum);
}
https://medium.com/graalvm/stream-api-performance-with-graalvm-be6cfe7fbb52
© 2019 NTT DATA Corporation 11
GraalVMの主要技術
GraalVM
Graal
コンパイラ
Truffle
Native
Image
© 2019 NTT DATA Corporation 12
• 言語インタプリタの実装フレームワーク
• 1つのVM上で様々な言語の相互運用が可能(Polyglot VM)
• Graalコンパイラを利用して高速実行が可能
Truffle
Truffle
LLVM
Graalコンパイラ
© 2019 NTT DATA Corporation 13
• Javaから他の言語を簡潔に呼び出し可能
Polyglot
import org.graalvm.polyglot.*;
public class HelloPolyglotWorld {
public static void main(String[] args) throws Exception {
System.out.println("Hello World from Java!");
Context context = Context.newBuilder().allowAllAccess(true).build();
context.eval("js", "print('Hello World from JavaScript!');");
context.eval("python", "print('Hello World from Python!')");
context.eval("ruby", "puts 'Hello World from Ruby!'");
context.eval("R", "print('Hello World from R!')");
}
}
© 2019 NTT DATA Corporation 14
JavaScriptベンチマーク(Octane benchmark)
https://medium.com/graalvm/oracle-graalvm-announces-support-for-nashorn-migration-c04810d75c1f
• Nashorn, Rhinoに比べて、圧倒的に速いJavaScript実行
© 2019 NTT DATA Corporation 15
GraalVMの主要技術
GraalVM
Graal
コンパイラ
Truffle
Native
Image
© 2019 NTT DATA Corporation 16
• JVM言語をAOT(Ahead-Of-Time)コンパイルしたもの
• VMが組込まれており、スタンドアロンで実行可能
• アプリ起動時にクラスロードや初期化処理が不要
→ 超高速起動が見込める!
Native Image
https://medium.com/graalvm/understanding-class-initialization-in-graalvm-native-image-generation-d765b7e4d6ed
Native Image
© 2019 NTT DATA Corporation 17
役に立ちそうなことは
わかった
© 2019 NTT DATA Corporation 18
じゃあ、Springでも
使えるのか?
© 2019 NTT DATA Corporation 19
• Spring Bootの起動JDKの代わりに使うなら超簡単
• インストールフォルダのbin/javaにパスを通すだけ
自分で試してみる
© 2019 NTT DATA Corporation 20
• Spring Bootの起動JDKの代わりに使うなら超簡単
• インストールフォルダのbin/javaにパスを通すだけ
• 起動が少し速くなっている
自分で試してみる
$ java –jar demo-0.0.1-SNAPSHOT.jar
…
INFO 1558 --- [main] com.example.demo.DemoApplication :
Started DemoApplication in 2.905 seconds (JVM running for 3.487)
$ java –jar demo-0.0.1-SNAPSHOT.jar
…
INFO 1561 --- [main] com.example.demo.DemoApplication :
Started DemoApplication in 2.65 seconds (JVM running for 3.283)
GraalVM CE 19.0.2 → 2.65秒(9%向上)
OpenJDK 12.0.1 → 2.905秒
※Hello Worldレスポンス返すだけのアプリで計測。繰り返して平均取っても大体同じくらい
© 2019 NTT DATA Corporation 21
• 残念ながら現時点では制約が多い・・・(そのままではコンパイルできない)
じゃあ目玉のNative Image化は?
https://github.com/oracle/graal/blob/master/substratevm/LIMITATIONS.md
https://github.com/spring-projects/spring-framework/issues/21529
静的なAOTコンパイルを適用するためには、
手動による追加設定・コマンド引数の指定が必要
Springはリフレクションやダイナミックプロキシによる
動的なクラス生成を多用
↓
https://github.com/spring-projects/spring-framework/issues/22968
Andy Clement (on GitHub)
「FW本体およびツールレベル両方で、
GraalVM用の機能を実装する必要がある」
https://github.com/spring-projects/spring-framework/wiki/GraalVM-native-image-support
※制約の詳細や現在の設定ノウハウ等はGitHub参照
© 2019 NTT DATA Corporation 22
• 2020年Q2のSpring 5.3でNative-Image化に対応予定!
今後の対応予定はあるの?
Juergen Hoeller
Spring開発リーダー
• Spring Boot Native-Image化機能の「乱雑なプロトタイプ」が開発・公開中
https://github.com/aclement/spring-boot-graal-feature
2020年Q2リリース予定のSpring 5.3では設定が
自動的に行われるよう、GraalVM開発チームと協力
して技術的課題の解決に努めていく。
© 2019 NTT DATA Corporation 23
• ダウンロード・ビルドする
• sample/demo のSpring Bootアプリ (Hello world) をネイティブイメージ化してみる
プロトタイプを自分で試してみる①
$ git clone https://github.com/aclement/spring-boot-graal-feature.git
$ mvn package
…
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-graal-feature ---
[INFO] Building jar: /xxx/spring-boot-graal-feature/target/spring-boot-graal-
feature-0.5.0.BUILD-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
$ sample/demo/compile.sh
© 2019 NTT DATA Corporation 24
• ダウンロード・ビルドする
• sample/demo のSpring Bootアプリ (Hello world) をネイティブイメージ化してみる
プロトタイプを自分で試してみる①
※2019/06時点の実装
$ git clone https://github.com/aclement/spring-boot-graal-feature.git
$ mvn package
…
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-graal-feature ---
[INFO] Building jar: /xxx/spring-boot-graal-feature/target/spring-boot-graal-
feature-0.5.0.BUILD-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
$ sample/demo/compile.sh
• 対象jarを分解して
• native化機能のクラスファイルにマージし、
• 引数にクラスパスを指定してnative-imageコマンドを叩く 実装になっている
© 2019 NTT DATA Corporation 25
• native compileに時間がかかったが、なんとか実行ファイルが完成
プロトタイプを自分で試してみる②
[demo:1255] [total]: 700,054.90 ms
© 2019 NTT DATA Corporation 26
• native compileに時間がかかったが、なんとか実行ファイルが完成
プロトタイプを自分で試してみる②
[demo:1255] [total]: 700,054.90 ms →
_人人人人人_
> 11分 <
 ̄Y^Y^Y^Y^Y^ ̄
© 2019 NTT DATA Corporation 27
• native compileに時間がかかったが、なんとか実行ファイルが完成
• 早速jar実行と比較してみる
プロトタイプを自分で試してみる②
[demo:1255] [total]: 700,054.90 ms →
_人人人人人_
> 11分 <
 ̄Y^Y^Y^Y^Y^ ̄
GraalVM CE 19.0.2 (native-image for Mac OS HS) → 0.081秒
$ ./demo
…
INFO: Started DemoApplication in 0.081 seconds (JVM running for 0.084)
$ java –jar demo-0.0.1-SNAPSHOT.jar
…
INFO 1558 --- [main] com.example.demo.DemoApplication :
Started DemoApplication in 2.905 seconds (JVM running for 3.487)
OpenJDK 12.0.1 → 2.905秒
※繰り返して平均取っても大体同じくらい
© 2019 NTT DATA Corporation 28
• native compileに時間がかかったが、なんとか実行ファイルが完成
• 早速jar実行と比較してみる
プロトタイプを自分で試してみる②
[demo:1255] [total]: 700,054.90 ms →
_人人人人人_
> 11分 <
 ̄Y^Y^Y^Y^Y^ ̄
GraalVM CE 19.0.2 (native-image for Mac OS HS) → 0.081秒
$ ./demo
…
INFO: Started DemoApplication in 0.081 seconds (JVM running for 0.084)
$ java –jar demo-0.0.1-SNAPSHOT.jar
…
INFO 1558 --- [main] com.example.demo.DemoApplication :
Started DemoApplication in 2.905 seconds (JVM running for 3.487)
OpenJDK 12.0.1 → 2.905秒
_人人人人人_
> 35倍 <
 ̄Y^Y^Y^Y^Y^ ̄
※繰り返して平均取っても大体同じくらい
© 2019 NTT DATA Corporation 29
• 起動速度は流石で、性能が重要なシステムにハマる余地はあるかも
• ただ、まだ発展途上感は否めない
• 複雑なSpringアプリケーションをNative化できるかは未知数
→ Native化可能なクラスは増えているが、まだ全てではない
• ビルド時間が非常に長い
→ OSやスペックによる気もするが・・・
• 来年のリリースに向けて今後に期待!
プロトタイプに関する所感
© 2019 NTT DATA Corporation 30
• GraalVM = 速く、様々な言語に対応している仮想マシン
• JDKの代わりに起動に使うだけでも有用かも
• Native-Image化で起動速度が爆速になるが、Spring Bootで使う
にはまだ課題有
• Spring 5.3で対応予定のため、2020まで待つべし!
• 開発中の機能が公開されているので試してみてもいいかも
まとめ
© 2019 NTT DATA Corporation

GraalVM の概要と、Native Image 化によるSpring Boot 爆速化の夢

  • 1.
    © 2019 NTTDATA Corporation 2019/6/24 日本Springユーザ会主催 Spring I/O 2019報告会 株式会社NTTデータ システム技術本部 高須隼太 GraalVMの概要と、Native-Image化による Spring Boot爆速化の夢
  • 2.
    © 2019 NTTDATA Corporation 2 名前:高須 隼太(たかす はやた) 所属:株式会社NTTデータ システム技術本部 インテグレーション技術センタ 仕事:Struts → Springのマイグレーションを専門として 様々な更改プロジェクトを支援しています その他:JSUG 初参加 CodeZineにSpring I/O 2019参加レポートを寄稿予定! 誰?
  • 3.
    © 2019 NTTDATA Corporation 3 Spring I/O 2019の講演内容を元に、 GraalVMって何?すごいの? Springで使えそう? をかいつまんで説明します 何しに来たの?
  • 4.
    © 2019 NTTDATA Corporation 4 1. GraalVMってなに? 2. GraalVMを支える技術 – Graalコンパイラ – Truffle – Native Image 3. GraalVMをSpring Bootで使うには – 起動JDKとしての利用 – Native Image化の現状と課題 – 今後の対応予定 もくじ ※1,2の引用元:『GraalVM for Java developers』 Oleg Šelajev – Oracle
  • 5.
    © 2019 NTTDATA Corporation 5 • Oracleが開発した多言語対応の仮想マシン • JVM言語のネイティブコンパイルに対応 • 2019年5月に本番運用可能バージョン「GraalVM 19.0」リリース GraalVMってなに?
  • 6.
    © 2019 NTTDATA Corporation 6 GraalVMの主要技術 GraalVM Graal コンパイラ Truffle Native Image
  • 7.
    © 2019 NTTDATA Corporation 7 GraalVMの主要技術 GraalVM Graal コンパイラ Truffle Native Image
  • 8.
    © 2019 NTTDATA Corporation 8 GraalVM従来のJVM • JIT(Just-In-Time)コンパイラ • Javaで実装されているため、維持保守や改良が容易 • 最適化技術に改良が加えられ、パフォーマンスが向上 Graalコンパイラ HotSpot VM Compiler Interface C1コンパイラ C2コンパイラ HotSpot VM Compiler Interface C1コンパイラ Graal コンパイラ JVMCI C++ Java
  • 9.
    © 2019 NTTDATA Corporation 9 JVMベンチマーク(Renaissance Benchmark Suite) https://renaissance.dev/ • 従来のOpenJDKに比べて、様々なベンチマークで速度が向上!
  • 10.
    © 2019 NTTDATA Corporation 10 Stream APIベンチマーク private double[] values = new double[2000000]; public double mapReduce() { return Arrays.stream(values) .map(x -> x + 1) .map(x -> x * 2) .map(x -> x + 5) .reduce(0, Double::sum); } https://medium.com/graalvm/stream-api-performance-with-graalvm-be6cfe7fbb52
  • 11.
    © 2019 NTTDATA Corporation 11 GraalVMの主要技術 GraalVM Graal コンパイラ Truffle Native Image
  • 12.
    © 2019 NTTDATA Corporation 12 • 言語インタプリタの実装フレームワーク • 1つのVM上で様々な言語の相互運用が可能(Polyglot VM) • Graalコンパイラを利用して高速実行が可能 Truffle Truffle LLVM Graalコンパイラ
  • 13.
    © 2019 NTTDATA Corporation 13 • Javaから他の言語を簡潔に呼び出し可能 Polyglot import org.graalvm.polyglot.*; public class HelloPolyglotWorld { public static void main(String[] args) throws Exception { System.out.println("Hello World from Java!"); Context context = Context.newBuilder().allowAllAccess(true).build(); context.eval("js", "print('Hello World from JavaScript!');"); context.eval("python", "print('Hello World from Python!')"); context.eval("ruby", "puts 'Hello World from Ruby!'"); context.eval("R", "print('Hello World from R!')"); } }
  • 14.
    © 2019 NTTDATA Corporation 14 JavaScriptベンチマーク(Octane benchmark) https://medium.com/graalvm/oracle-graalvm-announces-support-for-nashorn-migration-c04810d75c1f • Nashorn, Rhinoに比べて、圧倒的に速いJavaScript実行
  • 15.
    © 2019 NTTDATA Corporation 15 GraalVMの主要技術 GraalVM Graal コンパイラ Truffle Native Image
  • 16.
    © 2019 NTTDATA Corporation 16 • JVM言語をAOT(Ahead-Of-Time)コンパイルしたもの • VMが組込まれており、スタンドアロンで実行可能 • アプリ起動時にクラスロードや初期化処理が不要 → 超高速起動が見込める! Native Image https://medium.com/graalvm/understanding-class-initialization-in-graalvm-native-image-generation-d765b7e4d6ed Native Image
  • 17.
    © 2019 NTTDATA Corporation 17 役に立ちそうなことは わかった
  • 18.
    © 2019 NTTDATA Corporation 18 じゃあ、Springでも 使えるのか?
  • 19.
    © 2019 NTTDATA Corporation 19 • Spring Bootの起動JDKの代わりに使うなら超簡単 • インストールフォルダのbin/javaにパスを通すだけ 自分で試してみる
  • 20.
    © 2019 NTTDATA Corporation 20 • Spring Bootの起動JDKの代わりに使うなら超簡単 • インストールフォルダのbin/javaにパスを通すだけ • 起動が少し速くなっている 自分で試してみる $ java –jar demo-0.0.1-SNAPSHOT.jar … INFO 1558 --- [main] com.example.demo.DemoApplication : Started DemoApplication in 2.905 seconds (JVM running for 3.487) $ java –jar demo-0.0.1-SNAPSHOT.jar … INFO 1561 --- [main] com.example.demo.DemoApplication : Started DemoApplication in 2.65 seconds (JVM running for 3.283) GraalVM CE 19.0.2 → 2.65秒(9%向上) OpenJDK 12.0.1 → 2.905秒 ※Hello Worldレスポンス返すだけのアプリで計測。繰り返して平均取っても大体同じくらい
  • 21.
    © 2019 NTTDATA Corporation 21 • 残念ながら現時点では制約が多い・・・(そのままではコンパイルできない) じゃあ目玉のNative Image化は? https://github.com/oracle/graal/blob/master/substratevm/LIMITATIONS.md https://github.com/spring-projects/spring-framework/issues/21529 静的なAOTコンパイルを適用するためには、 手動による追加設定・コマンド引数の指定が必要 Springはリフレクションやダイナミックプロキシによる 動的なクラス生成を多用 ↓ https://github.com/spring-projects/spring-framework/issues/22968 Andy Clement (on GitHub) 「FW本体およびツールレベル両方で、 GraalVM用の機能を実装する必要がある」 https://github.com/spring-projects/spring-framework/wiki/GraalVM-native-image-support ※制約の詳細や現在の設定ノウハウ等はGitHub参照
  • 22.
    © 2019 NTTDATA Corporation 22 • 2020年Q2のSpring 5.3でNative-Image化に対応予定! 今後の対応予定はあるの? Juergen Hoeller Spring開発リーダー • Spring Boot Native-Image化機能の「乱雑なプロトタイプ」が開発・公開中 https://github.com/aclement/spring-boot-graal-feature 2020年Q2リリース予定のSpring 5.3では設定が 自動的に行われるよう、GraalVM開発チームと協力 して技術的課題の解決に努めていく。
  • 23.
    © 2019 NTTDATA Corporation 23 • ダウンロード・ビルドする • sample/demo のSpring Bootアプリ (Hello world) をネイティブイメージ化してみる プロトタイプを自分で試してみる① $ git clone https://github.com/aclement/spring-boot-graal-feature.git $ mvn package … [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-graal-feature --- [INFO] Building jar: /xxx/spring-boot-graal-feature/target/spring-boot-graal- feature-0.5.0.BUILD-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS $ sample/demo/compile.sh
  • 24.
    © 2019 NTTDATA Corporation 24 • ダウンロード・ビルドする • sample/demo のSpring Bootアプリ (Hello world) をネイティブイメージ化してみる プロトタイプを自分で試してみる① ※2019/06時点の実装 $ git clone https://github.com/aclement/spring-boot-graal-feature.git $ mvn package … [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ spring-boot-graal-feature --- [INFO] Building jar: /xxx/spring-boot-graal-feature/target/spring-boot-graal- feature-0.5.0.BUILD-SNAPSHOT.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS $ sample/demo/compile.sh • 対象jarを分解して • native化機能のクラスファイルにマージし、 • 引数にクラスパスを指定してnative-imageコマンドを叩く 実装になっている
  • 25.
    © 2019 NTTDATA Corporation 25 • native compileに時間がかかったが、なんとか実行ファイルが完成 プロトタイプを自分で試してみる② [demo:1255] [total]: 700,054.90 ms
  • 26.
    © 2019 NTTDATA Corporation 26 • native compileに時間がかかったが、なんとか実行ファイルが完成 プロトタイプを自分で試してみる② [demo:1255] [total]: 700,054.90 ms → _人人人人人_ > 11分 <  ̄Y^Y^Y^Y^Y^ ̄
  • 27.
    © 2019 NTTDATA Corporation 27 • native compileに時間がかかったが、なんとか実行ファイルが完成 • 早速jar実行と比較してみる プロトタイプを自分で試してみる② [demo:1255] [total]: 700,054.90 ms → _人人人人人_ > 11分 <  ̄Y^Y^Y^Y^Y^ ̄ GraalVM CE 19.0.2 (native-image for Mac OS HS) → 0.081秒 $ ./demo … INFO: Started DemoApplication in 0.081 seconds (JVM running for 0.084) $ java –jar demo-0.0.1-SNAPSHOT.jar … INFO 1558 --- [main] com.example.demo.DemoApplication : Started DemoApplication in 2.905 seconds (JVM running for 3.487) OpenJDK 12.0.1 → 2.905秒 ※繰り返して平均取っても大体同じくらい
  • 28.
    © 2019 NTTDATA Corporation 28 • native compileに時間がかかったが、なんとか実行ファイルが完成 • 早速jar実行と比較してみる プロトタイプを自分で試してみる② [demo:1255] [total]: 700,054.90 ms → _人人人人人_ > 11分 <  ̄Y^Y^Y^Y^Y^ ̄ GraalVM CE 19.0.2 (native-image for Mac OS HS) → 0.081秒 $ ./demo … INFO: Started DemoApplication in 0.081 seconds (JVM running for 0.084) $ java –jar demo-0.0.1-SNAPSHOT.jar … INFO 1558 --- [main] com.example.demo.DemoApplication : Started DemoApplication in 2.905 seconds (JVM running for 3.487) OpenJDK 12.0.1 → 2.905秒 _人人人人人_ > 35倍 <  ̄Y^Y^Y^Y^Y^ ̄ ※繰り返して平均取っても大体同じくらい
  • 29.
    © 2019 NTTDATA Corporation 29 • 起動速度は流石で、性能が重要なシステムにハマる余地はあるかも • ただ、まだ発展途上感は否めない • 複雑なSpringアプリケーションをNative化できるかは未知数 → Native化可能なクラスは増えているが、まだ全てではない • ビルド時間が非常に長い → OSやスペックによる気もするが・・・ • 来年のリリースに向けて今後に期待! プロトタイプに関する所感
  • 30.
    © 2019 NTTDATA Corporation 30 • GraalVM = 速く、様々な言語に対応している仮想マシン • JDKの代わりに起動に使うだけでも有用かも • Native-Image化で起動速度が爆速になるが、Spring Bootで使う にはまだ課題有 • Spring 5.3で対応予定のため、2020まで待つべし! • 開発中の機能が公開されているので試してみてもいいかも まとめ
  • 31.
    © 2019 NTTDATA Corporation