2.8.6 ワークロード管理へのクラスタの使用

複数の同名のクラスタキューをクラスタ内に設定することによって,システムの可用性を向上させ,メッセージの処理を負荷分散できます。ここでは,ワークロード管理を取り上げ,このようにクラスタを使用する意味を説明します。

<この項の構成>
(1) 複数キューマネジャにある同名クラスタキュー
(2) 負荷分散
(3) プログラミングの検討事項
(4) MQIとクラスタ
(5) クラスタ機能のリターンコード

(1) 複数キューマネジャにある同名クラスタキュー

複数のキューマネジャが,それぞれ同じ名前のキューを保持するクラスタを構築できます。これによって,キューマネジャが相互にクローンであるようにクラスタを構成できます。つまり,キューマネジャは,同じアプリケーションを実行でき,同じ名前のキューを持つということです。

このようにクラスタを使用する場合の利点は,次に示すとおりです。

特定のキューあてのメッセージは,その名前のキューを保持するキューマネジャのどれかによって処理されます。つまり,アプリケーションは,メッセージを送信する時にキューマネジャを明示的に指定する必要はありません。ワークロード管理アルゴリズムが,メッセージを処理するキューマネジャを決めます。

次の図は同名のキューQ3が複数あるクラスタを示しています。QM1のアプリケーションがQ3にメッセージを登録する場合,アプリケーションは,どのキューマネジャにあるQ3にメッセージが登録されるのか意識しません。しかし,QM2のアプリケーションまたはQM4のアプリケーションがメッセージをQ3に登録する場合には,ローカルキューが使用されることに注意してください。

MQOO_BIND_NOT_FIXEDオプションでクラスタ内のローカルキューがオープンされた場合,メッセージ転送中にキューが使用できなくなると,メッセージはほかのキューに転送されます。利用できるキューがない場合,メッセージはデッドレターキューに登録されます。クラスタ内のリモートキューや別名キューがメッセージの転送中に使用できなくなった場合,メッセージはデッドレターキューに登録されます。

図2-49 複数の同名キューがあるクラスタ

[図データ]

クラスタ転送キューにメッセージがあるが,送信経路の通信障害などによってあて先キューマネジャに送信できない場合,システムはメッセージの送信経路を再設定します。しかし,メッセージを喪失する危険を冒したり,複製を作成したりすることによってメッセージの一貫性に影響を与えることはありません。キューマネジャが失敗し,メッセージが不確定なままになっている場合,そのメッセージに対して送信経路が再設定されることはありません。

メッセージの送信経路が再設定される状態については,「2.8.7 経路の選択」を参照してください。

注意
  • 複数の同名キューがあるクラスタを設定する前に,自分のメッセージが相互依存性を持っていないこと,例えば,特定の順番で処理される必要があるとか,同じキューマネジャによって処理される必要があるとかいう条件について確認することが重要です。
  • 同じ名前のキューについては,モデルキューの属性定義を同一にしておくことをお勧めします。そうしないと,異なるMQINQ命令から異なる結果を得ることになります。

(2) 負荷分散

クラスタ内に複数の同名のクラスタキューがある場合,ワークロード管理アルゴリズムを使用して,メッセージのあて先になる最良のキューマネジャが決定されます。ワークロード管理アルゴリズムは,可能な場合,あて先としてローカルキューマネジャを選択します。ローカルキューマネジャに該当する名前のキューがない場合にアルゴリズムは,チャネルに割り振った優先度を含むチャネルの状態,およびキューマネジャやキューの利用可能性を基にして,どのあて先が適当か決定します。アルゴリズムはラウンドロビン方式で,最終的に適切なキューマネジャを選択します。

ローカルキューマネジャとリモートキューマネジャの両方,または一方に同名のクラスタキューがあり,そのクラスタキューに対してメッセージの登録を実行した時に解決されるキューについて,次の表に示します。

表2-15 メッセージ登録時に解決されるキュー

