【AWS Summit Tokyo 2018】 Amazon Redshiftの設計・運用大原則 レポート

AWS

2018.6.5

Topics

AWS Summit Tokyo 2018 で5月31日に行われた「Amazon Redshiftの設計・運用大原則」セッションに参加してきました。
セッションの内容を簡単に共有したいと思います。

セッション紹介と登壇者

仲谷 岳志
アマゾン ウェブ サービス ジャパン株式会社 プロフェッショナルサービス シニア・インフラストラクチャー・アーキテクト
Amazon Redshift は、高速で完全マネージド型のデータウェアハウス(DWH)です。Redshift により、DWH のローカルディスクに保存されたデータや、Amazon S3 上にある膨大な量の非構造化データに対して、簡単に分析クエリを実行することができます。本セッションでは、Redshift および S3 を活用してクラウド上にデータウェアハウスシステムを構築する上で、意識すべき設計と運用のポイントについてご説明します。
引用元:AWS Summit Tokyo 2018 セッション一覧

Redshiftをよりよく使うために

設計・運用要素の観点から押さえておくべき8の現場経験則が紹介されました。

Redshiftの設計・運用要素 8の現場経験則
クラスター構成 1.サイジングをちゃんとする
2.Spectrumのアーキ原則を押さえる
ロード 3.COPYの基本ルールを守る
4.ロード経路をセキュアにする
クエリー 5.同時実行要件に正しく対処する
6.クエリー特性を考慮する
ハウスキーピング 7.VACUUMを工夫する
8.更新処理を工夫する

 
では、8の現場経験則の詳細を見てみましょう。

1. サイジングをちゃんとする
 ①設計段階である程度シュアなサイジングを行う
  ・拡張/縮小は当然可能だが、ビックデータ特有の事情がある
 ②初期容量のみでサイジングしない
  ・増分、一時テーブルも考慮する(拡張目安は7割)
  ・クエリー性能(レスポンスタイム/スループット)を考慮する
 ③可能な場合は大きめのノードサイズを選択する
  ・リーダーノードのサイズはコンピュートノードに準ずる
 ※サイジングのアプローチ
  容量ベースのサイジングと性能ベースのサイジングの2つがある。
  要求キャパシティが大きい方を選択する。但し、見極めにはPoCが必須。

 

2.Spectrumのアーキ原則を押さえる
 ①パーティション、列指向ファイルフォーマットを活用する
  ・とにかく「読み取り量を減らす」
 ②データ量に応じたノードスライス数を用意する
  ・Spectrum層の処理能力は”親”となるRedshiftクラスターのサイズに依存
 ③データの持ち方を工夫する
  ・ファクトはS3、ディメンションはRedshift腹持ち
  ・ファクトの古いデータはS3、アクセス頻度の高い直近のデータは
   Redshiftとした上でLate Binding ViewでViewを作成、など

 

3.COPYの基本ルールを守る
 ①COPYで複数ファイルを並列ロードする
  ・COPYコマンド自体を多重実行しない
  ・ノードスライス数の倍数に揃える
  ・ファイルは圧縮し、ファイルサイズはそれぞれ数百MB〜1GBとする
 ②可能な場合は常にS3からロードする
 ③一意制約のRedshiftでの特性(重複は許容される)を理解する
 ④エラーハンドリングを実装する
 ※ロード時のありがちな問題
  ・一意性制約違反の行がロードされる
   ・Redshiftでは、一意制約は実行計画用途に使われるが、
    重複していてもロード時には止めない仕様
   ・一時テーブル経由でSELECT INSERTするなどの対応策が必要
  ・デリミター問題
   ・一般的なデリミターであるカンマがデータ内で使われるようなケース
   ・DELIMITERパラメータを駆使して対処
  ・テーブルとファイル間の不一致
   ・テーブルのデータ型と、ロード対象ファイル上の値の不一致
   ・テーブルのカラム数と、ロード対象ファイルのカラム数の不一致
   ・日付/時間のフォーマット不一致、など
 ※COPYコマンドのエラーハンドリング
  ・MAXERRORプロパティを指定することで、
   COPY時に許容するロードエラー件数を指定可能
   ・デフォルト0、最大100,000
  ・システムテーブルを使ってエラーが発生した値とカラムの詳細情報を調べることができる
   ・STL_LOAD_ERRORS
   ・STL_LOADERROR_DETAIL
  ・より簡単に一連の情報を取得するためには
   admin.v_my_last_copy_errorsを使う
      ex. select * from admin.v_my_last_copy_errors;
   参考:https://github.com/awslabs/amazon-redshift-utils

 

