2.8.6 ワークロード管理へのクラスタの使用
複数の同名のクラスタキューをクラスタ内に設定することによって,システムの可用性を向上させ,メッセージの処理を負荷分散できます。ここでは,ワークロード管理を取り上げ,このようにクラスタを使用する意味を説明します。
(1) 複数キューマネジャにある同名クラスタキュー
複数のキューマネジャが,それぞれ同じ名前のキューを保持するクラスタを構築できます。これによって,キューマネジャが相互にクローンであるようにクラスタを構成できます。つまり,キューマネジャは,同じアプリケーションを実行でき,同じ名前のキューを持つということです。
このようにクラスタを使用する場合の利点は,次に示すとおりです。
-
キューとアプリケーションの可用性の向上
-
メッセージのスループットの高速化
-
ネットワークへの負荷分散の均等化
特定のキューあてのメッセージは,その名前のキューを保持するキューマネジャのどれかによって処理されます。つまり,アプリケーションは,メッセージを送信する時にキューマネジャを明示的に指定する必要はありません。ワークロード管理アルゴリズムが,メッセージを処理するキューマネジャを決めます。
次の図は同名のキューQ3が複数あるクラスタを示しています。QM1のアプリケーションがQ3にメッセージを登録する場合,アプリケーションは,どのキューマネジャにあるQ3にメッセージが登録されるのか意識しません。しかし,QM2のアプリケーションまたはQM4のアプリケーションがメッセージをQ3に登録する場合には,ローカルキューが使用されることに注意してください。
MQOO_BIND_NOT_FIXEDオプションでクラスタ内のローカルキューがオープンされた場合,メッセージ転送中にキューが使用できなくなると,メッセージはほかのキューに転送されます。利用できるキューがない場合,メッセージはデッドレターキューに登録されます。クラスタ内のリモートキューや別名キューがメッセージの転送中に使用できなくなった場合,メッセージはデッドレターキューに登録されます。
クラスタ転送キューにメッセージがあるが,送信経路の通信障害などによってあて先キューマネジャに送信できない場合,システムはメッセージの送信経路を再設定します。しかし,メッセージを喪失する危険を冒したり,複製を作成したりすることによってメッセージの一貫性に影響を与えることはありません。キューマネジャが失敗し,メッセージが不確定なままになっている場合,そのメッセージに対して送信経路が再設定されることはありません。
メッセージの送信経路が再設定される状態については,「2.8.7 経路の選択」を参照してください。
- 注意事項
-
-
複数の同名キューがあるクラスタを設定する前に,自分のメッセージが相互依存性を持っていないこと,例えば,特定の順番で処理される必要があるとか,同じキューマネジャによって処理される必要があるとかいう条件について確認することが重要です。
-
同じ名前のキューについては,モデルキューの属性定義を同一にしておくことをお勧めします。そうしないと,異なるMQINQ命令から異なる結果を得ることになります。
-
(2) 負荷分散
クラスタ内に複数の同名のクラスタキューがある場合,ワークロード管理アルゴリズムを使用して,メッセージのあて先になる最良のキューマネジャが決定されます。ワークロード管理アルゴリズムは,可能な場合,あて先としてローカルキューマネジャを選択します。ローカルキューマネジャに該当する名前のキューがない場合にアルゴリズムは,チャネルに割り振った優先度を含むチャネルの状態,およびキューマネジャやキューの利用可能性を基にして,どのあて先が適当か決定します。アルゴリズムはラウンドロビン方式で,最終的に適切なキューマネジャを選択します。
ローカルキューマネジャとリモートキューマネジャの両方,または一方に同名のクラスタキューがあり,そのクラスタキューに対してメッセージの登録を実行した時に解決されるキューについて,次の表に示します。
クラスタキューの有無 |
メッセージ登録の有無 |
||
---|---|---|---|
ローカルキューマネジャ |
リモートキューマネジャ |
ローカルキューマネジャ |
リモートキューマネジャ |
○ |
× |
○ |
× |
○ |
○ |
○ |
× |
○※1 |
○ |
× |
○ |
○ |
○※1 |
○ |
× |
○※2 |
○ |
書き込みエラー※3 |
|
○※4 |
○ |
書き込みエラー※3 |
|
○※5 |
○ |
× |
○ |
○※5 |
○※5 |
書き込みエラー,またはMQOPEN命令時にエラー※3,※6 |
|
○※7 |
○ |
× |
○ |
○ |
○※7 |
○ |
× |
× |
○ |
× |
○ |
× |
○※2 |
書き込みエラー※3 |
|
× |
○※4 |
書き込みエラー※3 |
|
× |
○※5 |
MQOPEN命令時にエラー※3 |
(3) プログラミングの検討事項
アプリケーションは,MQOPEN命令を使用してクラスタキューをオープンし,MQPUT命令を使用してクラスタキューにメッセージを登録します。または,MQPUT1命令を使用して,まだオープンしていないクラスタキューに一つのメッセージを登録できます。
複数の同名のクラスタキューがないクラスタを設定する場合には,特にアプリケーションプログラミング上の検討事項はありません。しかし,クラスタのワークロード管理という利点を活用するには,アプリケーションの修正が必要なことがあります。同じ名前のキューが複数あるネットワークを構築する場合は,メッセージ類似性についてアプリケーションの見直しが必要です。
また,次に示す項目について注意してください。
-
メッセージを取り出したり,属性を設定する目的でアプリケーションからキューをオープンしたりする場合は,MQOPEN命令はローカルキューだけに有効です。
-
メッセージを登録する目的でアプリケーションからキューをオープンする場合は,MQOPEN命令はすべての利用できるクラスタキューから対象を選択します。ローカルキューが優先的に選択されます。そのためアプリケーションがクラスタの機能を十分に利用できないことがあります。
(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とクラスタ
クラスタに関係する命令は次に示すとおりです。
-
MQOPEN命令
-
MQPUT命令とMQPUT1命令
-
MQINQ命令
-
MQSET命令
各命令のクラスタに関連するオプションについて説明します。あわせて,マニュアル「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
-
DefPersistence
-
DefPriority
-
InhibitPut
-
QDesc
-
QName
-
QType
クラスタキューの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) ワークロード管理アルゴリズム
ワークロード管理アルゴリズムを次に示します。
-
MQOPEN命令でキューマネジャ名が指定されなかった場合,次のようになります。
-
登録禁止状態のキューを選択対象から除外します。
-
キューの属するクラスタがローカルキューマネジャの属するクラスタでないとき,キューを選択対象から除外します。
-
キューの経路となるリモートクラスタレシーバチャネルがキューと同じクラスタに属していないとき,そのチャネルを除外します。
-
-
MQOPEN命令でキューマネジャ名称が指定された場合,次のようになります。
-
登録禁止状態であるキューマネジャ別名を選択対象から除外します。
-
リモートクラスタレシーバチャネルの属するクラスタがローカルキューマネジャの属するクラスタでないとき,選択対象から除外します。
-
-
1.の結果ローカルキューが選択対象として残っているとき,または2.の結果ローカルキューマネジャ別名が選択対象として残っているとき,そのローカルキューマネジャ上のオブジェクトを選択します。
残っていないとき,4.以降の処理をします。
-
リモートキューマネジャ上のオブジェクトだけ残っている場合,RESUME状態のキューマネジャを,SUSPEND状態のキューマネジャより優先して選択します。
-
2つ以上のリモートキューマネジャ上のオブジェクトが残っている場合,次に示すクラスタセンダチャネルの状態の順序でチャネルを選択します。
-
「チャネル停止」または「チャネル動作中」
-
「チャネル確立リトライ中」
-
「チャネル使用不可」
-
-
同一状態である2つ以上のチャネルから選択します。
-
同一のリモートキューマネジャをあて先とする2つ以上のクラスタセンダチャネルが存在する場合,その中で最も高いNetworkPriority属性を持つチャネル以外のチャネルを除外します。
-
上記で2つ以上のリモートキューマネジャ上のオブジェクトが残っている場合,最後に使われた時刻がキューマネジャ単位で最も古いクラスタセンダチャネルを選択します。
-