Medley Developer Blog

株式会社メドレーのエンジニア・デザイナーによるブログです

データウェアハウスとして使うAmazon Redshiftについて

はじめに

こんにちは。開発本部の阪本です。

今回は私が社内勉強会(TechLunch)にてAmazon Redshift(以下Redshift)についてお話した内容を紹介させていただきます。

Redshiftとは

概要

f:id:medley_inc:20190701165024p:plain RedshiftとはAWSサービスが提供しているデータウェアハウスで、高可用/高パフォーマンス/柔軟なスケーラビリティを実現しているのが特徴です。

競合としてはBigQueryHadoop、また同じAWSサービスではAmazon Athenaも同様の位置付けになると思います。

データベースとしての特徴

Redshiftの特徴として、列志向型データベースという点があります。

MySQLのようなリレーショナルデータベースはデータを行(レコード)単位で保持している事に対し、Redshiftは列単位で保持しています。

f:id:medley_inc:20190701165052p:plainf:id:medley_inc:20190701165052p:plain 列単位でデータを持っているため集計クエリのような特定の列に対して大量の行を精査するのが高速である反面、行を特定してのアクセスはMySQLPostgreSQLのような行志向のデータベースに比べてのクエリに比べて遅い傾向にあります。

またデータにはSQLでアクセスすることができ、構文もPostgreSQLと互換性があります。 最近スキーマレスなデータベースなどが多く出てきていますが、Redshiftは事前にテーブルを作成する必要のある従来型のRDBMSの形となっており、テーブル作成時はCREATE TABLEといったデータ定義言語(DDL)を使うことになります。

機能面の特徴

f:id:medley_inc:20190701165113p:plain:w350 先にも書きましたが、データアクセス時に使うSQLPostgreSQLの構文と互換性があります。

よってPostgreSQL用ドライバ(JDBC含む)さえ使えれば、後は特別に意識することなくRedshiftに対して接続やクエリ発行が行えるということになります。

この恩恵はプログラムだけではなく他社が展開しているサービスにも受けることができ、BIツールのTableauRedashなどもそのままデータソースとして利用することが出来ます。

次に、一般的なRDBMSとの差についてです。 RDBMSにはありRedshiftには無いものとしては - UNIQUE制約 - 外部キー制約 - インデックスが無い

などがあります。

インデックスに関しては遠い意味での代用品(Sort Key)があるものの、基本的には使うことが出来ません。 注意点としてクエリ自体はPostgreSQL互換なのでこれらを作るDDL構文を受け入れてくれるますが、Redshiftでは無視されますのでご注意ください。

逆に、Redshift固有のものとしては - Sort Key - 分散キー - 列圧縮

などがあります。 これらについては以下で少し掘り下げて説明します。

Sort Key

テーブルをソートする際に使うインデックスのようなものです。 列単位で指定することができ、ORDER BYGROUP BY句などの精査速度に影響します。

分散キー

MySQLでいうパーティショニングキーに近いものとなります。

Redshiftのデータ分散方法は - 均等に分散 - キー値による分散 - 全コピー - Auto(負荷状況による自動選択)

の4つで、データ量や特性によって使い分けることが出来ます。

分散キーはRedshiftを上記の方法でクラスタリングした際に、どのノードにどのデータを保持するかを決定する判断材料となるキーです。

運用面の特徴

AWSコンソール

f:id:medley_inc:20190701165138p:plain RedshiftはAWSコンソール上からも詳細な情報を確認することが出来ます。

f:id:medley_inc:20190701165201p:plain Amazon RDSにあるような一般的なメトリクスに加えてクエリ単位での実行状況や実行計画、そしてクエリの強制停止もコンソールから実行することができます。

データ取り込み

Redshiftはインポート元となるデータ取り込み選択肢が豊富ということも特徴の一つです。

取り込み可能な形式

CSV/JSON/AVRO/PARQUET/ORC + これらの形式を圧縮したもの(BZIP,GZIPなど)

読み取り元

Amazon S3/Amazon EMR/Amazon DynamoDBなど

特にデータ配置元としてS3がサポートされているので、各種サービスが出力するログや、Amazon CloudWatch LogsからのS3やAmazon Kinesis Data FirehoseからのS3・・など、組み合わせ次第で可能性がとても広がります。

またS3に配置しているデータはインポートせずに外部テーブルとして直接クエリを実行する機能Amazon Redshift Spectrumがあります。データ量がとても多い場合などにはこちらを利用するのも有効な手段です。

ワークロード管理

f:id:medley_inc:20190701165215p:plain 負荷に関する運用についてはWLM(Work Load Management)という機能があります。

これはRedshiftに接続するユーザをグループ単位で負荷制御を行うことが出来る機能です。

制御できる項目としては

並列クエリ実行数

同一グループ内でのクエリ同時実行数。上限に達すると待ち行列に入って詰まる。

クエリ実行時間

クエリ実行時間の上限。

メモリ使用量

クエリ実行時に使うメモリ使用量の上限。

などがあります。

可用性について

Redshiftはクラスタリングをサポートしており、クラスタにはクエリの待受を行うリーダー(Leader)ノードと実処理を行うコンピューティングノードが作成されます。

AWSも推奨しているように、Redshiftはマルチノード運用を基本としています。

これはRedshiftの個々のデータノードはRAID5のような形で各ノードに分散しているため、ノード障害が発生した場合でも生存ノードからノード復旧を自動で行ってくれます。 (同時に障害が発生しても復旧可能なノード数については、クラスタ内のノード数に依存します)