4.ロード経路をセキュアにする
 ①COPY元のS3にはVPCエンドポイント経由でアップロードする
  ・データ発生元がオンプレミスの場合はプロキシーEC2経由とする
  ・S3からRedshiftへのロードにもS3 VPCエンドポイントを使う
  ・経路上のEC2にはアクセスキーを置かずにロールを使う
 ②バケットポリシーとAWS ConfigでS3のパブリック化を防ぎ、
  かつGuardDutyで不正な漏出を検知する
 ※発見的統制の併用
  ・AWS Configによる監視 (https://aws.amazon.com/jp/config/)
   s3-bucket-public-read-prohibited、s3-bucket-public-write-prohibited、
   s3-bucket-logging-enabledなどでバケットが不用意に(あるいは意図的に)
   公開されていないか監視
  ・GuardDutyによる監視 (https://aws.amazon.com/jp/guardduty/)
   不審な大量アップロードが発生していないか監視

 

5.同時実行要件に正しく対処する
 ①実測する
  ・15という参考数値はあるがあくまで目安
  ・むやみにスロットを増やすとスループットが下がる可能性がある
  ・逆に15以上で問題ないケースもある
 ②「現行システム要件」の実態を見極める
  ・同時接続ユーザーが多い→同時にクエリーを投げているとは限らない
  ・バッチの同時実行数が多い→遅くて滞留しているだけかも知れない
 ③本当に多数の同時実行クエリー数が必要な場合は、スロット細分化以外の方法を考える
  ・多すぎるスロット数:同時実行可能クエリー数は増えるが個々のクエリー所要時間が
          伸びた結果、スループットが低下する
  ・適正なスロット数:割り当てメモリが増えた結果、クエリーあたりの実行時間が
         短くなりスループットが増加する
 ※データマートによるワークロード吸収
  ・数十を超えるアクセスは、一般に集計済みデータに対する定型クエリーが中心
  ・データマートで対応するのが常套手段
   実装例1:Redshiftで集計処理 > Redshiftからアンロード > ETLツール等で定期的にロード
   実装例2:DBLINKで接続 > マテリアライズドビューを作成 > 定期更新
 ※Spectrumによるワークロード吸収
  ・探索的クエリーが多数発生するケースではRedshift Spectrumを活用
   ・複数クラスターで同時実行クエリー数を稼ぐことが可能
   ・データを腹持ちしないためクラスターサイズを抑えられる

 

6.クエリー特性を考慮する
 ①スループット重視のバッチとレスポンス重視の対話クエリーはキューを分ける
 ②探索的クエリーなどのロングクエリー/ローグクエリーが想定される場合は
  クエリーモニタリングルールで予防線を張る
  ・他の実行を妨げるだけでなくリーダーノードにも悪影響が生じ得るため
 ③BIツールからの定型クエリーに対する備えをする
  ・機械が生成した長大なSQLが来る、同じクエリーが繰り返し来る、
   短いレスポンスタイムが要求される、などの特性に備える
 ※ロングクエリー(long runnning query):長時間実行され続けているクエリー
  ローグクエリー(rogue query):大量の結果セットを返すなど作法の悪いクエリー
 ※キューの使用シナリオ
  日中帯は数名~十数名のデータアナリストがアドホッククエリーを実施
  夜間帯は業務はほぼ行われず、日次バッチによるデータ取り込みが中心
  ・日中帯は対話クエリーキューにリソースを集中させる
  ・60秒を超えるロングクエリーは別のキューにホップ
  ・結果セットが100万行を超えるローグクエリーは別のキューにホップ
  ・夜間帯はバッチキューにリソースを集中させる
  ・動的な割り当て変更の代わりに、バッチクエリー内でset_wlm_slot_countステートメントを
   利用して、一時的に複数スロットをクエリーに割り当てる方法も可能
 ※結果キャッシュの活用
  一致したクエリーの結果セットを実行プロセスなしで返す機能
  ただし、SQLが完全一致した時に効く
  性能測定時はenable_result_cache_for_session = offで無効化しておく

 

7.VACUUMを工夫する
 ①VACUUMを実行しないで済むように設計する
  ・VACUUM不要なスキーマにする
   (ex. 日付をソートキーとしたINSERTのみのファクトテーブル)
  ・更新や削除を極力なくす
 ②それでも必要な場合は
  ・短くてもWeekly周期に留め、更新/削除量の少ないテーブル群はMonthly、
   Quarterlyなども検討する
  ・VACUUM FULLで実行する
  ・カラム数が数百に及ぶテーブルは、実行時に複数スロットを割り当てる
  ・VACUUMの代わりにディープコピーを使うことも考慮する
 ※ディープコピーによるVACUUMの代替
  ・VACUUMの代わりにCATSを用いるパターン
   ・更新や削除が多いテーブル、列数が多いテーブル、
    インターリーブドソートキーが含まれるテーブルなど
   ・手順は以下の通り
    ・CTASでワークテーブルを作成し、元テーブルの全データを投入
    ・テーブル名切り替え
    ・切り替え後は元テーブルを削除

 

8.更新処理を工夫する
 ①Redshiftは大容量データの集計・分析処理に最適化されており、
  ランダムな更新処理や一件ごとのループ処理には適さない
 ②更新自体を回避するパターン
  ・更新・削除が頻発するテーブルでは、テーブルを丸ごと入れ替える「洗い替え」を検討する
 ③更新を効率化するパターン
  ・一時テーブルを活用したUPSERT処理など、極力まとまった単位での更新方式を実装する
 ※洗い替えのパターン例(大容量マスター等)
  ・公開用テーブルと同一定義のワークテーブルを用意
  ・手順は以下の通り(トランザクション)
   ・ワークテーブル作成(従属するViewや制約があれば再作成)
   ・ワークテーブルへ最新世代の全件データをロード
   ・テーブル名切り替え(公開⇔ワーク)
    ALTER TABLE B RENAME TO B_TMP;
    ALTER TABLE A RENAME TO B;
    ALTER TABLE B_TMP RENAME TO A;
   ・切り替え後は元テーブルを削除
 ※一時テーブルを活用したUPSERT処理
  ・本番テーブルと同一定義の一時テーブルを作成し、1トランザクションで
   COPY+DELETE+INSERTを実行
  ・手順は以下の通り
   ・生成データを一時テーブルへロード(COPY)する
   ・本番テーブルから更新対象のレコードをDELETEする
    (DELETEの条件列をソートキーに設定しておくことを推奨)
   ・一時テーブルから本番テーブルへデータをロード(INSERT-SELECT)する

まとめ

日ごろAmazon Redshiftを使っていますが、現場経験からしか得られない貴重なお話が聴けてとても勉強になるセッションでした。

テックブログ新着情報のほか、AWSやGoogle Cloudに関するお役立ち情報を配信中!

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら