本記事では、主にMySQLモードでのリソース分離の設定方法について説明します。
前提条件
リソース分離の設定を開始する前に、リソースグループ、リソース管理計画、リソース管理計画の内容などの基本概念を理解しておくことをお勧めします。リソース分離に関連する基本概念および適用シナリオについては、リソース分離の概要を参照してください。
CPUのリソース分離はcgroupに依存しているため、CPUのリソース分離を制御する必要がある場合は、リソース分離の設定を開始する前に、cgroupディレクトリを設定し、cgroup機能を有効にする必要があります。cgroupディレクトリの設定とcgroup機能の有効化に関する操作については、cgroupの設定を参照してください。
Userレベルのリソース分離とFunctionレベルのリソース分離を設定する場合、CPUのリソース分離を制御する必要がない場合(IOPSリソース分離のみが必要な場合)、cgroupの設定は不要です。SQLレベルのリソース分離を設定する場合は、CPUのリソース分離を制御する必要があるかどうかにかかわらず、cgroupの設定が必要です。
IOPSリソース分離を行う前に、ディスク性能のキャリブレーションを行うことができます。ディスク性能のキャリブレーションに関する操作については、ディスク性能のキャリブレーションを参照してください。
説明
現在のバージョンでは、IOPSリソース分離はディスク性能のキャリブレーション操作に強く依存しなくなりました。
リソース分離を行うユーザーが既に作成されていることを確認してください。ユーザー作成の詳細な操作については、ユーザーの作成を参照してください。
SQLレベルのリソース分離を設定する必要がある場合は、リソース分離を行うデータベース、テーブル、列が既に作成されていることを確認してください。
背景
リソース分離は、Userレベルのリソース分離、SQLレベルのリソース分離、Functionレベルのリソース分離の3種類に分けられます。これら3種類のリソース分離に関するより詳細な説明については、リソース分離の概要を参照してください。
ステップ1(オプション):テナントのMAX_IOPSとMIN_IOPSを有効な値に設定する
説明
テナント作成時に使用したUnit仕様で、MAX_IOPSとMIN_IOPSが16KB読み取りに対応するIOPS値に設定されている場合、またはIOPSを制御するリソース分離が不要な場合は、この手順を無視してください。
ディスクキャリブレーション完了後、リソース分離計画を設定する前に、テナントのリソース仕様におけるMAX_IOPSとMIN_IOPSの値が有効な値であることを確認する必要があります。ここでの有効な値とは、16KB読み取りに対応するIOPS値をテナントのIOPS設定の参考値とすることを指します。
rootユーザーでクラスタのsysテナントにログインします。以下のコマンドを実行し、リソース分離を行うテナントのリソース仕様を確認します。
obclient [oceanbase]> SELECT * FROM oceanbase.DBA_OB_UNIT_CONFIGS;クエリ結果の例は以下のとおりです:
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+ | UNIT_CONFIG_ID | NAME | CREATE_TIME | MODIFY_TIME | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT | +----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+ | 1 | sys_unit_config | 2023-12-19 13:55:04.463295 | 2023-12-19 13:56:08.969718 | 3 | 3 | 2147483648 | 3221225472 | 9223372036854775807 | 9223372036854775807 | 3 | | 1001 | small_unit | 2023-12-19 13:56:09.851665 | 2023-12-19 13:56:09.851665 | 1 | 1 | 2147483648 | 6442450944 | 9223372036854775807 | 9223372036854775807 | 1 | | 1002 | medium_unit | 2023-12-19 13:56:10.030914 | 2023-12-19 13:56:10.030914 | 8 | 4 | 8589934592 | 25769803776 | 9223372036854775807 | 9223372036854775807 | 4 | | 1003 | large_unit | 2023-12-19 13:56:10.112115 | 2023-12-19 13:56:10.112115 | 16 | 8 | 21474836480 | 64424509440 | 9223372036854775807 | 9223372036854775807 | 8 | +----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+---------------------+---------------------+-------------+ 4 rows in setクエリ結果によると、そのテナントの
MAX_IOPSとMIN_IOPSがどちらもデフォルト値INT64_MAX(9223372036854775807)である場合、テナントが使用可能なIOPSリソースを再計画する必要があります。以下のコマンドを実行し、テナントがデプロイされているOBServerノードを確認します。
obclient [oceanbase]> SELECT DISTINCT SVR_IP, SVR_PORT FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE tenant_id = xxxx;クエリ結果の例は以下のとおりです:
+----------------+----------+ | SVR_IP | SVR_PORT | +----------------+----------+ | xx.xxx.xxx.xx1 | xxxx1 | | xx.xxx.xxx.xx1 | xxxx2 | | xx.xxx.xxx.xx1 | xxxx3 | +----------------+----------+ 3 rows in set以下のコマンドを実行し、リソース分離を行うテナントが存在するOBServerノードのディスクキャリブレーション値を確認します。16KB読み取りのディスクキャリブレーション値をそのノードのIOPS設定の上限値として使用します。
obclient [oceanbase]> SELECT * FROM oceanbase.GV$OB_IO_BENCHMARK WHERE MODE='READ' AND SIZE=16384;クエリ結果の例は以下のとおりです:
+----------------+----------+--------------+------+-------+-------+------+---------+ | SVR_IP | SVR_PORT | STORAGE_NAME | MODE | SIZE | IOPS | MBPS | LATENCY | +----------------+----------+--------------+------+-------+-------+------+---------+ | xx.xxx.xxx.xx1 | xxxx1 | DATA | READ | 16384 | 48162 | 752 | 331 | | xx.xxx.xxx.xx1 | xxxx2 | DATA | READ | 16384 | 47485 | 741 | 336 | | xx.xxx.xxx.xx1 | xxxx3 | DATA | READ | 16384 | 48235 | 753 | 331 | +----------------+----------+--------------+------+-------+-------+------+---------+ 3 rows in setクエリ結果に基づき、取得した各ノードのディスクキャリブレーション値を上限値としてテナントが使用可能なIOPSを計画します。クラスタ内には複数のテナントが同一のOBServerノードにデプロイされている可能性があるため、業務の実際の状況に応じてこれらのIOPSを割り当てる必要があります。
あるクラスタに2つのテナントがあり、両方のテナントが同一のOBServerノードにデプロイされている場合、各OBServerノードの16KB読み取りのディスクIOPSベース値が同じで20000 IOPSであり、かつ、2つのテナントの負荷がほぼ同じであると予想される場合、20000 IOPSを2つのテナントに均等に分割することができます(具体的には、実際の業務状況に応じてテナントが使用可能なIOPSを割り当てることができます)。つまり、各テナントの
MAX_IOPSとMIN_IOPSを10000に設定します。業務上の理由から、MIN_IOPSをMAX_IOPSより小さい値に設定することもできます。以下のコマンドを実行し、テナントの
MAX_IOPSとMIN_IOPS値を変更します。MIN_IOPSを変更してからMAX_IOPSを変更することを推奨します。ALTER RESOURCE UNIT unit_name MIN_IOPS = xxx;ALTER RESOURCE UNIT unit_name MAX_IOPS = xxx;
ステップ2:リソース分離計画を設定する
現在のテナントに既に tp_user と ap_user の2つのユーザーがいると仮定します。
以下の手順を参考にリソース分離計画を設定し、異なるユーザーやバックグラウンドタスクが異なるCPUまたはIOPSリソースを使用するよう制御できます。
テナント管理者がクラスタのMySQLテナントにログインします。
DBMS_RESOURCE_MANAGERシステムパッケージのCREATE_CONSUMER_GROUPサブプログラムを呼び出して、リソースグループを作成します。ステートメントは以下のとおりです:
CALL DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( CONSUMER_GROUP => 'group_name' , COMMENT => 'coments' );関連パラメータの説明は以下のとおりです:
CONSUMER_GROUP:リソースグループ名を定義します。COMMENT:リソースグループの備考情報を入力します。
例えば、以下の2つのリソースグループ
interactive_groupとbatch_groupを作成します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( CONSUMER_GROUP => 'interactive_group' , COMMENT => 'TP' );obclient [test]> CALL DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP( CONSUMER_GROUP => 'batch_group' , COMMENT => 'AP' );作成成功後、
oceanbase.DBA_RSRC_CONSUMER_GROUPSビューを確認できます。oceanbase.DBA_RSRC_CONSUMER_GROUPSビューの詳細については、oceanbase.DBA_RSRC_CONSUMER_GROUPSを参照してください。DBMS_RESOURCE_MANAGERシステムパッケージのCREATE_PLANサブプログラムを呼び出して、リソース管理計画を作成します。ステートメントは以下のとおりです:
CALL DBMS_RESOURCE_MANAGER.CREATE_PLAN( PLAN => 'plan_name', comment => 'coments');関連パラメータの説明は以下のとおりです:
PLAN:リソース管理計画名を定義します。COMMENT:リソース管理計画の備考情報を入力します。
例えば、
daytimeという名前のリソース管理計画を作成し、備考情報を追加します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.CREATE_PLAN( PLAN => 'daytime', comment => 'TPFirst');作成成功後、
oceanbase.DBA_RSRC_PLANSビューを確認できます。oceanbase.DBA_RSRC_PLANSビューの詳細については、oceanbase.DBA_RSRC_PLANSを参照してください。DBMS_RESOURCE_MANAGERシステムパッケージのCREATE_PLAN_DIRECTIVEサブプログラムを呼び出して、リソース管理計画の内容を作成します。これはリソース管理計画を有効化する際に、リソースグループが使用するCPUリソースとIOPSリソースを制限するために使用されます。ステートメントは以下のとおりです:
CALL DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE ( PLAN => 'plan_name', GROUP_OR_SUBPLAN => 'group_name' , COMMENT => 'comments', MGMT_P1 => int_value, UTILIZATION_LIMIT => int_value, MIN_IOPS => int_value, MAX_IOPS => int_value, WEIGHT_IOPS => int_value, MAX_NET_BANDWIDTH => int_value, NET_BANDWIDTH_WEIGHT => int_value);関連パラメータの説明は以下のとおりです:
PLAN:リソース管理計画名を指定します。GROUP_OR_SUBPLAN:リソースグループを指定します。COMMENT:リソース管理計画の備考情報を入力します。デフォルト値はNULLです。MGMT_P1:システムがフル負荷の場合、相対的に利用可能な最大CPU比率を指定します。デフォルト値は100です。UTILIZATION_LIMIT:リソースグループが使用するCPUリソースの上限を指定します。このパラメータのデフォルト値は100で、値の範囲は (0, 100] です。100はテナントの全CPUリソースを最大限に使用できることを意味します。値を70に設定すると、テナントのCPUリソースの70%を最大限に使用できます。MIN_IOPS:I/O競合が発生した場合に、リソースグループが予約するIOPSリソースです。合計は100を超えません。デフォルト値は0です。MAX_IOPS:リソースグループが使用できる最大IOPSリソースを指定します。合計は100を超えることができます。デフォルト値は100です。WEIGHT_IOPS:IOPSの重み値を指定します。合計は100を超えることができます。デフォルト値は0です。MAX_NET_BANDWIDTH:使用できる最大ネットワーク帯域幅リソースを指定します。合計は100を超えることができます。デフォルト値は100です。NET_BANDWIDTH_WEIGHT:ネットワーク帯域幅の重み値を指定します。合計は100を超えることができ、比率に応じて分割されます。デフォルト値は0です。
例:
リソース計画を
daytimeに指定し、リソースグループinteractive_groupにバインドします。使用可能なCPUリソースの上限をテナントのCPU総リソースの80%に設定します。同時に、I/O競合が発生した場合、使用可能なIOPSリソースの最小割り当てを30%、使用可能なIOPSリソースの上限をIOPS総リソースの90%、IOPSリソースの重みを80%、使用可能なネットワーク帯域幅リソースを40%、ネットワーク帯域幅の重みを40%に指定します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( PLAN => 'daytime', GROUP_OR_SUBPLAN => 'interactive_group' , COMMENT => '', UTILIZATION_LIMIT =>80, MIN_IOPS => 30, MAX_IOPS => 90, WEIGHT_IOPS => 80, MAX_NET_BANDWIDTH => 40, NET_BANDWIDTH_WEIGHT => 40);リソース計画を
daytimeに指定し、リソースグループbatch_groupにバインドします。使用可能なCPUリソースの上限をテナントのCPU総リソースの40%に設定します。同時に、I/O競合が発生した場合、使用可能なIOPSリソースの最小割り当てを40%、使用可能なIOPSリソースの上限をIOPS総リソースの80%、IOPSリソースの重みを70%、使用可能なネットワーク帯域幅リソースを30%、ネットワーク帯域幅の重みを30%に指定します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE( PLAN => 'daytime', GROUP_OR_SUBPLAN => 'batch_group' , COMMENT => '', UTILIZATION_LIMIT => 40, MIN_IOPS => 40, MAX_IOPS => 80, WEIGHT_IOPS => 70, MAX_NET_BANDWIDTH => 30, NET_BANDWIDTH_WEIGHT => 30);
作成成功後、
oceanbase.DBA_RSRC_PLAN_DIRECTIVESビューとoceanbase.DBA_OB_RSRC_IO_DIRECTIVESビューを確認できます。oceanbase.DBA_RSRC_PLAN_DIRECTIVESビューの詳細については、oceanbase.DBA_RSRC_PLAN_DIRECTIVESを参照してください。oceanbase.DBA_OB_RSRC_IO_DIRECTIVESビューの詳細については、oceanbase.DBA_OB_RSRC_IO_DIRECTIVESを参照してください。DBMS_RESOURCE_MANAGERシステムパッケージのSET_CONSUMER_GROUP_MAPPINGサブプログラムを呼び出し、実際の使用シナリオに基づいてリソース分離のマッピングルールを作成します。ステートメントは以下のとおりです:
CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'column | user | function', VALUE => 'values', CONSUMER_GROUP => 'group_name');関連パラメータの説明は以下のとおりです:
ATTRIBUTE:属性タイプを指定します。属性名は大文字小文字を区別しません。columnはSQLレベルのリソース分離を表します。userはUserレベルのリソース分離を表します。functionはFunctionレベルのリソース分離を表します。
VALUE:属性値を指定します。属性タイプが
columnの場合、データベース名、テーブル名、列名、定数値、ユーザー名などの情報を指定する必要があります。その中で:
データベース名とユーザー名はオプションです。デフォルトのデータベース名は現在のデータベース名です。ユーザー名を指定しない場合、現在のテナント内で後から作成されるすべてのユーザーに適用されます。
テーブル名、列名、定数値は必須項目であり、各項目には1つの値しか指定できません。定数値を指定する場合、数値または文字列のみを指定できます。
テーブル名、列名、ユーザー名を指定する場合、指定したテーブル、列、ユーザーが存在している必要があります。
属性タイプが
userの場合、ここではユーザー名を指定するだけで済みます。現在は1人のユーザーのみを指定できます。属性タイプが
functionの場合、ここではDAGスレッドに対応する複数のバックグラウンドタスクを指定します:compaction_high、ha_high、compaction_mid、ha_mid、compaction_low、ha_low、ddl、ddl_high、clog_high、および opt_stats。そのうちの1つを記入します。現在は1つのタスクのみを指定できます。各タスクの詳細については、リソース分離の概要を参照してください。
CONSUMER_GROUP:バインドするリソースグループを指定します。SQLがVALUEで設定されたマッチングルールにヒットした場合、そのステートメントを実行するためにどのリソースグループにバインドするかを示します。現在は1つのリソースグループのみをバインドできます。バインドするリソースグループを指定しない場合、デフォルトでシステム組み込みの
OTHER_GROUPSにバインドされます。システム組み込みのOTHER_GROUPSが対応するリソースは以下のとおりです:MIN_IOPS = 100 - SUM(テナント内の他のリソースグループの合計)
MAX_IOPS = 100
WEIGHT_IOPS = 100
例:
SQLレベルのリソース分離マッチングルールを作成します。
ユーザー
tp_userが実行するWHERE条件にtest.t.c3 = 3を含むSQLステートメントがある場合、そのSQLステートメントはbatch_groupという名前のリソースグループにバインドされて実行され、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。注意
SQLステートメントを実行する際、ステートメントに
test.t.が含まれている必要はありません。c3が最終的にtest.t.c3として解釈されれば、そのSQLステートメントはbatch_groupという名前のリソースグループにバインドされて実行されます。例:SELECT * FROM test.t WHERE c3 = 1;。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'column', VALUE => 'test.t.c3=3 for tp_user', CONSUMER_GROUP => 'batch_group');実行する
WHERE条件にt.c3=5を含むSQLステートメントがある場合、そのSQLステートメントはinteractive_groupという名前のリソースグループにバインドされて実行され、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'column', VALUE => 't.c3=5', CONSUMER_GROUP => 'interactive_group');
SET_CONSUMER_GROUP_MAPPINGサブプログラムを呼び出してリソースグループにバインドする方法以外に、OceanBaseデータベースではHintを使用してリソースグループにバインドする方法もサポートしています。ユーザーはHintを使用して、実行するSQLを指定したリソースグループに柔軟に送信できます。例えば、実行するSQLステートメントがSELECT * FROM Tの場合、そのSQLがリソースグループbatch_groupによって制限されたリソースを使用するようにするには、Hintを使用してリソースグループにバインドする例は以下のとおりです:obclient [test]> SELECT /*+resource_group('batch_group')*/ * FROM t;説明
Hintを使用してリソースグループを指定した後、リソースグループが存在しない場合、ステートメントの実行時にはデフォルトのリソースグループ
OTHER_GROUPSが使用されます。Userレベルのリソース分離マッチングルールを作成します。
ユーザー
tp_userが実行するSQLをinteractive_groupという名前のリソースグループにバインドして実行し、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'user', VALUE => 'tp_user', CONSUMER_GROUP => 'interactive_group');ユーザー
ap_userが実行するSQLをbatch_groupという名前のリソースグループにバインドして実行し、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'user', VALUE => 'ap_user', CONSUMER_GROUP => 'batch_group');
Functionレベルのリソース分離マッチングルールを作成します。
compaction_highタスクを実行する際、システムがinteractive_groupという名前のリソースグループにバインドされて実行され、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'function', VALUE => 'compaction_high', CONSUMER_GROUP => 'interactive_group');ddl_highタスクを実行する際、システムがbatch_groupという名前のリソースグループにバインドされて実行され、そのリソースグループによって制限されたCPUリソースとIOPSリソースを使用します。obclient [test]> CALL DBMS_RESOURCE_MANAGER.SET_CONSUMER_GROUP_MAPPING( ATTRIBUTE => 'function', VALUE => 'ddl_high', CONSUMER_GROUP => 'batch_group');
作成成功後、
oceanbase.DBA_RSRC_GROUP_MAPPINGSビューを確認できます。oceanbase.DBA_RSRC_GROUP_MAPPINGSビューの詳細については、oceanbase.DBA_RSRC_GROUP_MAPPINGSを参照してください。リソースグループに適切なリソース管理計画を有効にします。
異なるリソース管理計画では、同一のリソースグループが制限されるリソースが異なる場合があります。リソースグループに適切なリソース管理計画を有効にする必要があります。
obclient [test]> SET GLOBAL resource_manager_plan = 'daytime';説明
リソースを制限する必要がない場合、
SET GLOBAL resource_manager_plan = '';ステートメントを使用してすべてのリソース計画を無効にできます。
設定後の注意事項
リソース分離のマッチングルールを追加した後、ユーザーを削除して再作成しても、リソース分離のマッチングルールは引き続き適用されます。
リソース分離のマッチングルールは追加後すぐには有効になりません。通常は10秒以内に有効になる予定ですが、実際の環境によって異なる場合があります。
SQLレベルのリソース分離は、UserレベルおよびFunctionレベルのリソース分離よりも優先順位が高いです。
リソース分離のマッチングルールを追加した後、現在は
SELECT、INSERT、UPDATE、DELETEなどのステートメントでのみ有効であり、DDLやDCLステートメント、PLステートメントでは有効になりません。prepareStatementでは有効になります。
構成パラメータによるパフォーマンスへの影響
UserレベルおよびFunctionレベルのリソース分離は、SQLが解析される前にどのリソースグループのリソースを使用するかを確認できるため、パフォーマンスに影響しません。
SQLレベルのリソース分離によるパフォーマンスへの影響は、主に再試行によるものです。UserレベルおよびFunctionレベルのリソース分離が、1つのSQLが解析される前にどのリソースグループのリソースを使用するかを決定するのとは異なり、SQLレベルのリソース分離では、SQLが解析されたりPlan Cacheにヒットしたりした時点で初めて、どのリソースグループのリソースを使用するかが決定します。その際、使用すべきリソースグループが現在使用中のものと異なる場合、システムは1回再試行を行い、マッチングルールに対応するリソースグループのリソースを使用してそのSQLを処理します。
SQLレベルのリソース分離によるパフォーマンスへの影響は、主に以下の3つのケースに分けられます:
1つのSQLがいずれのルールにもマッチしない場合、パフォーマンスへの影響はほとんどありません。
1つのSQLが1つのルールにマッチする場合、そのルールで指定されたリソースグループが
batch_groupであると仮定すると、そのSQLは最終的にbatch_groupのリソースで実行されるだけでなく、次のSQLも最初はbatch_groupのリソースで実行されます。ルールにマッチして他のリソースグループへの切り替えが必要であることが判明するまで、システムは再試行しません。連続して一括のSQLを実行し、それらのSQLがすべて同じリソースグループにバインドされているシナリオでは、このポリシーを使用することで、最初のSQLを処理する際にのみ再試行が必要となり、後続のSQLは再試行が不要になります。これにより再試行が大幅に削減され、パフォーマンスへの影響は小さくなります。各SQLが想定して使用するリソースグループが前のSQLと毎回異なる場合、各SQLは1回ずつ再試行が必要となり、パフォーマンスへの影響は大きくなります。