Amazon Redshift 動的ワークロードマネジメント(WLM)を試してみた

2015.09.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

先日、Redshiftのワークロードに割り当てたメモリや最大並列実行数を再起動なしで変更可能になりました。この機能を利用すると、日中はBIツールにリソースを優先的に割り当て、夜間はバッチ処理用といった異なるワークロードに対して柔軟にリソースの割り当て変更するなどの応用が考えられます。実際にバッチ処理用のキューを割当て動的変更した時の動作やこの機能の使い勝手についてレポートします。

WLM(ワークロードマネジメント)

Redshiftには実行に長い時間を要するクエリー(ロングクエリー)は、クラスタ全体のボトルネックとなり、ショートクエリを待たせる可能性があります。そこで、用途ごとにクエリーの並列度やメモリ(%)の上限を設けた複数のキューを定義することでクエリー処理の制御が可能になります。

wlm-flow

WLM(ワークロードマネジメント)の詳細につきましては、以下の資料を御覧ください。

AWS Black Belt Tech Webinar 2015 Amazon Redshift

RedshiftのWLM小話

動的ワークロードマネジメント

新しくWLMのパラメータが Dynamic と Static の区別が用意され、Dyamic Parameter は Redshift を再起動せずにパラメータ変更が可能になりました。

  • Dynamic Parameter
    • Concurrency(並列実行数)
    • Percent of memory to use (メモリ使用量)
  • Static Parameter
    • User groups
    • User group wildcard
    • Query groups
    • Query group wildcard
    • Timeout

想定したユースケース

Redshift のデフォルトは、 単一のデフォルトキューで構成されています。BIツールのようなアドホックなショートクエリーはこれまで通り、デフォルトキューを用います。バッチ処理のようなロングクエリーは新たにバッチキューを作成して、バッチ処理はこのバッチキューを用いるように構成します。

キューへのクエリの割り当て方法は、Redshiftのグループに割り当てる「ユーザーグループ」と実行時にクエリをキューに割り当てる「クエリグループ」があります。今回はクエリグループを利用します。

以下のように日中は、BIツール(デフォルトキュー)に対して優先的にメモリを多く設定します。

  • BIツールからのアドホックなショートクエリーは並列度「10」、メモリ80%
  • バッチ処理のロングクエリーに対して並列度「1」、メモリ20%

wlm-default

対して、以下のようにバッチ処理(バッチキュー)に対して優先的にメモリを多く設定します。

  • BIツールからのアドホックなショートクエリーは並列度「10」、メモリ20%
  • バッチ処理のロングクエリーに対して並列度「1」、メモリ80%

wlm-batch

以降では、このバッチキューに対して、動的にメモリ(%)を変更させる前後のVACUUM処理のパフォーマンスの違いについて見ていきます。

動的ワークロードマネジメントの検証

動的ワークロードマネジメントの機能でメモリ(%)を増やすことでどれだけ処理時間が短縮できるかの検証として、処理負荷の高いVACUUM処理に要する時間をそれぞれ計測してみます。

クエリ実行前にクエリーグループに 'batch' を設定

今回はクエリグループを利用しますので、クエリ実行前に以下のコマンドを実行します。
cmdb=# SET query_group TO 'batch';

並列度「1」、メモリ20%時の処理時間

この条件のVACUUMの実行時間に約7分かかりました。
cmdb=# INSERT INTO lineorder_20percent VALUES(1,1,1,1,1,1,'9','8',1,1,1,1,1,1,1,1,'7');
INSERT 0 1
Time: 405.142 ms

cmdb=# INSERT INTO lineorder_20percent SELECT * FROM lineorder;
INSERT 0 75004738
Time: 81320.134 ms

cmdb=# VACUUM lineorder_20percent;
VACUUM
Time: 418926.359 ms

メモリ20%から80%に変更

パラメタの変更にAWSCLIを用いて以下のように設定を変更しました。動的にパラメターを適用するので、ApplyTypeに"dynamic"を指定しています。

aws redshift modify-cluster-parameter-group \
--parameter-group-name r21-redshift-other-sets-parametergroup-aaaaaaaaa \
--parameters '{"ApplyType":"dynamic","ParameterName":"wlm_json_configuration","ParameterValue":"[{\"query_group\":[\"batch\"],\"user_group\":[],\"query_group_wild_card\":0,\"user_group_wild_card\":0,\"query_concurrency\":1,\"max_execution_time\":0,\"memory_percent_to_use\":80},{\"query_group\":[],\"user_group\":[],\"query_group_wild_card\":0,\"user_group_wild_card\":0,\"query_concurrency\":10,\"max_execution_time\":0,\"memory_percent_to_use\":20}]"}'

コマンドを実行するとマネジメントコンソールに直ちに Cluster Status が modifying 変わりました。今回の環境(dc1.large シングルクラスタ構成)では、150秒ほどすると available になりました。 wlm-amc

動的なパラメターの反映に150秒ほどかかりましたので、反映するまでの時間の考慮が必要となります。クラスタステータスのイベントを利用して非同期でジョブを実行するなどの検討が必要となりそうです。

並列度「1」、メモリ80%時の処理時間

この条件のVACUUMの実行時間に約4分かかりました。

cmdb=# INSERT INTO lineorder_80percent VALUES(1,1,1,1,1,1,'9','8',1,1,1,1,1,1,1,1,'7');
INSERT 0 1
Time: 201.490 ms

cmdb=# INSERT INTO lineorder_80percent SELECT * FROM lineorder;
INSERT 0 75004738
Time: 89496.209 ms

cmdb=# VACUUM lineorder_80percent;
VACUUM
Time: 247059.006 ms

設定したクエリーグループのリセット

現在設定しているクエリグループ 'batch' の設定を解除(リセット)します。これで設定前の状態に戻ります。

reset query_group;

計測結果

メモリを20%から80%に変更することで、処理時間を40%短縮しました。パラメタが動的に反映されていることが確認できます。メモリを80%にするとディスクのRead IOPSとWrite IOPSに対する負荷が低下ました。これまでディスクに作成していた中間テーブルが不要になりメモリ内で実行できるようになったと考えられます。多くのメモリを割り当てが、IOバウンドなクエリには効果的であることが証明されました。 wlm-cpu

最後に

従来にもスロット数を動的に変更することでメモリ割り当てを変更するテクニックがありましたが、この方法は1キューの中のスロット数(並列実行数)の変更であるのに対して、動的ワークロードマネジメントはキューの間のリソース動的変更が可能になっています。これらを使い分けられるとワークロード管理の達人です。

WLMは、メモリ割当を管理できますが、CPUやIOの割当ては管理していません。例えば、リクエストの多いワークロードに対して極端にメモリを割当てない場合、本来メモリ内で実行可能だったクエリが、ディスクに中間テーブルを作成する必要に迫られ、全体のディスクI/Oがパフォーマンスを低下させる可能性が考えられます。なので、並列実行数との組み合わせが重要になります。

動的ワークロードマネジメントは動的なワークロードをプログラムで管理ができるようになり、限られたリソースを積極的に効率良く使うことができるようになりました。クラスタ数が大きくなるとこのようなチューニングは費用対効果が高いので、ぜひともご活用ください。