クラスタキューの有無メッセージ登録の有無
ローカルキューマネジャリモートキューマネジャローカルキューマネジャリモートキューマネジャ
××
×
※1×
※1×
※2書き込みエラー※3
※4書き込みエラー※3
※5×
※5※5書き込みエラー,またはMQOPEN命令時にエラー※3,※6
※7×
※7×
××
×※2書き込みエラー※3
×※4書き込みエラー※3
×※5MQOPEN命令時にエラー※3
(凡例)
○:該当します。
×:該当しません。
注※1
MQOPEN命令発行後に作成されたキューです。
注※2
MQOPEN命令発行後に書き込み禁止になったキューです。
注※3
ローカルキューマネジャでMQIがエラーになります。リモートキューマネジャにメッセージは送信されません。
注※4
MQOPEN命令発行後に障害になったキューです。
注※5
MQOPEN命令発行前に書き込み禁止になったキューです。
注※6
MQOO_BIND_ON_OPEN指定時は書き込みエラーです。
MQOO_BIND_NOT_FIXED指定時はMQOPEN命令でエラーです。
注※7
MQOPEN命令発行前に書き込み禁止,MQOPEN命令発行後に書き込み可能になったキューです。

(3) プログラミングの検討事項

アプリケーションは,MQOPEN命令を使用してクラスタキューをオープンし,MQPUT命令を使用してクラスタキューにメッセージを登録します。または,MQPUT1命令を使用して,まだオープンしていないクラスタキューに一つのメッセージを登録できます。

複数の同名のクラスタキューがないクラスタを設定する場合には,特にアプリケーションプログラミング上の検討事項はありません。しかし,クラスタのワークロード管理という利点を活用するには,アプリケーションの修正が必要なことがあります。同じ名前のキューが複数あるネットワークを構築する場合は,メッセージ類似性についてアプリケーションの見直しが必要です。

また,次に示す項目について注意してください。

(a) メッセージ類似性についてのアプリケーションの見直し

同じキューの複数の定義を持ったクラスタを使用する前に,メッセージ類似性を持っていないか,つまり関連メッセージの交換要求がないか,自分のアプリケーションを調査する必要があります。クラスタでは,メッセージは,該当するキューを保持しているキューマネジャに転送されます。したがって,メッセージ類似性を持っているアプリケーションのロジックは無効になることがあります。

例えば,質疑応答の形での連続するメッセージフローに依存している二つのアプリケーションがあるとします。すべての質問を同じキューマネジャに送信し,すべての回答をほかのキューマネジャに送り返すことが重要です。また,ワークロード管理機能が,該当するキューを保持しているだけのキューマネジャにメッセージを送信しないことも重要です。

同様に,順番どおり取り出されるべきメッセージのバッチを送信するファイル転送アプリケーションやデータベース複製アプリケーションのように,メッセージが順番に処理されなければいけないアプリケーションがある場合もあります。

注意
セグメント化されたメッセージを使用しても,類似性の問題が発生することがあります。
(b) メッセージ類似性の処置

メッセージ類似性を持っているアプリケーションがある場合,できるだけクラスタを使用する前に,その類似性を取り除く必要があります。

メッセージ類似性を取り除くと,アプリケーションの可用性が改善されます。メッセージ類似性を持っているアプリケーションがメッセージのバッチをキューマネジャに送信し,バッチの一部を受け取ったあとでそのキューマネジャが失敗した場合,送信元のキューマネジャは,さらにメッセージを送信する前に送信先のキューマネジャの回復を待たなければいけません。

また,メッセージ類似性を取り除くと,アプリケーションのスケーラビリティが改善されます。類似性を持っているメッセージのバッチによって,以後のメッセージを待っている間に,あて先のキューマネジャのリソースがロックすることがあります。このリソースが長期間ロックしたままであると,ほかのアプリケーションの業務を妨害することがあります。

さらに,メッセージ類似性によって,クラスタのワークロード管理機能は最良のキューマネジャを選択できなくなります。

類似性を取り除くには,次について検討します。

メッセージ類似性を取り除くために自分のアプリケーションを修正するのが適当でない場合,ほかにも多数の解決策があります。例えば,次に示すことを実行できます。

MQOPEN命令で特定のあて先を指定する
各MQOPEN命令でリモートキューの名前とキューマネジャの名前を指定するのも,一つの解決策です。その場合,オブジェクトハンドルを使用してすべてのメッセージが同じキューマネジャに行くようにします。それが,ローカルキューマネジャのこともあります。
この方法には,次に示すような不都合があります。
  • ワークロード管理が実行されません。これによって,ワークロード管理の利点を活用できなくなります。
  • ターゲットキューマネジャがリモートであり,そこへの複数のチャネルがある場合,メッセージは別のルートを通ることがあり,メッセージの連続性が保たれません。
  • 自分のキューマネジャがあて先キューマネジャと同じ名前を持った転送キューの定義を持っている場合,メッセージはクラスタ転送キューではなくその転送キューに登録されます。
ReplyToQMgrフィールドにキューマネジャ名を返す
最初の解決策の変形として,最初のメッセージをバッチで受信するキューマネジャが応答でその名前を返すようにするという方法もあります。メッセージ記述子のReplyToQMgrフィールドを使用して,これを実現します。送信側のキューマネジャは,このキューマネジャ名を取り出し,それを以後のすべてのメッセージで指定します。
前の方法と比べると,この方法は最初のメッセージを転送するために負荷分散が実行されるという利点があります。
しかし,この方法では,最初のキューマネジャは最初のメッセージに対する応答を待たなければいけなくて,以後のメッセージを送信する前にReplyToQMgrの情報を見つけて使用しなければいけないというデメリットがあります。前の方法と同様に,キューマネジャへのルートが複数ある場合,メッセージの連続性が保たれないことがあります。
MQOPEN命令でMQOO_BIND_ON_OPENオプションを使用する
自分のすべてのメッセージを同じあて先に登録するというのも解決策として考えられます。そのためには,MQOPEN命令でMQOO_BIND_ON_OPENを使用します。キューをオープンし,MQOO_BIND_ON_OPENを指定することによって,すべてのメッセージをこの同じキューに登録するようにします。MQOO_BIND_ON_OPENは,すべてのメッセージを同じキューマネジャに,または同じルートにバインドします。したがって,例えば,同じあて先に複数のルートがある場合,キューがオープンされるときにどれかのルートが選択されると,取得したオブジェクトハンドルを使用して同じキューに登録されたすべてのメッセージは同じルートを選択します。
MQOO_BIND_ON_OPENを指定することによって,すべてのメッセージが同じあて先に転送されるようにします。したがって,メッセージ類似性を持っているアプリケーションが壊されることはありません。あて先が利用できない場合,メッセージは,あて先が再度利用可能になるまで転送キューに残ります。
キューをオープンする時にキューマネジャ名がオブジェクト記述子で指定されている場合にも,MQOO_BIND_ON_OPENが適用されます。名前付きキューマネジャへのルートが複数存在することがあります(例えば,複数のネットワークパスがある,またはほかのキューマネジャが別名を定義している)。MQOO_BIND_ON_OPENを指定する場合,キューがオープンされる時にルートが選択されます。
注意
この方法をお勧めします。しかし,キューマネジャがクラスタキューの別名を通知しメッセージを中継する環境では使用できません。また,アプリケーションがメッセージグループごとに,同じキューマネジャの異なるキューを使用する場合にも使用できません。
MQOPEN命令でMQOO_BIND_ON_OPENを指定する代わりに,キューの定義を変更することによっても同じ効果を得られます。mqaqueatl定義コマンドで-wオプションにfixedを指定してMQOPEN命令でのMQOO_BINDオプションがMQOO_BIND_AS_Q_DEFにデフォルト設定されるようにします。

(4) MQIとクラスタ

クラスタに関係する命令は次に示すとおりです。

各命令のクラスタに関連するオプションについて説明します。あわせて,マニュアル「TP1/Message Queue プログラム作成の手引」を参照してください。

ここでは,一般的なプログラミングインタフェース情報を含んでいます。

(a) MQOPEN命令

