ODPはブロックリストメカニズムを使用し、OBServerノードのピーク時を避けたマージ、アップグレード、リーダー切り替え、ダウン、起動、停止などのプロセスにおけるOBServerノードへのアクセス制御を適応的に処理します。
背景
ODPには、ステータスブラックリスト、ディテクションブラックリスト、アクティブながら利用不可ブラックリストの3種類のブラックリストがあり、パラメータ設定によってブラックリストを管理できます。
ブラックリストにより、主に以下のシナリオでアクセス制御を実現できます:
ピークカットマージ時にマージ中のZoneにトラフィックがない場合。
クラスタアップグレード時に、アップグレード中のOBServerノードまたはZoneにアクセスできない場合。
OBServerノードがダウンした後、そのOBServerノードに再びアクセスしないようにする場合。
Partition移行後、移行前の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未満の場合、ブラックリスト内のすべてのServerがブラックリストから除外されます。congestion_fail_window エラー統計期間の時間(秒)を設定します。デフォルト値は120秒です。エラー統計期間内にエラー回数が congestion_failure_thresholdの値を超えた場合、そのServerノードをブラックリストに追加します。このパラメータの値は動的に調整可能です。このパラメータを変更すると、現在のエラー統計カウントがリセットされ、新しい設定値からエラー回数の統計が再開されます。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 以降のバージョンでは、シングルクォートまたはダブルクォートで囲む必要があります。