テクノロジー・リーダーシップ

コンテナ環境に適応し進化を続けるJavaエコシステム

記事をシェアする:

Javaは業務システムの開発言語として重要な言語であり、ソフトウェア資産の活用の観点から今後も使われ続けると考えられています。一方、コンテナやサーバーレスなどクラウド技術の普及により、Java VM上で実行されるJavaプログラムはメモリ使用量や起動時間の点で改善が求められてきました。このような課題をネイティブ・バイナリー化で改善する技術の実用化が始まりつつあります。この技術の活用を容易にするオープンソースのJavaフレームワークQuarkusと、ネイティブ・バイナリー化の可能性を紹介します。

クラウドアプリケーション記述言語としてのJava®の特性

マイクロサービスなどのクラウド向けアーキテクチャーの普及により、コンテナベースのアプリケーション開発が広く用いられるようになり、サービスを実装するプログラミング言語やフレームワークも多様化してきました。しかし、ビジネスロジックなどアプリケーションの基幹部分は、豊富なライブラリなどのソフトウェア資産を活用できることから、依然としてJavaが広く使われています。

一方、コンテナ環境におけるJavaの弱点としては、実行環境としてJava VMが必須であることに起因する、リソース使用量の増大や起動時間の長さが挙げられます。これらの弱点は、負荷の急増時にコンテナ数を増やして対応するアーキテクチャーでは、スケーラビリティの制約要因となります。

クラウド指向アプリケーションフレームワークQuarkusとは

Red Hatがオープンソースで開発し、商用サポートも行っているWebアプリケーションフレームワークQuarkus [1] は、Javaプログラムのスケーラビリティをネイティブ・バイナリー化によって改善する手段を提供します。Javaクラスファイルをさらにコンパイルしてネイティブ・バイナリー化することで、Java VMを使わずにプログラムが実行できるようになり、Java VMによるリソース使用量や、Java VM自体の初期化などJava特有のオーバーヘッドを削減できます。

Quarkusは、Eclipse MicroProfile® [2] やJAX-RSなど最新のWeb標準に準拠すると共に、依存性注入(Dependency Injection、以下DI)を活用してプログラム作成の生産性向上を目指したWebアプリケーションフレームワークです。RESTサービスなどマイクロサービスを作成するのに適しており、MongoDB®を始めとしたDB接続、トランザクション処理、認証処理に対応したライブラリ(エクステンションと呼ばれる)を組み込むことで、DIを活用して生産性・保守性を向上しています。Spring Bootフレームワークに近いアーキテクチャーのため、フレームワーク乗り換えの学習コストも低くなっています。さらにQuarkusでは、通常はプログラム実行時に行われるDIの解決を可能な限りビルド時に行うことで、従来のDIフレームワークより実行時オーバーヘッドを削減できます。

Quarkusのエクステンションは、ネイティブ・バイナリー化の際にも活用されます。Javaプログラムのネイティブ・バイナリー化は以前より研究されていますが、Java言語の特徴である動的クラスロードやリフレクションなどの機能のために、アプリケーション実行時でないと実際に使われるコードを特定できない場合があることが課題になっていました。Quarkusでは、フレームワークが用意したアノテーションとエクステンションのみでDI機能を実装可能にすることと、エクステンションにネイティブ・バイナリー化に必要なメタデータを付加することで、これらの言語機能の制約を解決し、Javaアプリケーションのネイティブ・バイナリー化を実現しました。

Quarksを用いたJavaネイティブ・バイナリー化の効果

Quarkusを用いてJavaアプリケーションを実装し、さらにネイティブ・バイナリー化した場合の効果は、QuarkusプロジェクトWebサイトのトップページ [1] でも紹介されています。

quarkusの転載画像 Memory in Megabytes

※画像はquarkus Webサイトより転載