MQOPEN命令のオプションであるMQOO_BIND_ON_OPENオプションによって,クラスタ内に複数の同名のキューがある場合に,ターゲットキューマネジャを固定するよう指定できます。つまり,MQOPEN命令から返されるオブジェクトハンドルを指定するキューに登録されるすべてのメッセージは,同じキューマネジャに向けられることになります。

類似性を持ったメッセージがある場合に,このオプションを使用できます。例えば,メッセージのバッチをすべて同じキューマネジャによって処理する必要がある場合,キューをオープンする時にMQOO_BIND_ON_OPENを指定します。これによって,キューマネジャを固定し,そのキューに登録されたすべてのメッセージがそのルートを採用するようになります。

必ずしもすべてのメッセージを同じあて先に登録したくない場合,MQOPEN命令でMQOO_BIND_NOT_FIXEDを指定します。これによって,MQPUT命令発行時にあて先が選択されます。つまり,あて先はメッセージごとに選択されます。

注意
MQOO_BIND_NOT_FIXEDとMQMF_SEGMENTATION_ALLOWEDを同時に指定しないでください。指定した場合,メッセージのセグメントが異なるキューマネジャに転送されることがあります。

MQOO_BIND_ON_OPENもMQOO_BIND_NOT_FIXEDも指定しない場合,デフォルトオプションはMQOO_BIND_AS_Q_DEFです。MQOO_BIND_AS_Q_DEFを使用すると,キューハンドルに使用するバインドは,DefBind属性から取得されます。

MQOPEN命令のオブジェクト記述子で名前を指定することによっても,あて先キューマネジャを選択できます。このようにすれば,ローカルキューマネジャを含め,どのようなキューマネジャでも選択できます。

MQOPEN命令でMQOO_BROWSE,MQOO_INPUT_*,またはMQOO_SETの一つ以上を指定した場合,オープンが成功するためには,ローカルのクラスタキューである必要があります。MQOPEN命令でMQOO_OUTPUT,MQOO_BIND_*,またはMQOO_INQUIREの一つ以上を指定し,MQOO_BROWSE,MQOO_INPUT_*,またはMQOO_SET(常にローカルのクラスタキューが選択されるようにする)のどれも指定しなかった場合,オープンされるクラスタキューは次に示すどちらかです。

●解決されたキューマネジャ名

キューマネジャ名がMQOPEN命令発行時に解決される場合,その解決された名前がアプリケーションに返されます。

(b) MQPUT命令とMQPUT1命令

MQOO_BIND_NOT_FIXEDがMQOPEN命令で指定されている場合,以後のMQPUT命令は,ワークロード管理機能を起動して,メッセージを送信するキューマネジャを決定します。したがって,そこで指定されるあて先とルートはメッセージごとに選択されます。ネットワークの条件が変わった場合,メッセージが登録されたあとに,あて先とルートが変わることがあります。MQPUT1命令は,常にMQOO_BIND_NOT_FIXEDが有効であるかのように動作します。つまり,常にワークロード管理機能を起動します。

ワークロード管理機能がキューマネジャを選択した場合に,ローカルキューマネジャの登録オペレーションは完了します。ターゲットキューマネジャがローカルキューマネジャと同じクラスタのメンバである場合,ローカルキューマネジャは,メッセージをクラスタ転送キューに登録します。ターゲットキューマネジャがクラスタの外にあり,ローカルキューマネジャがターゲットキューマネジャと同じ名前の転送キューを持っている場合,メッセージはその転送キューに登録されます。

MQOO_BIND_ON_OPENがMQOPEN命令で指定されている場合,あて先とルートはすでに選択されているので,MQPUT命令は,ワークロード管理機能を起動する必要がありません。

(c) MQINQ命令

キューを照会する前に,MQOPEN命令を使用して,MQOO_INQUIREを指定してキューをオープンする必要があります。

複数の同名のクラスタキューがあるクラスタを持っている場合,照会できる属性はクラスタキューがローカルにあるかどうか,キューがどのようにオープンされたのかによって異なります。

MQOPEN命令でMQOO_INQUIREを指定しているほかに,MQOO_BROWSE,MQOO_INPUT_*,またはMQOO_SETオプションのどれかも指定している場合に,オープンが成功するには,ローカルのクラスタキューが必要です。この場合,ローカルキューに有効なすべての属性を照会できます。

