Amazon Redshift の『DISTKEY』と『SORTKEY』 は、クエリのパフォーマンスを最適化するための強力なツールです。Redshift は圧縮されたストレージを持つカラム型データベースなので、MySQL、Microsoft SQL、PostgreSQLなどのトランザクション型データベースのようにインデックスが使われることはなく、その代わりに、DISTKEY と SORTKEY が使われます。

そこで、Amazon Redshift のDISTKEYとSORTKEYについて知っておくべきことを5つご紹介します:

  1. DISTKEY と SORTKEY は、Amazon Redshift のクエリのパフォーマンスを最適化するためのツールである。
  2. Redshift は圧縮されたストレージを持つカラムナデータベースで、トランザクショナルデータベースと同じようにインデックスが使われることはない。
  3. DISTKEY と SORTKEYの値を選ぶのは簡単ではない。
  4. 誤った値の選択は、クエリのパフォーマンスに影響を与える可能性がある。
  5. Integrate.io は、Amazon Redshift への継続的なリアルタイムデータベースレプリケーションを提供しており、それによってデータ分析パイプラインが効率化される。

DISTKEYとSORTKEYとして使用する値の選択は、思っているほど簡単ではありません。実際、DISTKEY/SORTKEYの設定を誤ると、クエリのパフォーマンスに悪影響を及ぼす可能性があります。そこで、Amazon Redshift のDISTKEYとSORTKEYについて、以下のチュートリアルで詳しく見ていきましょう。

目次

データを知る

この例では、以下のような「system_errors#」という一連のテーブルを使います。

位置

#

# は数字の羅列です。テーブルの各レコードは、システムで発生したエラーとその  ①タイムスタンプ、②エラーコードで構成されており、各テーブルは2億8千2百万行(たくさんのエラー!)あります。ここで、最適化が必要なクエリがあります。このクエリは、各タイムスライスのエラータイプごとのエラー数を取得します:

thumbnail image

DISTKEYを設定する前に、DISTKEYのないテーブルを作成し、クエリのパフォーマンスを確認することができます:

thumbnail image

この Redshift クラスタ(2ノードdc1.large)では、クエリの実行に20.52秒かかりました。これは、テーブルの行数を考えれば、それほど悪くはないでしょう。ただ CPU (中央処理装置)の使用率を見ると、両方のコンピュートノードで最大で30%のCPU が使われていました。これはクエリパフォーマンスを調査することで改善されるでしょう。

DISTKEY Redshift:クエリーを調査する

では、いよいよAmazon Redshift コンソールを解析してクエリパフォーマンスを確認しますよ。ありがたいことに、クエリパフォーマンスを分析するための便利なグラフやメトリクスが用意されています。

以下は、そのクエリーの「クエリー実行の詳細」です:

thumbnail image

注意書きを見てみましょう。何かが間違っていたのでしょう:

thumbnail image

この警告は、集計が必要な行(同じerr_codeとcreated_atの値を共有する行)が複数の計算ノードにまたがっているために発生しました。各ノードはまず自分の行を集計し、次にリーダーノードがその結果を再度集計する必要があります。上のスクリーンショットで「Aggregate」ステップが2つ見えるのはそのためです。さらに重要なのは、大量のデータがネットワークを介してリーダーノードに送信され、これがパフォーマンスのボトルネックとなったことです。同じerr_codeとcreated_atの値を共有する行をすべて1つのノードに置くことで、これを回避することができますが、これは DISTKEYを確定すればできます。

DISTKEYとSORTKEYを追加する

関連する行をすべて1つのノードに配置するには、カラムの err_code created_at を DISTKEYで使うといいでしょう。


err_code でグループ化したクエリーを created_at なしで実行したい場合は、

DISTKEY と SORTKEYで err_code を選びます。

thumbnail image

新しいテーブルに対してクエリがどのように実行されるかを見てみましょう:

thumbnail image

驚くなかれ、このクエリには54.9秒もかかりました。これは、DISTKEY/SORTKEYを持たないテーブルに対する最初のクエリよりも2.5倍も遅いです。この新しいテーブルは、エラーコードの行を全部同じノードに置き、隣り合わせに保存しています。なぜこのテーブルに対するクエリは、DISTKEY/SORTKEYのないテーブルよりもさらに遅くなるのでしょうか?

パズルを解く

DISTKEYのあるテーブルとないテーブルを2つ作成したところ、DISTKEYのあるテーブルの方が圧倒的に遅かったです:

