Amazon Redshift について。 使い勝手について使い勝手は、RDS と EMR の間に位置しますが、RDS 寄りです。手間のかからなさは RDS のマネージド環境とよく似ていますし、常時稼働している環境に対してのクエリも、普通の DB として発行できます。I/O S3 をフルに活用するところは EMR の感覚です。 基本的な内部構成マルチノード構成のクラスタとして動作する、パラレルクエリ DB です。カラム型 DB であることとあわせて、集約処理が高速に行えます。 アーキテクチャ等については、右記。 ∥ Amazon Redshift System Overview - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/c_redshift_system_overview.html クラスタは、リーダーノードと、コンピュートノードからなります。リーダーが DB システムの上モノのレイヤ(パースや実行計画の作成等)を担い、下まわりのストレージ等はコンピュートノードの機能です。 ∥ Data warehouse system architecture - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/c_high_level_system_architecture.html 不思議なんですが、実行計画が C++ で書かれていて、それをコンパイルしたものがコンピュートノードで実行され、キャッシュもされるらしいんです。 ∥ Client requests and execution - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/c_client_requests_exec_plans_code_gen_execution.html インデックスがありません。かわりに、ソートキーを用いて、データ自体をソートされた状態で保持します。追加 INSERT されたデータは、追加されたデータの単位でソートされます。保存単位の「ブロック」には、メタ情報として、そのブロックに含まれるデータの下限・上限が記録されるので、不要なブロックアクセスを回避し、高速化することが可能です。メンテナンスコマンドで、完全に再ソートすることもできますが、たまにで良さそうです。 ノード間へのデータの分散には、分散キーを用います。JOIN するデータどうしが分散されないように気をつけなければなりませんが、うまく設計できれば、高速な処理ができます。 性能確認今回利用したインスタンス構成は、XL x 2 です。これは、スケーラブルな最少の構成となります(テスト用の 1 インスタンス構成は、リサイズができない)。ノードを増やしたり、インスタンスを 8XL にすることで、より高速・高性能が期待できます。 今回使ったスキーマは、以下です。店舗が別なデータはお互いに関係ない(結合される予定がない)ので、店舗コードを分散キーに指定します(DISTKEY)。処理的に、日付順に並んでいる方が都合が良いと想定して日付順にソートし、その中ではさらに店舗コードでソートするようにしています(DISTKEY, SORTKEY)。 CREATE TABLE sales ( shop_id integer, -- グループ ID(店舗の ID を想定、ランダムな並び) create_time timestamp, -- 時刻(年月日、時分秒、昇順) test1 text, -- ランダム文字列(10 文字) * 以降 20 カラム test2 text, test3 text, test4 text, test5 text, test6 text, test7 text, test8 text, test9 text, test10 text, test11 text, test12 text, test13 text, test14 text, test15 text, test16 text, test17 text, test18 text, test19 text, test20 text ) DISTKEY (shop_id) SORTKEY (create_time, shop_id) ; Redshift は、パラレルにロードを行うことができるので、S3 上に、分割された CSV としてファイルを配置しておくと高速なロードが可能です。今回のテストデータは、1 ファイルが 1,000,000 件で、CSV としては 234MB ほどのファイルを 10 個、COPY コマンドで並列にロードします。総計、10,000,000 件(1,000 万件)、CSV で 2.28GB ほどのデータになります。 上記のとおり、入力のスプリットは自前でする必要があります。 ∥ Splitting your data into multiple files - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/t_splitting-data-files.html ロード性能COPY コマンドによる、S3 からのパラレルロードを行う。 # 5,000,000 件 1GB ちょいの CSV で 90 秒とちょっと。RDBMS であれば、SSD には負けそうだけれど、SAS HDD を 10~20 個くらい RAID0 にするとどっこいくらいか? 10,000,000 件 2.28GB のロード(統計情報アップデート有りのオプション付き)に 210~300 秒 = 4~5 分程度。 この状態では VACUUM をしていないからフルにソートはされていないが、ロードした単位内ではソートされている。ブロックには min と max のメタ情報がついた一種のレンジパーティションになっているため、実用上はこれで充分だと思われる。たとえば週に一回くらいのペースで、要所だけ VACUUM SORT ONLY を、月に一回程度のメンテ時間を取って、フルに VACUUM をするくらいが、パフォーマンス的には良いのではないかと思われる。COPY sales FROM 's3://~/split-data.csv' CREDENTIALS 'aws_access_key_id=~;aws_secret_access_key=~' DELIMITER ',' STATUPDATE TRUE; 複製同一定義のテーブルへの丸コピーを行う。サイズは先の 10,000,000 件で 75 秒。ANALYZE に 15 秒。 insert into sales_hist (select * from sales); 結合先ほど複製した 10,000,000 件のデータの簡単な結合。本来、このような全カラムを舐めるようなクエリは不得手なはずではあるし、あまり良い使い方ではない。それでも 135 秒ほど。ANALYZE に 18 秒ほど。 抽出日付でソートキーを指定しているので、日付抽出は速い。下記は結果が 172,800 件で 11 秒。 insert into sales_tmp2 (select * from sales where '2013-07-01' <= create_time and create_time < '2013-07-02'); 単純な S3 への Unloadさきほどの、ロードに 4~5 分のデータの単純な Unload に、120~140 秒ほどなので、2 分半ほどを要する。ロードと違って単純に出力するだけなので、アンロードの方が速い。当然のことながら内部での I/O に比べれば遅いので、利用回数は少なくしたい。 機能面で気になったところ次に、機能面について。 文字コードCHAR 型は 8 ビット文字しか扱えないので、日本語等のマルチバイト文字を扱うには VARCHAR 型(CHARACTER VARYING)を使います。エンコーディングは UTF-8 限定で、外部・内部でのエンコーディングの変換はありません(UTF-8 と干渉しない ISO-2022-JP ならば入れられます。EUC-JP や SJIS は干渉するので、INSERT の際にエラーになります)。 ∥ Multi-byte character load errors - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/multi-byte-character-load-errors.html 長さ無指定時のデフォルトは VARCHAR VARYING (256))を使う必要がある。外部表現、内部表現ともに UTF-8 で良いようなので、上限バイト数には注意する必要がある。"text" も、varchar(256) のエイリアスである。 面倒であれば、長さには "max" を指定のこと。 ∥ Character types - Amazon Redshift 使いこなしTips。 upsert のしかた (UPDATE OR INSERT や INSERT OR REPLACE に相当)クエリとして、UPDATE OR INSERT はないので、2 段階のステップを踏む必要がある。 まず、UPDATE して、
次に、INSERT をする。
実際にやるときは、WHERE 句に DISTKEY も必要となる。 ∥ Updating and inserting new data - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/t_updating-inserting-using-staging-tables-.html ウィンドウ関数Redshift のフロント側は PostgreSQL 8.1 あたりに相当するのだが、ウィンドウ関数などの、集計・解析に有用な機能は、9.* 系からバックポートされている。 以下の例は、"07/17" の行に、"07/16" 以降の最多で 3 つ遡った在庫の平均を入れて行くクエリ。従来であれば、プログラム側でやるか、ストアドでも併用しなければできないはず。
できました。 distkey での分割 Unload当然のことながら、一時テーブルを作成してから店舗に分けて unload する方が、生成しつつ店舗ごとに unload するよりも速い。 いかんせん、unload 機能がシンプルすぎて良くない。Hive で言う、パーティショニングされたテーブルを、パーティショニングを保持したままの S3 上の外部表現のまま出力する機能が欲しいのだが、これが無い。prepared statement で unload は使えないし(select 文しか使えない)で、下記のような一連のスクリプトを作成し、select into でテンポラリを作成して、以下のようにやってみた。
並列化が効かないので、能率は悪い。所用時間は、ダメですね、一向に終わりません。 素直に ORDER BY shop_id して出力し、呼び出し側で分割すべきだろう。ノード間のデータ移動は、マージソートになるから重くはないだろうし、呼び出し側での処理も簡単だ。 COPY のエラースキーマに合致しないエラーに限らず、COPY コマンドによるロード時のエラーの詳細はログ用のシステムテーブル「STL_LOAD_ERRORS」に蓄積され、失敗の回数が COPY コマンドのオプション MAXERROR で指定された数を越えるまではロード自体は失敗せずに続行します。 Troubleshooting data loads - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/t_Troubleshooting_load_errors.html COPY - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/r_COPY.html COPY 時の重複Redshift にはプライマリキーも一意制約もありませんので(あるにはあるのですが、実行計画策定時の参考程度にしか使われないらしいですので)、重複して入ります。分析系ですので、単純な追記を主に考えているようです。 Defining constraints - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/t_Defining_constraints.html いわゆる「UPDATE OR INSERT」については、「upsert のしかた」のところで触れています。この方法が、Redshift においては定石パターンとして文書に書かれています。 運用・メンテナンスログなどで、一定期間で drop したいデータ日付順のデータ(とりわけ、保持期間があるログのようなデータ)には、単位時間ごとに分けてロードしたテーブルの、UNION によるビューを検討せよとある。 ∥ Using time-series tables - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-time-series-tables.htmlcreate table や truncate 直後の COPY によるロードでは、ユニット単位でソートして突っ込むから、完全にソートされている。その意味でも、日次等でロードしたデータの UNION は高速 ∥ Using a COPY command to load data - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/c_best-practices-use-copy.html 定期メンテナンスコマンドいわゆる autovacuum のような機能は無いが、OLTP 向けの DB ではないので問題にはならないかと思われる。頻繁に DELETE するような使い方に問題がある。 ∥ Vacuuming tables - Amazon Redshift http://docs.aws.amazon.com/redshift/latest/dg/t_Reclaiming_storage_space202.html リンクリンク各種。
|
AWS >