ODPはブロックリストメカニズムを用いて、OBServerノードのピーク時を避けたマージ、アップグレード、リーダー切り替え、ダウン、起動、停止などのプロセスにおけるアクセス制御を適応的に処理します。
背景
ODPには、ステータスブロックリスト、ディテクションブロックリスト、アクティブであるが利用不可なブロックリストの3種類があり、パラメータ設定によってブロックリストを管理できます。
ブロックリストは主に以下のシナリオでアクセス制御を実現するために使用されます:
ピークカットマージ時にマージ中のZoneにトラフィックがない場合。
クラスタアップグレード時に、アップグレード中のOBServerノードまたはZoneにアクセスできない場合。
OBServerノードがダウンした後、そのOBServerノードに再びアクセスしないようにする場合。
パーティション移行後、移行前のOBServerノードにアクセスしないようにする場合。
アクセス対象のOBServerノードにテナントリソースが存在しない場合のリトライ。
OBServerノードがアクティブであるが利用不可(メモリ上限超過、タイムアウト、OBServerノードの初期化および終了)の場合のリトライ。
ステータスブロックリスト
ステータスブロックリストは、OBServerノードのステータス変更に依存しています。歴史的な理由から、ステータスブロックリストに関連するステータスにはDETECT_ALIVEとDETECT_deadの2つのステータスが含まれていませんが、残りのステータス変更はすべてOBServerノードのビューにアクセスすることで取得できます。
定期タスクによってOBServerノードの最新ステータスを取得した後、ODPはOBServerノードのステータスに応じて以下の操作を実行します。
ACTIVE:OBServerノードをステータスブロックリストから削除し、OBServerノードを「洗浄」します。INACTIVE/REPLAY:OBServerノードをステータスブロックリストに追加します。DELETED/DELETINGステータス:メモリ内のOBServerノードのマシンリストを更新し、そのノードへのSQL転送を停止します。UPGRADEステータス:ステータスブロックリストには追加されませんが、そのノードへのSQL転送も行われません。効果はブロックリストと同様です。
ディテクションブロックリスト
ステータスブロックリストはOceanBaseの総合管理サービスノード(Root Service)から情報を取得しますが、この情報はODPとOBServerノード間の状況を必ずしも反映しているわけではありません。下図のように、ODPはRSからOBServer1ノードのステータスがACTIVEであると取得しますが、ODPとOBServer1ノード間のネットワークは接続されていません。

