Redshift"を翻訳しました。Processing)のデータウェアハウスで、運用の簡単さと高いパフォーマンスを提供しています。Redshiftを使われているお客様もいます。Redshiftは業界標準のJDBC/ODBCドライバーのインタフェースを提供しているので、お客様は既存のBIツールや分析クエリをそのまま再利用することができます。いかなるデータ・モデルでも動かすことができます。Redshiftを使い込んでくると、自身のデータモデルがデータベース上で正しく分散され管理されているかを保証するために、そのアーキテクチャを考慮する必要がでてきます。Redshiftを使い込むとお客様が直面する最も一般的な課題を見ていって、それぞれにどの様に対処していくかの具体的なガイダンスをお伝えします。しこれらの課題に対処できれば、最適なパフォーマンスのクエリを実現でき、要求にあわせて効率てきにスケールすることができるはずです。Redshiftは列指向(カラムナ)のデータベースで、データを行毎にディスクに保存するのではなく列毎に保存し、行はカラム毎のストレージから実行時に取り出されます。このアーキテクチャは大量のカラムを持つテーブルの分析クエリに特に最適で、なぜなら多くのクエリは全ての列のいくつかにしかアクセスしないからです。RedshiftはクエリのSELECTやWHERE句に含まれる列のディスクブロックにのみアクセスすることができ、全てのテーブルデータを読む必要がありません。Guideの列圧縮タイプの選択をご覧ください)、それによって高い圧縮率を実現し、高い読み込みパフォーマンスを得られます。Redshiftではインデックスの作成や運用が必要ないとも言えます。全ての列は自身のインデックスのようなもので、データが保存されるための適切な構造になっています。Redshiftクラスタを利用するのはベストプラクティスではないですし、列圧縮を最適化した場合には高いパフォーマンス向上を体感できます。Utilityを使ってみましょう。COMPRESSIONコマンドを各表に使います。し、トランザクションを使って新しい表を元々のデータがある古い名前にリネームするSQLのスクリプトを生成してくれます。コンパウンドソートキーの第1カラムは圧縮すべきでなく、このツールではそれは圧縮されません。Redshiftは分散、シェアードナッシング型のデータベースアーキテクチャで、クラスタの各ノードはデータの一部分を保持しています。ノード間で均等に分散するか(デフォルト)、列の値に基いてノードに配置するかを決めます。とで、JOINの時のネットワーク越しのデータ転送量を最小化することができます。いったクエリにおいては列の値に基づいた分散をすることで非常に高いパフォーマンスが得られます。良い分散キーの選び方は、最適な分散スタイルの選択を含む、多くのAWSの記事でも話題になっています。Redshiftのブログ記事をご覧下さい。分散キーの各ユニークな値が、均等な回数、表内に現れること。Redshiftは同じ数のレコードをクラスタ内の各ノードに配置することができます。分散キーの列は他の表とのJOINによく使われること。この条件に当てはまりそうな列が多数あった場合は、最も大きい表とJOINするときに使われる列を選びます。偏った分散キーになってしまうと、各ノードでクエリの実行が均等にならず、CPUやメモリの要求もバラバラになり、究極的には最も遅いノードの実行速度までしかクエリが速くなりません。:もしも偏りが問題となっていたら、クラスタ内でノードのパフォーマンスが均等でない状況がよく見られます。クラスタ内のスライスとノードに配置されているかを見ることができます。偏った分散キーを持つ表を発見したら、高いカーディナリティと正規分布を持つ列に分散キーを変更することを検討しましょう。NAME>;新しい表にも再度table_inspector.sqlを実行してみて、データの偏りを分析します。分散キーに適したカラムがなければ、EVEN(均等)分散を利用した方が、単一ノードがホットスポットにならないので、良くなることがあります。ALLを使ってクラスタ内の全てのノードに表データを配置することもできます。Redshiftの表にはソートキー列を定義することができます。これは他のデータベースでいうところのインデックスに近い動きをしますが、それらのようにストレージ利用量の増加は発生しません(詳細はソートキーの選択をご覧ください)。ソートキーはWHERE句でもっとも頻繁に利用される列を指定して作られるべきです。いったクエリが実行されるか分かっているのであれば、コンパウンドソートキーを利用することでベストパフォーマンスを得られます;もしエンドユーザが異なるクエリーをバラバラに実行するのであれば、インターリーブドソートキーを利用してください。Redshiftデベロッパーガイドのチュートリアルを確認して、ソートされていない表にどう取り組むべきかを確認することができます。クエリーのアクティビティを基にソートキーを推奨してくれるGitHubにある管理スクリプトを活用することもできます。気をつけないといけないのは、ソートキーの利用時に関数を利用しないようにすることです。代わりにソートキーの列を直接比較するようにしてください。これはTIMESTAMP列をソートキーとして利用する場合によく現れることが分かっています。Redshiftもクエリーを計画する際に良い選択をするため、表やストアされたブロックの圧縮といった統計情報を必要とします(より詳細な情報はテーブルを分析するを御覧ください)。適切な統計情報が無い場合、オプティマイザーはどの表にアクセスするか、もしくはどのデータセットをジョインするかという選択で、次善のもしくは良くない選択をしてしまう可能性があります。RedshiftデベロッパーガイドのANALYZEコマンド履歴には、統計情報が無い、もしくは古くなった表を探すことを手伝うクエリーが掲載されています。Redshiftでは、データブロックが処理の最小単位です。行が削除もしくは更新された場合、それらは単純に論理的な削除(削除されたフラグが付く)が実行されますが、物理的にはディスクから消えません。UPDATEを実行すると新しいデータブロックが作成され、追記(アペンド)されます。これら両方のオペレーションは古いヴァージョンの行によってディスクを消費し続け、クエリーが表をスキャンする範囲にも残り続けます。この結果、表のストレージスペースは増加し、スキャン時の不要なディスクI/Oによりパフォーマンスは低下します。VACUUMコマンドはこの削除済の不要な領域を開放し、データをソート順に並べて格納し直します。Schemaが利用できます。TABLEを実行しつづける事ができます。複雑なクエリーを処理している途中で、中間のクエリー結果とテンポラリーブロック(ディスク)にストアする必要になる場合があります。これらテンポラリー表は圧縮されません。不必要なサイズをもつ列は必要以上のメモリとテンポラリーディスクスペースを消費し、これによりクエリーパフォーマンスに影響を与えます。詳細な情報は最小列サイズの使用をご覧ください。table_name;場合によっては、巨大なVARCHAR型列を保持する必要もあります。JSONの構成要素を表に保持して、JSON関数でクエリーしているようなケースです。しているクエリーに特別の注意を払ってください。エンドユーザがこれら巨大列をクエリーするが、JSON関数をこれらの列に適用していないようであれば、それらの列を、もとの表のプライマリーキー列とJSON列のみにした別表に移動しする事を検討してください。これら表の列が必要以上に長い場合は、ディープコピーを使って必要なサイズの幅をもった列で表を作りなおす必要があるでしょう。Management、ワークロード管理)というキューイングシステムを内蔵しています。最大で8つのキューまで定義をすることができ、それぞれのワークロードを分離し、各キューでの並列度(同時実行レベル)を必要なスループットに見合うように調整することができます。キューにアサインされたクエリ、もしくはユーザが極めて重い処理を実行し、他ユーザのクエリーがそのキュースロットが空くのを待つことになる場合があります。この間はクエリーを全て実行できておらず、これは並列度を増加させる必要性のサインです。管理スクリプトを使ってどのクエリーがキューイングされているかを判断する必要があります。wlm_apex.sqlで確認し、wlm_apex_hourly.sqlを使って1時間単位での利用履歴分析と突き合わせます。並列性の増加はより多くのクエリーを実行可能にしますが、一方で割当られたメモリ空間を共有しているためにクエリあたりのメモリが減少する(メモリ割当てを増やさない限り)という点には注意が必要です。並列性を増加させると、いくつかのクエリを実行するためにテンポラリーディスクへの書き出しが必要になる場合があります。この調整は次の課題で検討します。課題#7-ディスクベースのクエリークエリーがメモリ内で実行しきれない場合、実行計画の一部としてディスクベースのテンポラリストレージが必要になります。この追加のディスクI/Oはクエリーの速度を低下させますが、セッションあたりのメモリ量を増加させることでこれを調整することが可能です(より詳細な情報はWLMの動的なメモリ割りてをご確認ください)。q.query;ユーザの定義もしくはキュー割り当てのルールをベースに、選択したキューでクエリーが実行完了までにディスクへのI/Oを発生させないよう、メモリの割り当てを増加させることが可能です。セッションごとにWLM_QUERY_SLOT_COUNT(http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_wlm_query_slot_count.html)を増加させることが可能で、デフォルトである1からキューでの最大並列度数まで調整可能です。課題#6に示したように、これはクエリをキューイングさせます、つまり使用には注意が必要です。Redshiftはトランザクション処理のクエリーよりも、分析クエリー用にデザインされています。相対的に見てCOMMITのコストは高く、必要以上にCOMMITを実行することは、コミットキューへのアクセスをウエイトさせることになります。データベースで必要以上にCOMMITを実行した場合、コミットキューでのウエイトが増加し始めます。管理スクリプトで確認することができます。このスクリプトは過去2日間での最長のキュー長と、クエリ時間を表示します。コミットキューをウエイトするクエリーがあった場合は、何度もCOMMITを実行しているセッション、例えばETLジョブで処理経過をロギングしたり、非効率的なをデータロード(次項も参照)を行っているといったセッションを探しあててください。Redshiftのベストプラクティスでは、データロードにCOPYコマンドを利用する事を推奨しています。HDFS、もしくはSSH接続からパラレルにデータロードするために使用します。RedshiftはGZIPとLZO圧縮をサポートしています(訳注:元記事執筆後にBZIP2サポートの追加も発表されました)。1つの巨大ファイルをロードするより、小さく分割されたファイルをロードする方が効率的であり、そのファイル数はスライス数に等しいのが理想的です。ノードあたりいくつスライスがあるかは、クラスターのノード種別によって異なります。DS1.xlargeコンピュートノードは2つのスライスを持ち、DS1.8xlargeコンピュートノードは16スライスを持っています。ファイル数をスライスの整数倍にすることで、COPYコマンドはクラスターリソースを平等に使い切ることができ、COPYの完了が最も早くなります。Redshiftに一行づつ、もしくは最大16MBまで可能なマルチバリューINSERTステートメントによって一度にデータをインサートしようとすることです。これはリーダーノードで処理されるオペレーションであり、リーダーノードのCPUやメモリを最大限まで利用することで、大きなパフォーマンスボトルネックを作成してしまいます。Redshiftではテンポラリ表を利用可能です。これは、通常の表と同じですが、同セッションの中でのみアクセス可能であるという点が異なります。ユーザがセッションの接続を解除すると表は自動的に削除されます。#TEMP_TABLEとクエリすることで作成できます。TABLEステートメントはテンポラリ表を作成する際の定義を全てコントロールできます。...)は、入力データを基に列名や列サイズ、データ型を決定し、データ格納のプロパティはデフォルトを使用します。デフォルトのデータ格納のプロパティは良く検討して利用しないと、問題を引き起こす場合があります。Redshiftのデフォルトの表定義はEVENディストリビューションを使用し、列のエンコーディング(圧縮)は無しです。INTOシンタックスを使う場合はエンコーディングや、ディストリビューション、ソートキーを指定出来ないということです。INTOクエリは、CREATEステートメントに置き換える事が強く推奨されます。変更することで、テンポラリ表の列にエンコーディング(圧縮)がセットでき、ディストリビューションの変更は、ワークフロー上の他の要素にも連鎖的な影響を与えます。Redshiftの列指向のアドバンテージを得ることが可能になります。オプティマイザのアラートを利用する最後のTipは、クエリー実行時の診断情報を利用することです。この情報は大変使いやすいSTL_ALERT_EVENT_LOGビューに格納されています。管理スクリプトを利用することで、過去7日間でクラスターに発生した問題を診断することができます。これはみなさんのクラスターがこれまでどのように使われてきたのかを理解する大変有用なリソースです。Redshiftはパワフルで、フルマネージドなデータウェアハウスであり、高いパフォーマンス拡張と、低いコストをクラウド上で提供します。Redshiftは多様なデータモデルを分析できるだけでなく、データがどう格納され管理されているかに注意することで、パフォーマンス低下やコスト上昇といった落とし穴を避けることが可能です。一般的な課題用の診断クエリを実行し、可能な限りベストのパフォーマンスが得られるようにしてください。ご質問やご意見がありましたら、コメントを残してください。Facebookこのブログの最新情報はTwitter、Facebookでもお知らせしています。お気軽にフォローください。