NIKKEI Digital Recruiting Site

Redshiftを数百人で使うためのコツ(クラスター構成編)

日経ではアクセスログ、所謂クリックストリームデータを用途に合わせた複数のデータベースに格納し、サービス開発やマーケティングに携わる社員が自身でデータ分析ができるよう、セルフサービス化を進めています。

セルフサービス化を進めている背景として、データの集計や分析のニーズは日々増え続ける一方で、アナリストやデータサイエンティストのリソースはオンデマンドに増やせないため、いかにしてデータのアウトプットをスケールさせるかという課題があります。この課題に対するソリューションとして、データ専門チームの設立やオフショアのような人のリソースを拡張する施策に加え、ツールの整備と教育によるセルフサービス化に力を入れています。

今日はあまり使われていない

データの集計や分析のセルフサービス化において、特に大きな課題がクエリーの負荷です。現在、およそ 200 人が BI ツールにログインして Redshift でクエリーを実行できる権限を保有しています。これらの多数のユーザーが実行するアドホックで 無茶 なクエリーと、マーケティング施策や経営層向けのレポートのようなミッションクリティカルな処理、アナリストやデータサイエンティストが実行する複雑な処理を共存させるために実践していることを紹介します。

クラスター構成

現在のクラスタは ds2.xlarge の 14 台構成です。

ワークロードの傾向として、Redshift への書き込みはログデータを半リアルタイム(この場合逐次処理という意味であってレイテンシーの短さの意味ではない)にCOPYコマンドで S3 からロードするか、各種マスターデータを毎時や毎日の頻度でロードするのみです。一方、読み出しはバッチ処理とアドホックなクエリーが頻繁に流れる状態で、そのスキャン範囲も結果の大きさも様々、頻度もほぼランダムに不特定多数実行されています。

こういった read heavy なワークロードに対応するため、ノード当たりのサイズよりもノードの台数を優先し、処理の分散性を高めることでパフォーマンス上の効果が期待できるため、現在の構成になっています。

また、現在の台数は処理性能のための台数ではなく、あくまでストレージ容量のための台数と言えます。性能的には 6 台でも用途に対しては十分な速度でしたが、ds2.xlarge の 2TB の HDD は 6 台で 12TB となり、増え続けるデータとスワップ発生に対して心許なく、現在の 14 台に至りました。

※ Redshift の他に、Elasticsearch に同数のデータを、Aurora (MySQL5.7 互換)に利用頻度の高いデータマートを、インメモリ型の RDB にリアルタイムデータを格納しており、Redshift に対して処理速度を求めないため現在の構成でも速度面の不満が少ない状態です。

WLM 設定

前置きが長くなりましたが、このような環境で数百人がランダムにクエリーを流せるような「Data Democratization」を実現するために、Redshift の WLM(Work Load Management)の設定を活用しています。

WLM はクエリーを一定の条件でキューに分類するものなので、利用者や処理内容によってリソース配分を制御します。自動実行されるバッチ処理と BI ツールから手動で実行されるクエリーでは、前者は処理に時間がかかっても許容でき、後者はなるべく早く結果を返したいということもありますし、アナリストと非アナリストでもクエリーの優先度に差を付けたいケースがあります。

キューの分類

同時実行数とメモリ配分、そしてタイムアウトの設定を適用する単位「キュー」は、クエリー元の特性と期待されることに応じた分類をしています。

  1. データのロードやデータの品質に関わるクエリー
  2. ダッシュボード、レポーティングツールのようなバッチ処理から来るクエリー
  3. アナリストやデータサイエンティストがアドホックに実行するクエリー
  4. 一般ユーザーが BI ツールを通じて流すクエリー

1〜2 については、データを受け取るのがツールなのでレスポンスの早さはあまり重要ではありませんが、確実に完了することが期待されます。 3 については複雑なクエリーが多く、レスポンスの早さが業務効率と密接に関わるため、パフォーマンスが重要で、やはり確実な完了が期待されます。 4 についてが難しく、クエリーの複雑さやスキャン範囲は予測不可能で、クエリーの多い時間帯も一貫性はありません。しかしデータ活用を促進するためには自由に使える状態にしておく必要があります。

タイムアウト

タイムアウト設定は一般ユーザー向けのキューのみ 30 分(1800000ms)に設定しています。その他のキューにはタイムアウトは設定していません。

同時実行数