そのため、ODPは既存のステータスブロックリストに加えてディテクションブロックリストを実装し、OBServerノードにディテクションSQLを送信してノードのステータスを確認します。ODPはOceanBaseデータベースのsysテナントにディテクションSQL select 'detect server alive' from dual を送信し、5秒のタイムアウト時間を設定します。タイムアウト時間内に結果が返されない場合、ディテクション失敗回数が1回増加し、連続失敗回数が3回を超えた場合、ディテクション失敗とみなしてOBServerノードのステータスをDETECT_DEADに設定します。結果が返された場合、ディテクション失敗回数をリセットし、OBServerノードのステータスをDETECT_ALIVEに設定します。ディテクションステータスが変更されると、ODPの動作は以下のようにトリガーされます。
DETECT_ALIVEステータス:OBServerノードをディテクションブロックリストから「洗浄」します。DETECT_DEADステータス:OBServerノードをディテクションブロックリストに追加し、そのOBServerノードとのすべての接続を閉じます。
説明
OBServerノードをディテクションブロックリストに追加した後、そのOBServerノードとの接続を切断しない場合、接続は占有されたままとなり、新しいSQLを送信できません。そのため、パフォーマンスデータ上では、この期間のそのOBServerノードのTPSが0と表示されます。接続を切断すると、以降のリクエストについてODPはブロックリストに従ってルーティングし、そのOBServerノードに転送しなくなるため、TPSは正常に戻ります。
アクティブ不可用ブラックリスト
アクティブ不可用ブラックリストメカニズムの核心は、業務SQLの実行結果に基づいてOBServerノードの状態を定義し、ブロックおよび解除操作をトリガーすることです。状態ブラックリストや検出ブラックリストと比較して、アクティブ不可用ブラックリストのブロックおよび解除ははるかに慎重に行われます。主な目的は、単一のSQL実行結果による誤判断を防ぐことです。具体的な動作は以下の通りです。
失敗:時間点ごとに次回の失敗イベントを記録します。
ODPがOBServerノードにSQLを送信した後、ob_query_timeout時間を超えても応答がない場合。
OBServerノードがエラーコードOB_SERVER_IS_INIT、OB_SERVER_IS_STOPPING、OB_PACKET_CHECKSUM_ERROR、OB_ALLOCATE_MEMORY_FAILEDを返した場合。
ODPとOBServerノードの接続失敗/メッセージ解析失敗、データ転送失敗の場合。
ブロック:デフォルトでは、OBServerノードが120秒以内に5回のアクティブ不可用失敗レコードを持つ場合、そのOBServerノードをブロックします。これは、パラメータcongestion_fail_window(エラー統計周期)とcongestion_failure_threshold(エラー回数)によって制御されます。
再試行:デフォルトでは、アクティブ不可用ブラックリストに追加されてから20秒以上経過すると、そのOBServerノードに再びSQLを送信する試みが行われます。リトライの時間間隔は
congestion_retry_intervalパラメータで制御されます。解除:試行したSQLの実行が成功した場合、解除処理が行われます。デフォルトでは、OBServerノードは20秒間解除されません。この値はパラメータ
min_keep_congestion_intervalで制御されます。
上記の3種類のブラックリスト間に優先順位はありません。OBServerノードがいずれかのブラックリストに含まれている限り、そのマシンはリクエストを受信できません。言い換えれば、OBServerノードがどのブラックリストにも含まれていない場合にのみ、リクエストを受信できます。
選択可能なすべてのOBServerノードがブラックリストに含まれている場合、ブラックリスト内のOBServerノードに対して強制的にリトライが行われます。
ブロックリストの構成パラメータ
クライアント側でrootユーザーを使用し、ODPプロキシ経由でクラスタの
sysテナントにログインします。obclient> obclient -h10.10.10.1 -uroot@sys#obdemo -P2883 -p -cここでは、ODPマシンのIPアドレスを
10.10.10.1、クラスタ名をobdemoとして、OBClientを使用してクラスタに接続する例を示します。OceanBaseテナントへの接続手順の詳細については、接続方法の概要(MySQLモード)および接続方法の概要(Oracleモード)を参照してください。以下のコマンドを実行して、ODPの構成パラメータを確認します。
obclient> SHOW PROXYCONFIG;ALTER proxyconfig SET key=valueコマンドを実行して、ODPの指定した構成パラメータを更新します。構成パラメータの更新は即時に反映されます。ブロックリストに関連する構成パラメータの説明は、次の表のとおりです。
パラメータ説明enable_congestion ブロックリストメカニズムを有効にするかどうかを指定します。デフォルトで有効です。ブロックリストメカニズムの動作に問題が発生した場合、このオプションを一時的に無効にしてODPの正常な動作を確保できます。 congestion_failure_threshold OBServerノードをブロックリストに追加するかどうかを制御します。 congestion_fail_windowと組み合わせて使用します。congestion_fail_window時間内にOBServerノードのエラー回数がこの値を超えた場合、ODPはそのOBServerノードをブロックリストに追加します。このパラメータの値が0未満の場合、ブロックリストに登録されているすべてのサーバーがブロックリストから除外されます。congestion_fail_window エラー統計の期間(秒)を設定します。デフォルト値は120秒です。エラー統計期間内にエラー回数が congestion_failure_thresholdの値を超えた場合、そのサーバーノードをブロックリストに追加します。このパラメータの値は動的に調整可能です。このパラメータを変更すると、現在のエラー統計カウントがリセットされ、新しい設定値からエラー回数の統計が再開されます。congestion_retry_interval アクティブ不可用ブロックリストに追加されたOBServerノードのリトライ間隔を設定します。デフォルト値は20秒です。 min_keep_congestion_interval ブロックリストに追加されたOBServerノードが、ブロックリストから除外されるまでの許容時間を設定します。 min_congested_connect_timeout クライアント接続タイムアウトの値を設定します。接続タイムアウトした場合、OBServerノードをアクティブ不可用ブロックリストに追加します。デフォルト値は100msです。
ブラックリストの確認
クライアント側でrootユーザーを使用し、ODPプロキシ経由でクラスタの
sysテナントにログインします。obclient> obclient -h10.10.10.1 -uroot@sys#obdemo -P2883 -p -cここでは、ODPマシンのIPアドレスを
10.10.10.1、クラスタ名をobdemoとして、OBClientを使用してクラスタに接続する例を示します。OceanBaseテナントへの接続手順の詳細については、接続方法の概要(MySQLモード)および接続方法の概要(Oracleモード)を参照してください。以下のコマンドを実行して、ブラックリスト情報を確認します。
ステートメントは以下のとおりです:
SHOW PROXYCONGESTION [all] [clustername];関連パラメータの説明は以下のとおりです:
オプションを指定しない場合、すべてのクラスタのブラックリスト情報を照会できます。
allのみを指定した場合、すべてのクラスタのOBServerノード情報(ブラックリストおよび非ブラックリスト内のOBServerノード情報を含む)を表示できます。clusternameのみを指定した場合、指定されたクラスタのブラックリスト情報を表示できます。allとclusternameを同時に指定した場合、指定されたクラスタのOBServerノード情報を表示できます。
例
ここでは、単一ノードクラスタ obcluster のブラックリスト情報を確認する例を示します。
obclient> show proxycongestion 'obcluster'\G
出力は次のとおりです:
*************************** 1. row ***************************
cluster_name: obcluster
zone_name: zone1
region_name: sys_region
zone_state: ACTIVE
server_ip: xxx.xxx.xxx.xxx:2881
cr_version: 5
server_state: ACTIVE
alive_congested: 0
last_alive_congested: 0
dead_congested: 0
last_dead_congested: 0
stat_alive_failures: 0
stat_conn_failures: 0
conn_last_fail_time: 0
conn_failure_events: 0
alive_last_fail_time: 0
alive_failure_events: 0
ref_count: 2
detect_congested: 0
last_detect_congested: 0
説明
dead_congestedまたはalive_congestedのいずれかの状態が1の場合、そのOBServerノードはブラックリストに追加されています。ODP V1.1.2 より前のバージョンでは、
clusternameはシングルクォートまたはダブルクォートで囲む必要はありません。V1.1.2 以降のバージョンでは、シングルクォートまたはダブルクォートで囲む必要があります。