本記事では、MySQLモードにおけるリソース分離の設定方法について説明します。
前提条件
リソース分離の設定を開始する前に、リソースグループ、リソース管理計画、リソース管理計画の内容などの基本概念を理解しておくことを推奨します。リソース分離に関する基本概念および適用シナリオについては、リソース分離の概要を参照してください。
CPUのリソース分離はcgroupに依存しているため、CPUのリソース分離を制御する必要がある場合は、リソース分離の設定を開始する前に、cgroupディレクトリを設定し、cgroup機能を有効にする必要があります。cgroupディレクトリの設定およびcgroup機能の有効化に関する操作については、cgroupの設定を参照してください。
Userレベルのリソース分離とFunctionレベルのリソース分離を設定する際、CPUのリソース分離を制御する必要がなく(IOPSリソース分離のみが必要な場合)、cgroupを設定する必要はありません。SQLレベルのリソース分離を設定する場合、CPUのリソース分離を制御する必要があるかどうかにかかわらず、cgroupを設定する必要があります。
IOPSリソース分離を行う前に、ディスク性能のキャリブレーションを実行する必要があります。ディスク性能のキャリブレーションに関する操作については、ディスク性能のキャリブレーションを参照してください。
CPUのリソース分離のみを制御する必要がある場合、ディスク性能のキャリブレーションは不要です。
説明
V4.3.5バージョンでは、V4.3.5 BP2バージョン以降、CPUおよびIOPSリソース分離はもはやディスク性能のキャリブレーション操作に強く依存しません。
リソース分離を行うユーザーが作成済みであることを確認してください。ユーザー作成の詳細な操作については、ユーザーの作成を参照してください。
SQLレベルのリソース分離を設定する場合は、リソース分離を行うデータベース、テーブル、および列が作成済みであることを確認してください。
背景
リソース分離には、Userレベルのリソース分離、SQLレベルのリソース分離、Functionレベルのリソース分離の3種類があります。3種類のリソース分離の詳細については、リソース分離の概要を参照してください。
ステップ1(オプション):テナントのMAX_IOPSとMIN_IOPSを有効な値に設定する
説明
テナント作成時に使用したユニット仕様で、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です。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レベルのリソース分離とは異なり、SQLレベルのリソース分離では、SQLが解析されるかPlan Cacheにヒットするまで、どのリソースグループのリソースを使用するかが決定されません。その際、使用すべきリソースグループが現在使用中のものと異なることが判明した場合、システムは一度リトライを行い、マッチングルールに対応するリソースグループのリソースを使用してそのSQLを処理します。
SQLレベルのリソース分離によるパフォーマンスへの影響は、主に以下の3つのケースに分かれます:
あるSQLがどのルールにもマッチしない場合、パフォーマンスへの影響はほとんどありません。
あるSQLが1つのルールにマッチした場合、そのルールで指定されたリソースグループが
batch_groupであると仮定すると、このSQLは最終的にbatch_groupのリソースで実行されるだけでなく、次のSQLも最初はbatch_groupのリソースで実行されます。他のリソースグループに切り替える必要があると判断されるまで、システムはリトライしません。連続して一連のSQLを実行し、これらのSQLがすべて同一のリソースグループにバインドされている場合、このポリシーを使用することで、最初のSQLの処理時にのみリトライが必要となり、その後のSQLについてはリトライが不要になります。リトライを最小限に抑えることで、パフォーマンスへの影響は小さくなります。各SQLが予想されるリソースグループが前のSQLと異なる場合、各SQLは一度ずつリトライが必要となり、パフォーマンスへの影響は大きくなります。