メモリ使用量の比較では、簡単なRESTサービスを従来のソフトウェアスタックを使った場合と比較して、Quarkusを使うことで46%削減、ネイティブ・バイナリー化すると91%と大きく削減されています。データベースへのアクセスを含むCRUDサービスでも、それぞれ31%、および、87%削減されています。また、プログラムを起動してから、最初のリクエストに応答するまでの所要時間の比較では、RESTサービスとCRUDサービスのどちらも、Quarkusを使うことで78%、ネイティブ・バイナリー化で99%と大幅な削減となっています。特に、ネイティブ・バイナリー化した場合は、最初の応答までの時間が0.05秒未満となり、スケーラビリティの改善に大きく貢献できることが分かります。

一方、ネイティブ・バイナリー化は、ピークパフォーマンスの点で改善の余地があることが、Quarkusプロジェクトのblogで紹介されています [3] 。この記事では、ネイティブ・バイナリー化したプログラムの最大スループットは、QuarkusアプリケーションをJava VM上で実行した場合の半分強、平均レスポンスタイムが約2倍になっています。この理由の一つとして考えられることは、Java VMのjust-in-time (JIT)コンパイラーと、ネイティブ・バイナリー化で用いられる事前コンパイラーの最適化能力の違いです。

JITコンパイラーはプログラム実行時の情報を活用して積極的な最適化を行うのに対して、事前コンパイラーでは実行時情報を利用できません。一方、事前コンパイラーではプログラム全体をコンパイル対象にできる点でJITコンパイラーより有利ですが、JITコンパイラーはJavaが公開されて以来25年以上に渡る研究の成果が適用されているのに対し、Javaの本格的な事前コンパイラーの開発は、2016年にJEP 295[4] で提案されてから5年程度しか経っていないため、まだ改善の余地があると考えられます。事実上Javaの事前コンパイラーの標準となっているGraalVM™ Native Image [5]はオープンソースで活発に開発されており、さらなる性能改善が期待されています。

Quarkusを使うことで、DIなどJavaの動的機能が使われていてもプログラム全体をコンパイル対象にできます。プログラム全体の解析を活用した最適化は、従来のJava JITコンパイラーでは動的機能のサポートが制約となるため適用できず、あまり研究されていない分野でした。Red HatとIBMはこのような最適化の重要性に注目し、その研究を行うコンパイラー・フレームワークqbicc [6]を開発中で、オープンソースとして公開しています。qbiccを活用して、ネイティブ・バイナリー化したプログラムの性能向上に貢献したいと考えています。

Javaは業務アプリケーションの開発に長く使われてきたことで、一部の開発者から「古い言語」と見なす論調を見聞きすることもあります。しかし、Java言語自体も、Javaプログラム向けフレームワークなどのエコシステムも、クラウドコンピューティングやサーバーレスなどの新しいコンピューティング環境に適応するために革新を続けています。今後とも業務アプリケーション開発の主要言語であり続けると考えられることから、Quarkusなどの新しいエコシステムを積極的に採用し、新しいコンピューティング環境に適したアーキテクチャーを検討してはいかがでしょうか。

参考文献

[1] Quarkus – Supersonic Subatomic Java.
[2] MicroProfile.
[3] Quarkus Runtime Performance.
[4] JEP 295: Ahead-of-Time Compilation.
[5] GraalVM Native Image.
[6] qbicc: Experimental static compiler for Java programs.


緒方 一則
緒方 一則
東京基礎研究所、Research Stuff Member/IBM Academy of Technology member

東京基礎研究所に異動後、Java VMの性能向上や性能評価の研究に従事。DockerやOpenJDKなどのオープンソースをLinux on Power向けに最適化や機能改善する研究にも取り組んでいる。

More テクノロジー・リーダーシップ stories
2021年11月16日

グローバル企業における研究者の働き方と、研究者を支えるコミュニティー活動

IBM Researchのハイブリッドクラウド研究 IBM Researchは世界の7つの地域に17の研究所があり、密に協業しながら最新技術の研究開発をしています。私はIBM東京基礎研究所で、Hybrid Cloud & […]

さらに読む