thumbnail image

なぜこのようなことが起こったのでしょうか?クエリの実行の詳細から、見解を得られるでしょう:

https://cdn.filestackcontent.com/auto_image//compress/cache=expiry:max/0PjYpDLURCG2N5DJ5XG8


赤の長い線があることにお気づきでしょうか。これは、最も遅いノードが平均処理時間より大幅に長くかかったということです。この場合、平均の4倍以上かかっており、最も遅いノードは、他のノードよりも多くの行を有していたはずです。以下のクエリを実行すると、各err_codeの行数が分かります:

thumbnail image

エラーコードの1つ(1204)の行数が、他のものと比べて非常に多いことがわかります。実際には、テーブル内の行の95.5%を占めており、err_codeはDISTKEY であるため、少なくとも95.5%の行がある特定のノードに置かれたことになります。これがいわゆる「スキュー」です。このようなスキューが発生すると、最も遅い処理ノードによって性能が制限されるため、クエリの総処理時間は非常に長くなります。この(極端な)ケースでは、行がほとんどすべて1つのノードで処理されているため、このクエリはDISTKEYのないテーブルに対して行われたクエリよりも時間がかかっているのです。

異なるDISTKEYとSORTKEYを試してみよう

err_codeカラムの値はDISTKEYとして使用するには偏りすぎているので、

代わりに

他のカラムであるCreated_atを使うといでしょう。

thumbnail image

同じクエリを実行した場合、8.32秒しかかからず、前のクエリの6倍以上、最初のクエリの2倍以上の速さで結果が得られました。

CPUの使用率も、以前の30%から10%に改善されています。

thumbnail image

クエリ実行の詳細も良好なようです。スキューは最小限であり、ネットワーク上での大きなデータ転送に対する警告サインはありません。

thumbnail image

Hash Aggregation の詳細を見てみると、一番最初のクエリと比べて、手順がかなり簡略化されていることがわかります。二重の "Aggregate" はもう見えません。

thumbnail image

まとめ

以下が今回のポイントになります:

  1. データベースを最適化したい重要なクエリを少数選びましょう。残念ですが、全クエリに対してテーブルを最適化することはできません。
  2. ネットワーク上での大きなデータ転送を避けるためにDISTKEY を確定しましょう。
  3. クエリで使用するカラムの中から、最もスキューの少ないカラムをDISTKEYとして選び’ましょう。timestamp のような多くの異なる値があるカラムは、最初の選択として適していますが、クレジットカードの種類や曜日など、明確な値が少ないカラムは避けましょう。
  4. DISTKEY/SORTKEYを使用しないテーブルが最高のパフォーマンスを発揮することはほとんどありませんが、オールラウンドなパフォーマンスを発揮することは可能です。データやクエリの性質をよく理解するまでは、DISTKEYとSORTKEYを確定しないのも選択してはありです。

Integrate.ioがデータパイプラインを効率化する方法

Integrate.io は、Amazon Redshift やその他のデータウェアハウスへの継続的でリアルタイムのデータベースレプリケーションを提供します。手動でスクリプトを作成することなく、単一のインターフェースでデータ分析パイプラインを簡素化する、信頼性の高い強力な方法があり、それによって、データチームの時間が節約され、ビジネスが必要とする結果を確実に生成することができます。

リアルタイムのデータベースレプリケーションを提供するだけでなく、Integrate.io のネイティブETLコネクタを使って、異なるタイプのデータを異なるソースからこのデータウェアハウスは移動できます。また、主キー、メタデータ、スキーマ、データ配布、APIなどのデータ統合タスクを気にすることなく、Oracle、AWS RDS、Snowflakeなどのサポート先との間でのデータセットの転送ができます。

Integrate.io はELT、リバース ETL、CDC(変更データキャプチャ)にも対応し、データウェアハウスのインサイトと高度なデータ観測性を提供します。このノーコードデータパイプラインプラットフォームは、キルセットは限定的に必要ですがデータエンジニアリングの知識はほとんど必要ないため、トランザクションデータベースやリレーショナルデータベースなどのデータソースから目的の場所にデータを移動するのにピッタリな方法です。

Integrate.ioのAmazon Redshift へのリアルタイムデータレプリケーションは、このプラットフォームの数ある機能の1つに過ぎません。ビジネスのユースケースにIntegrate.ioをお試しになりたい場合は、ぜひ今すぐデモをご予約下さい。