クラスター全体でのクエリーの同時実行数(= WLM の個々のキューの同時実行数の合計)を 25 以下になるようにしています。実際には利用状況を見ながら、数ヶ月に 1 回の頻度で WLM を更新しているので一定ではありませんが、18〜24 の範囲内で推移させています。

  • AWS によるベストプラクティスの解説では、クエリーの同時実行数は「25」を越えたところから性能が並列度と速度のバランスがくずれるという言及がある
  • 後述の SQA を有効化するには同時実行数が 15 以下を推奨(UI では強制)されており、SQA を利用する上では同時実行数は少ない方が有利と思われる
  • キューに対するメモリ配分を、そのキューの同時実行数で割ったものがクエリー 1 件が利用できるメモリ容量であることから、現在のクラスターサイズでは均等配分でおよそ 17GB がクエリー 1 件が利用できる計算。過去の経験値から最低でも 5GB を割り当てられるようにしたい

メモリ配分

クラスター全体で 434GB ですが、このメモリ容量はキューごとに配分され、さらにキュー内の同時実行数で割られます。クエリーの処理中にスワップが発生すると、ストレージに HDD を用いるノードではパフォーマンスが大きく低下するため、クエリーあたりのメモリ割り当てはスワップが発生しない程度に確保します。

  • データのロードや、比較的最近の範囲に関してデータマートを生成する処理ではメモリ要求が低め
  • 一般ユーザーが流すクエリーは予測が難しく、メモリは多めに割り当てたいが占有させるほどではない
  • アナリストが流すクエリーは WITH 句やネストを含み、一時テーブルが生成されることが多いためクエリーあたりのメモリ割り当ては多めにしたい

SQA(Short Query Acceleration)

2017 年 11 月にリリースされた「Short Query Acceleration」は、AWS の告知にあるように、機械学習を用いて頻繁に実行される軽い処理を既存のキューの外側で捌く仕組みです。

SQA を有効化することで、定期的な処理が従来のキューに入らないため、キューの空きを待つようなことが減りました。特にダッシュボードのように同じクエリーを頻繁に流すようなものは速度改善が見られました。(同時期にアナウンスされているクエリーキャッシュの効果もありました)

  • 全般的に重い処理が多いので「ショートクエリの最大実行時間」を最大値である 20 秒に設定しています
  • AWS コンソールでは、SQA の有効化には同時実行数の合計が 15 以内であることが必須になっているため、CLI を用いて WLM 設定を更新することで、同時実行数 25 と SQA 有効化を共存させています

WLM の更新は CLI では以下のようなコマンドですが、最近は SDK を使って Python から叩くようにして WLM の記述を楽にしています。

aws redshift modify-cluster-parameter-group --parameter-group-name atlas --parameters '[]'

実際の設定値と WLM 計算シート

以上のようなことを踏まえ、日々調整を重ねつつ現在の WLM 設定は以下のようになっています。

キュー ユーザーグループ タイムアウト(min) 同時実行数 メモリ(%) メモ
1 batches 0 6 24 通常のバッチ処理
2 analysts 0 3 20 データ部門のアナリストならびにデータサイエンティスト
3 viewer 30 8 38 一般ユーザー
4 integrations 0 6 16 サードパーティのダッシュボードツール等
5 long_batch 0 1 1 テーブル変更等の長時間動かし続ける処理
デフォルト 0 1 1 マスターユーザー他

この WLM はクラスターの構成によって実質扱えるメモリー量が変わるため、Excel で計算しながら検討することもあります。

WLM計算シート

補足

  • 200 人がクエリーできる権限を持っていても、常に同時にクエリーするわけではないので、Redshift そのものの同時実行数を 200 にする必要はありません
  • この先、同時実行数の増加が必要になる場合への対処法として、Athena や Spectrum が候補となっています。既に S3 に Parquet 形式でデータを書き出しているため、必要に応じて即展開できるようにしています。(Redshift クラスタを並列させることも考えていますが倍のコストを正当化できるバリューは見込めない)
  • BI ツールが持つクエリーキャッシュの効果や、Aurora に作るデータマートで多くの用途がカバーできるため、Redshift へのクエリー頻度は必ずしも増え続けるわけではありません
  • Elasticsearch やインメモリ DB も併用しているため、リアルタイム性の高い情報やカラム定義をしていない情報は Redshift の外で利用しており、クエリーは分散しています

まとめ

長くなりましたが、この記事のまとめとしては:

  1. 「誰がどういう目的でクエリーするか」「レスポンス速度の期待値はどれくらいか」でキューを分ける
  2. 「メモリ要求はどれくらいか」でキューに対するメモリ割り当てと同時実行数を決める
  3. 同時実行数は 25 以下を目指す(過剰に並列させると時間あたりの処理量は下がる)
  4. SQA を有効化する
  5. データマートの作成、クエリーキャッシュ、適材適所の DB 選択も併せて考える
佐野玄
ENGINEER佐野玄

Entry

各種エントリーはこちらから

キャリア採用
Entry
新卒採用
Entry