シリーズ連載
止まらないWebシステム構築の基礎知識


清水徳雄
日本BEAシステムズ
プロフェッショナル・サービス
2001/8/23


Javaアプリケーション・サーバを使った大規模なWebシステム構築案件が増えていく中で、顧客に対し24時間365日の安定したサービスを提供すること、将来のスケーラビリティを保障することなどが重要になってきている。本連載では、Webシステムのコンサルティングや開発を手がけるコンサルタントやエンジニアに、止まらないWebシステム構築を考える上で必要となる基礎知識を解説する。第1回は、アプリケーション・サーバ側で行うクラスタリング機能について、WebLogic Serverの機能を例にあげながら、日本BEAシステムズの清水徳雄氏に紹介していただく。(編集局)


第1回 アプリケーション・サーバのクラスタリングを知る

 スケーラビリティや高可用性が要求されるシステムでは、プラットフォームのさまざまなレベルでクラスタリング技術が利用されています。このうち、アプリケーション・サーバにおけるクラスタリング技術の基本をWebLogic Serverを例に解説します。

 今回は、クラスタリングの概念を中心に、次回は具体的な構成例を中心に解説します。ここではWebLogic Serverにおけるクラスタリングを例に説明していますが、ほかのアプリケーション・サーバも共通の要素を多く含んでいるはずです。

クラスタの基本的な概念

 まず、クラスタとは何か、そしてクラスタがなぜスケーラビリティや可用性の向上に貢献するのか簡単におさらいしておきましょう。

 クラスタとは、簡単にいってしまえば等価なサービスを提供するサーバ群のことです。サービスを利用するクライアントからは、クラスタ全体で1つのサーバに見えることが重要で、かつクラスタ内のサーバは等価かつ透過でなければなりません。クラスタに所属するサーバをクラスタ・メンバーと呼びます。クラスタを構成するサーバ全体で次の2つの特性を提供します。

●スケーラビリティ
 クラスタとしての性能は、これを構成するサーバ群全体の性能の総和になります。クラスタへ新たなサーバを追加することにより、クラスタ全体の性能を向上させることが比較的簡単にできます。

●高可用性
 クラスタ内のあるサーバがダウンした際には、ほかのサーバがその処理を引き継ぐ(フェイルオーバー)ことで高可用性を実現します。これにより、クラスタ全体として、提供するサービスを中断することなく常に使用可能な状態に保つことができるわけです。

 クラスタリングを実現するうえでコアとなる機能に、リクエストの負荷分散およびルーティング、状態のレプリケーションがあります。

●リクエストの負荷分散
 クラスタ内のサーバはすべて等価なサービスを提供しています。結果がサーバ側の状態に依存しない処理はクラスタ内のどのサーバで処理してもよいので、そういったリクエストをクラスタ・メンバーに分散して振り分けることによりスケーラビリティを実現します。

図1 リクエストの負荷分散

●リクエストのルーティング
 一方、サーバ側でクライアントごとの状態を保持しなければならない種類のサービスもあります。こういったサービスに関しては、そのクライアントの状態を保持しているクラスタ・メンバーに対してリクエストを正しくルーティングする仕組みが必要になります。この種のサービスでは、最初のリクエストでは負荷分散させ、サーバ内にクライアントの状態を保持するようになったら、後続のリクエストでは最初のリクエストと同じ振り分け先にリクエストをルーティングさせます。

●状態のレプリケーション
 クライアントの状態を保持しているクラスタ・メンバーがダウンした際にも、ほかのクラスタ・メンバーで後続のリクエストを正しく処理できなければなりません。そのためには、クライアントの状態を別のサーバにコピー、維持しておく必要があります。このようにクライアントの状態をコピーすることをレプリケーション、コピーした状態をレプリカと呼びます。レプリケーションとルーティングは一体で機能し、元のメンバーがダウンした際には、そのレプリカを保持しているメンバーに以降のリクエストがルーティングされることを保証しなければなりません。

●プライマリとバックアップ
 元のクライアント状態を保持するクラスタ・メンバーをプライマリと呼びます。一方、レプリカを保持するクラスタ・メンバーをバックアップと呼びます。バックアップは、ベンダーによってはセカンダリと呼んでいる場合がありますが、今回はバックアップで統一して説明します。

 一般に、プライマリがダウンするとバックアップが新たなプライマリに昇格し、別のクラスタ・メンバーが (あれば) 新たなバックアップになります。また、ある時点であるクライアントにとってのプライマリは、別のクライアントのバックアップにもなっている点に注意してください。WebLogic Serverの場合、固定的にこのサーバがプライマリ、このサーバがバックアップといったような色分けはありません。

図2 状態のレプリケーションとリクエストのルーティング

クラスタ対応機能

 J2EE準拠のアプリケーション・サーバであるWebLogic Serverでは以下のサービスについてクラスタリング機能を提供します。

スケーラビリティ 高可用性
Web Container層
(JSP/Servlet)
HTTPリクエストの負荷分散 HttpSessionオブジェクトのレプリケーションとHTTPリクエストのルーティング
EJB Container層
(EJB)
EJBの生成とメソッドの呼び出しの負荷分散 Stateful Session Beanのレプリケーション/メソッド呼び出しのルーティング
JNDI クラスタ・ワイドなJNDIツリー

(これらの他に、JDBCやJMS といったサービスもクラスタに対応していますが、今回は説明を割愛しています)

Web Container層におけるクラスタリング

 Web Containerへのリクエスト(HTTP リクエスト)の負荷分散とルーティングは、WebLogicの場合は、WebLogicが提供するProxy Plug-inの機能として実装されています。Web Container層におけるクラスタリングでは、Proxyをクラスタの前に配置してクラスタへのリクエストを負荷分散/ルーティングさせます。

 負荷分散とルーティングのPlug-inは、以下のWebサーバに対応しています。

  • Apache
  • NES/iPlanet
  • Microsoft IIS

 また、Proxy としてWebLogic Serverを使用することもできますが、この場合はプラグインではなく組み込みサーブレット(HttpClusterServlet) を使用することになります。

 参考までに、WebLogicがサポートしているWebサーバとそのバージョン情報はプラットフォーム別に下記の URL に記載されています。

http://e-docs.bea.com/wls/platforms/index.html
http://www.beasys.co.jp/weblogic/docs/platforms/index.html

図3 ProxyによるHTTPリクエストの負荷分散

 WebLogic Server 6.0以降では、Proxy Webサーバの代わりにスティッキング機能を備えたスイッチやロード・バランサーなどのハードウェアを前に立ててクラスタリングできるようになりました。これをインクラスタ・ルーティング (In-cluster Routing) と呼びます。Proxyを使用した場合と、インクラスタ・ルーティングとでは若干振る舞いが異なりますが、提供する機能に違いはありません。ここでは、Proxyを使用する場合について説明します。

●HTTP リクエストの負荷分散
 クライアントのセッション情報(HttpSession オブジェクト)を維持する必要がないリクエストは、どのクラスタ・メンバーで処理しても構いません。Proxyがリクエストの情報を解析し、セッションと関連付いていない場合はラウンドロビンでクラスタ・メンバーにリクエストを分散させます。

 セッションがない場合は、同じクライアントからのリクエストであっても別々のサーバへ分散させます。

 また、Proxy がサーバにリクエストを転送してから応答が返るまでの間にそのサーバがダウンしてしまったような場合には、自動的にproxyからほかのサーバにリクエストを再発行しフェイルオーバーさせることもできます。

●HTTP リクエストのルーティング
 リクエストがセッションと関連付いている場合は、セッション情報を保持しているプライマリへルーティングします。プライマリがダウンしている場合は、バックアップへルーティングします。また、リクエストがバックアップへ転送されると、バックアップが新たなプライマリに昇格します。

●HttpSession オブジェクトのレプリケーション
 一方、セッションのレプリケーションはWebLogicの Web Containerの役割です。セッションのレプリケーションはサーバ単位(WebLogic Server 5.1)またはWeb Application単位(6.0 以降)で設定することができます。この設定は、サーバ自体がクラスタに参加していることが前提条件になります。

EJB Container層におけるクラスタリング

 EJB Containerへのリクエストの負荷分散とルーティングは、コンテナとコンテナ・ツールがEJBデプロイ時に生成するクライアント・スタブの機能です。EJB の種類によって内部ステートの扱いに差がありますので、クラスタ対応の範囲もEJBの種類により異なります。

●EJB呼び出しの負荷分散とルーティング

  • Stateless Session Bean
    メソッド呼び出しのたびに負荷分散されます。同じクライアントからの同じメソッドの呼び出しであっても、異なるサーバに分散されます。

  • Stateful Session Bean
    生成(home.create メソッド呼び出し)時に負荷分散され、生成後はプライマリにルーティングされます。6.0 以降ではプライマリがダウンした場合、自動的にバックアップへルーティングしフェイルオーバーします。

  • Entity Bean
    生成または検索 (home.create または home.find メソッド呼び出し) 時に負荷分散され、以降はそのサーバにルーティングされます。Homeインターフェイスのそのほかのメソッド(create、find、remove以外のいわゆるHomeメソッド)も負荷分散されます。

●EJB内部ステートのレプリケーション

  • Stateless Session Bean
    内部ステートを持たないのでレプリケーションの対象外です。

  • Stateful Session Bean
    6.0以降では HttpSessionオブジェクトと同様にプライマリとバックアップでレプリケーションします。

  • Entity Bean
    内部ステートはDBから取得できますので、レプリケーションは行いません。また、生成先のサーバがダウンした場合は、自動的なフェイルオーバーも行われません。従って、生成先のサーバがダウンした場合、クライアントは生成または検索からやり直す必要があります (この時点で再度負荷分散されます)。これはクラスタ環境で Entity Bean を使用する際の非常に重要なポイントです。

 なお、ローカル・クライアント(EJBコンテナと同じJVM上に存在するクライアント)からのEJB呼び出しは、クラスタリング環境であってもローカルのEJBへ優先的にルーティングされます。

クラスタ・ワイドなJNDIツリー

 J2EE では、さまざまなファクトリ・クラスを JNDIツリーから取得して、必要なサービスを提供するためのオブジェクトを生成するプログラミング・モデルが用いられています。例えばEJBの場合は、まず Home オブジェクトのクライアント・スタブをJNDIから取得し、これを使ってEJBを生成します。J2EE では、JNDI は各種サービスの窓口として重要な役割を担っています。

 WebLogic Serverではクラスタ・メンバーのJNDIツリーもレプリケートします。このため、クライアントからはクラスタ全体で1つのJNDIツリーが存在するように見えます。クラスタ対応のサービスであればファクトリからオブジェクトを取得する際に(例えば)負荷分散され、クラスタ非対応のサービスであれば所定のサーバにルーティングされます。従って、クライアントはどのクラスタ・メンバーのJNDIをlookupするのか意識する必要がありません。これは、クラスタ・メンバーの等価性と透過性を提供するうえで重要な機能です。

そして全体像

 これまでの話を総合すると、Web Container、EJB Container、JNDIツリーに着目したクラスタの全体像は次のようになります。なお、この図はあくまで論理的な構成を説明するもので、通常行う物理的な構成とは異なる点に注意してください(たとえばWeb ContainerとEJB Containerとの物理的な分離は通常行いません)。

図4 クラスタの全体像 (クリックすると拡大します)

 次回は、現実のシステムでクラスタをどう構成するかを、ハードウェアとネットワークを含めた具体例を示しながら説明する予定です。

連載記事一覧

 



Java Agile フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Java Agile 記事ランキング

本日 月間