将来性について

過去1年半の間でもこれだけの新機能が追加されており、まだまだ進化しています。

  • UNLOADコマンドのCSV対応
  • Concurrency Scaling
  • ALTER文でVARCHARの桁数変更
  • Elastic Resize
  • UNLOADコマンドのヘッダ行出力対応
  • コンソールにてクエリ実行環境追加
  • ネスト化されたデータのサポート
  • 自動バージョンアップ方式の設定/予告確認可能
  • Parquet、ORCからのIMPORTサポート
  • Amazon Redshift Spectrum東京サポート
  • 新ノードタイプDC2
  • Query Editorの追加
  • PL/SQL プロシージャのサポート
  • Vacumコマンドの自動化 New!!(2018/12リリース)
  • WLMワークロード管理の自動化 New!!(2019/06リリース)

実際の使い勝手

では、実際のところRedshiftの使い勝手がどういったものなのかを実例を含めて紹介します。 ここではdc2.large ノード数2のサンプル環境を使用します。

データのロード

クエリを発行するにも、まずは元になるデータが必要です。

ここでは日本語Wikipediaの目次ダンプデータを100セット分用意し、その内容をRedshiftにロードしてみます。

f:id:medley_inc:20190701165252p:plain f:id:medley_inc:20190701165257p:plain まずは目次データをこちらの画像の様に加工し、100セット分のファイルとして分割しS3へとアップロードします。

f:id:medley_inc:20190701165317p:plain 今回のロードするデータ量は235,732,000レコードの11.9GBとなりました。

f:id:medley_inc:20190701165331p:plain S3にファイルが配置出来たら、それを格納するテーブルをRedshiftに作ります。 この際PostgreSQLCREATE TABLEによってテーブルを作成します。

f:id:medley_inc:20190701165355p:plain テーブルの作成が完了したら、次はデータのロードです。 これもSQLクエリのCOPYコマンドによって取り込みが行われます。 今回このロード処理は8分55秒で完了しました。

データ量から考えるとかなり早いと感じますが、これはロード処理において並列処理の恩恵を最大限に受けているということが理由と考えられます。

Redshiftのロード処理は分割されたファイルを使って並列処理を実行するため、巨大な単一ファイルを取り込むより短時間で取り込むことができます。

クエリ発行

次に、クエリ発行についてですが、これはそのままPostgreSQLのクエリを実行することになります。

今回は先のステップで取り込んだ目次ページをタイトルごとにDISTINCTする集計クエリを発行してみます。

f:id:medley_inc:20190701165409p:plain すると49秒で結果が帰ってきました。 最低限のスペックで235,732,000レコードを精査するクエリの実行時間としては良いスコアではないでしょうか。

不便に感じたこと

ここでは私がRedshiftを運用していて不便に感じた事をいくつか紹介します。

料金が高い

これだけの機能とスペックが含まれているので仕方が無いかもしれませんが、AWSの他のサービスと比較して高価な印象があります。

さらにマルチノードとなると料金が掛け算で増えることになり、スペックの選択肢が他のサービスと比べても少ないため運用の際にはよく見積もりされることをおすすめします。

更新クエリが遅い

列志向型のせいなのかランダムアクセスが苦手で、特定の行を探して更新するUPDATEDELETEは遅いです。

そもそもRedshiftは頻繁にUPDATE/DELETEする用途には向いておらず(後述)、INSERTのみの積み上げ型や全レコード洗い替えが基本の用途になります。

また、UPDATE/DELETEを繰り返すとパフォーマンスが低下します。

これは内部的に保持しているSortKeyの状態が更新するたびに劣化し、連動してパフォーマンスが低下するためです。

解消するためにはSortKeyの再構築(VACUM/OPTIMIZEコマンド)により回復しますが、そもそもコマンド実行時間が長く、負荷も大きいので実行タイミングは検討が必要となります。

(追記)2018/12のアップデートで自動実行機能が追加されました!

AWSコンソールが機能しないことがある

先に多くの便利な機能を紹介しましたが、なぜかこれらがAWSコンソール上で機能してくれないことが割とあります。

WLMの設定次第なのか不明ですが、実行中のクエリが出なかったりクエリの強制停止が効かないなど、イザという時に限って使えないことがよくありました。

メンテナンスが高頻度

新機能が続々追加されていると紹介していますが、この度にメンテナンスが発生するものとなります。

タイミングは事前に設定したメンテナンスウインドウの週一の曜日/時間帯ですが、経験から2週間に1度ぐらいの頻度で発生していました。

この時間帯は再起動を伴う場合もあるため、WriteどころかReadすら出来ない状態になることもあります。

そのため日中は社内業務。夜間はバッチでといった24時間ずっと稼働する要件を満たす事は少し厳しいものとなります。

まとめ

まとめととなりますが、Redshiftは特徴をふまえると下記のような場面で利用すれば良いかなと感じています。

BIツール等のデータソースとして

メンテ頻度や負荷の問題があるので、自分達のアプリから直接は繋げない。

履歴やマスタデータのような大量の積み上げ型データの集計

UPDATEが発生するなら、全件入れ替えが可能なデータ。

1日の利用頻度がそれなりにあること

頻度が高く無いのであれば、Athenaの方が安い。

どのサービスにも言えることですが、要件の合ったサービス選びをすることが一番大事です。

Redshiftについても特徴がはっきりしているタイプのサービスなので、使い所を間違えないように、上手く使っていければと思います。