MQOPEN命令で,MQOO_INQUIREだけ,またはMQOO_INQUIREとMQOO_OUTPUTを指定している場合(しかし,常にローカルのクラスタキューが選択されるようにするMQOO_BROWSE,MQOO_INPUT_*,またはMQOO_SETのどれも指定していない),オープンされるクラスタキューは,次に示すどちらかです。

オープンされたキューがローカルキューでない場合,次に示す属性だけを照会できます。この場合,QType属性はMQQT_CLUSTERの値を持っています。

クラスタキューのDefBind属性を照会するには,MQIA_DEF_BINDセレクタのMQINQ命令を使用します。返される値は,MQBND_BIND_ON_OPENまたはMQBND_BIND_NOT_FIXEDのどちらかです。ローカルキューのClusterName属性を照会するには,MQCA_CLUSTER_NAMEでMQINQ命令を使用します。

注意
固定バインドにしないで(つまりMQOPEN命令でMQOO_BIND_NOT_FIXEDを指定する,またはキューのDefBind属性がMQBND_BIND_NOT_FIXEDの場合にMQOO_BIND_AS_Q_DEFを指定する),クラスタキューをオープンした場合,以後のMQINQ命令は,他キューマネジャのクラスタキューを照会することがあります。
(d) MQSET命令

属性を設定するためにクラスタキューをオープンする場合(MQOO_SETオプションを指定),オープンが成功するためにはローカルのクラスタキューが必要です。したがって,MQSET命令を使用してはクラスタのどこかほかにあるキューの属性を設定できません。しかし,クラスタ属性で定義されている別名キューまたはリモートキューをオープンする場合には,ターゲットキューまたはリモートキューが解決されてクラスタキューになっても,MQSET命令を使用して別名キューまたはリモートキューの属性を設定できます。

(5) クラスタ機能のリターンコード

クラスタを使用する場合に固有のリターンコードがあります。

MQRC_CLUSTER_PUT_INHIBITED(2268,X'000008DC')
MQOO_OUTPUTおよびMQOO_BIND_ON_OPENオプションの有効なMQOPEN命令がクラスタキューに発行されたが,クラスタ内のキューが現在すべて登録禁止状態(InhibitPut属性がMQQA_PUT_INHIBITED)である場合に発生します。メッセージを受信するために利用できるキューがないために,MQOPEN命令は失敗します。
この理由コードは次に示す条件を満たす場合だけ発生します。
  • ローカルキューがありません(ローカルキューがある場合,ローカルキューが登録禁止であってもMQOPEN命令は成功します)。
MQOO_BIND_NOT_FIXEDオプションがMQOPEN命令に指定される場合,クラスタ内のすべてのキューが登録禁止であっても成功することがあります。しかし,以降のMQPUT命令は,発行時にすべてのキューが登録禁止のままであると失敗します。
MQRC_CLUSTER_RESOLUTION_ERROR(2189,X'0000088D')
MQOPEN命令,MQPUT命令,またはMQPUT1命令が,クラスタキューへのオープンまたはメッセージ登録のために発行されたが,フルリポジトリキューマネジャからの応答がないためにキュー定義を正しく解決できない場合に発生します。
MQRC_CLUSTER_RESOURCE_ERROR(2269,X'000008DD')
MQOPEN命令,MQPUT命令,またはMQPUT1命令が,クラスタキューに発行されたが,クラスタに必要なリソースを使用するのに失敗した場合に発生します。
MQRC_NO_DESTINATIONS_AVAILABLE(2270,X'000008DE')
MQPUT命令,またはMQPUT1命令が,クラスタキューにメッセージを登録するために発行されたが,その時点でクラスタ内にキューがなくなっていると発生します。命令は失敗し,メッセージは送信されません。
この状況はキューをオープンするMQOPEN命令にMQOO_BIND_NOT_FIXEDオプションが指定される場合,またはメッセージを登録するのにMQPUT1命令が使用される場合に発生します。