2022年5月9日 ジェシー・ゴルジンスキー
ジェシー・ゴルジンスキーのこのブログで、Nginxを学ぶことがオープンソースのエコシステムにおいて最大の秘宝であるかも知れない理由を学びましょう。
前回のブログ記事の中で、私は幾つかのオープンソースの「秘宝」について述べました。それらはJSONの処理からディスクスペースの分析に至るまであらゆることができます。偶然にも私がこのブログを始めたとき、Twitterで世論調査を行いました。もちろん、このデータには大きな結論を形成するほどの重要性はありませんが、私はその結果に驚きました。Nginxを使っていないユーザーは、十分に定着したIBM i 用のApache HTTPサーバーに単純に満足していると私は予期していました。ところがそうではなく、とても多くの人々がアプリケーションを直接ウェブに接続していたり、あるいは単にNginxのことを知らなかったりしたのです(図1参照)。この事実に、Nginxは最大の秘宝ではないだろうかと私は思いました。
▲図1:Nginxを使用していないユーザーに対するTwitterの世論調査
ウェブアプリケーションまたはAPIを、NginxまたはApacheのようなHTTPサーバーの背後でホストすることがしばしば推奨されています。HTTPサーバーは、アプリケーションを直ぐに本番環境で使えるようにするのを支援するための多くのことを処理できます。たとえば、次のようなことです:
- 高負荷の状況下で接続をキューイングする
- TLS(Transport Layer Security:トランスポート層セキュリティ)を処理する。IBM i用のHTTPサーバーはデジタル認証マネージャー(DCM)と統合されているが、Nginxはそうではないことに注意
- 様々なHTTPヘッダなどをフィルタリングする
- 認証を処理する
- 静的なコンテンツを(しばしば高水準言語アプリケーションサーバーよりもずっと効率的に)供給する
- 複数の言語・アプリケーションを単一の仮想ホストの背後で処理する
- HTTP要求のログ機能を提供する
今日は、ウェブワークロードのパフォーマンス向上に焦点を当てるつもりです。Nginxは物事を素早く行うためにいくつかの機能を提供しています。最善のアプローチは、あなたが処理しているワークロードのタイプに依って変わります。私は通常ウェブコンテンツを次の4つのカテゴリの内の1つに分類します。つまり、静的コンテンツ、動的で時々変わるコンテンツ、動的で頻繁に変わるコンテンツ、そしてリアルタイム情報です。Nginxは、使用しているプログラミング言語とは無関係に、これらのタイプのそれぞれに対して何らかの機能を提供しています。
カテゴリ1:静的コンテンツ
静的コンテンツは、ウェブトラフィックの大きな部分を占めています。これにはHTMLだけでなく、JavaScriptファイル、イメージなどが含まれます。静的コンテンツをプログラムロジックとは別のディレクトリに保存するのが定石で、大体各ウェブフレームワークはこの静的コンテンツを供給する単純な方法を提供します。たとえば、Express.jsには気の利いたstatic()関数があります。
しかし、アプリケーションプログラムがNginxの背後でホストされているなら、このコンテンツを直接Nginxから供給することができます。このように、ウェブフレームワークは必ずしもそれを取り扱う必要はありません。図2のNginxの構成は1つの例を提供しています。この場合、Nginxはポート番号9333を聴いています。それは静的コンテンツを直接処理し、それ以外の物はすべてポート番号3341のバックエンドのPythonサーバーに処理を委ねています。
▲図2:静的コンテンツを持つNginxの構成
このようにしたい理由は何でしょうか?簡単に言うと、HTTPサーバーは高水準言語フレームワークよりも静的コンテンツをもっと効率的に処理できるのです。デモのために、私は静的コンテンツから成る小さなウェブページをホストし、高負荷の下でパフォーマンスを測定しました。その負荷は、単一CPUのIBM iシステム上で、同時に10個の接続(10ユーザーよりももっと集中的です)を有するというものです。私は複数スレッドのウェブフレームワークであるCherryPyをスタンドアロンで実行した時のパフォーマンスと、Nginxの後ろでCherryPyを動かした時のパフォーマンスを比較しました。図3に示すように、その結果は説得力のあるものでした。1秒間の要求数は5倍に増大しました。応答時間は更に相当な差がありました!
▲図3:静的コンテンツに対するNginxのパフォーマンス
カテゴリ2:動的で時々変わるコンテンツ
多くの場合、ウェブワークロードは静的か動的かのどちらかに分類されますが、動的ワークロードの様々なタイプをさらに区別することが重要です。たとえば、あなたのAPIまたはウェブページが天気予報情報を提供するとしましょう。それは時間の経過と共に変化するので、間違いなくそのデータは「動的」です。しかし、それは常に変化しているわけではありません。多分それは1時間か2時間毎に何回か変化します。
これらのケースでは、コンテンツキャッシングというウェブパフォーマンスの教科書にある最も古いやり方を活用できます。結局のところ、間欠的にしか変化しないデータへのすべての取得要求に対してプログラムに再計算を要求する理由は何でしょうか?そうする代わりに、道理に適った(15分?30分?)という時間間隔でのこの情報を単純にキャッシュすることができます。ウェブサイトまたはAPIが高負荷状態にある時、このやり方はとても役に立ちます。
もちろん、キャッシングそれ自体にはそれ自身のオーバーヘッドがありますから、多くの要素を考慮するべきです。たとえば、1秒間にどれだけの数の要求を処理するか?それらキャッシュされたデータの「ヒット率」は?不確かな場合は、ちょっとした試行錯誤が非常に効果を発揮します。
カテゴリ3:動的で頻繁に変わるコンテンツ
別のケースでは、コンテンツはもっと頻繁に変化しているかも知れません。たとえば、1つのAPIが現在の在庫水準あるいは移動している配送車のGPS座標を公開しているかも知れません。このシナリオにおいては、キャッシングは上手く適合しないと考えるのは自然なことです。しかし、あなたのアプリケーションが高負荷の状況にあるなら、依然としてキャッシングの恩恵がある可能性があります。
マイクロキャッシングが出現するのはこうしたケースです。マイクロキャッシングという言葉は、正にご想像のとおりの事を意味します。すなわち、短い時間間隔でコンテンツをキャッシングします。結局のところ、その発生から数秒しか経っていないなら古いデータでも構わないかも知れません。たとえば配送車のGPS座標は、3秒前の位置を表すのであれば依然として有用です!
1秒間に複数の要求に応えている場合、マイクロキャッシングは特に役に立ちます。たとえば、3秒のキャッシング許容差がある場合、処理するべきAPI要求の数に関係なく、バックエンドは1分間に20回の計算を行うだけで済みます。1秒間に10個の要求を処理している時、これがどれだけの影響を与え得るかを図4は示しています。
▲図4:バックエンド負荷へのマイクロキャッシングの効果(10要求/秒)
もちろん、もっと高い負荷がウェブサーバーに掛れば、その優位性はさらに高まります。この利点を理解するために、Express.jsと同時に100個の接続のあるベンチマークを使ってちょっとしたDb2 APIを作成しました。3秒間のマイクロキャッシングを使い、約5倍のワークロードを処理することができました(図5)。
▲図5:Db2 APIとマイクロキャッシングを使ったベンチマーク
カテゴリ4:リアルタイム情報
幾つかのケースでは、データは出来る限り生のものである必要があります。当然ながら、この場合キャッシングは役に立ちません。大規模なリアルタイム要求を処理する必要があるなら、仕事を複数のジョブまたは複数のシステムに分散させる必要があります。問題ありません。Nginxはロードバランシングが大の得意です!
ロードバランシングの概念は単純です。幾つかのバックエンドサーバー(Python、PHP、Javaなど)が要求を処理しているかも知れませんが、クライアントは仕事を結果的に分散させる中央のNginxサーバーに接続するだけです。それは、潜在的なパフォーマンスの利点に加え、弾力性の高さも加えます。もしバックエンドサーバーの1つが壊れても、ウェブサイトまたはAPIは機能し続けられます。図6をご覧ください。
▲図6:Nginxは複数のPythonサーバーにロードバランスさせることが可能
当然ながら、私はこの利点についても幾つかの面白い測定を行いました!この場合(図7をご覧ください)私はPython Waitress Db2プログラムを単一インスタンスで実行している場合と、(サービスコマンダーの“クラスターモデル”経由で)4人の作業者にロードバランスした場合の測定を行いました。
▲図7:ロードバランシングによるPythonアプリのパフォーマンス向上
予見できる拡張性と耐久性という利点があるので、ロードバランシングはコンテンツを供給するためにもっとハードウェア資源を活用する常識的なステップです。
Apacheはどうなのか?
ご存知のように、Apache HTTPサーバーは何年にも亘りずっとIBM iで利用可能でした。事実、今日私が説明したパフォーマンス向上テクニックはApacheにも使えます。さらに、ほとんどの場合Nginxと肩を並べるパフォーマンスだろうと私は予期しています。
ならば、Nginxを使いたい理由は何でしょうか?まず、ApacheとNginxの主要な違いを理解することが重要です。これらはHTTPサーバーの異なる実装であり、それ故当然それ自身の差異があります。インターネット上には数多くの意見が見られます。IBM iに関しては注意するべき幾つかの追加の差異があります。つまり、以下に示すような事柄です:
- NginxはPASE RPMとして利用可能。ApacheはIBM HTTP server for i (5770-DG1)製品の一部として提供される
- セキュアな接続の処理に関して、Apache HTTPサーバーはデジタル認証マネージャー(DCM)を統合している。Nginxは業界標準の構成とOpenSSLを使用する
- Nginxは完全にPASE内で実行される。Apacheの一部はILE環境で実行する
- Nginxはchrootコンテナ内部で実行できる。Apacheはそれができない
ところで、あなたはどちらを選びますか?往々にして、答えは結局のところ利用可能なスキルまたは個人的な好みのようなものになります。個人的には私はNginxのファンです。なぜなら、構成や管理が容易だからですが、当然ながら別の人はそれと逆の主張をする可能性があります。もし本番用のアプリケーションを構築中ならば、決める前に両方を試してみることをお勧めします。
しかし、私は次の1つの強い主張を行うつもりです:アプリケーションの前にはHTTPサーバーを置いて実行すること。HTTPサーバーはあなたの人生をとても余裕あるものにすることができ、あなたのウェブサイトまたはAPIをより早く、よりセキュアにすることができます。信じられませんか?あなたの好きなウェブフレームワーク用の文書を読んでください。たとえば、Express.jsまたはGunicorn文書のように、それはフロントエンドHTTPサーバーの必要性を叫んでいる可能性が高いです。
Nginxに関する結論
お分かりの様に、Nginxはオープンソースエコシステムへのとても有用な追加物です。もし始めてみようと興味を持ったなら、IBM iオープンソースリソースページで文書化された幾つかのコミュニティポータルと同様に、私達のオープンソース文書サイトにIBM i上のNginxに関する幾つかの基本情報あります。間違いなくあなたのウェブワークロードは超速になれます。
Nginx(エンジンエックス)は、ウェブサーバーとしてApacheに並ぶ人気を誇っていますが、IBM iユーザーにはまだよく知られていないようです。今回は、Nginxを使ってウェブアプリケーションを高速化する手法を通して、その魅力をお伝えします。(編集部)