こんにちは。AI事業本部の AIR TRACK でサーバーサイドエンジニアをしている宮川です。プロダクトでデータウェアハウスを Redshift から Snowflake に乗り換えたので、意思決定をした理由や Snowflake のメリット・デメリットについてご紹介したいと思います。

Snowflake とは

 

Snowflake のロゴ

 

Snowflake とは Snowflake 社が提供するデータウェアハウス(DWH)です。 コンピュートノードとストレージを分離した設計がなされており、計算リソース(ウェアハウス)を簡単にスケールアップ・スケールアウトできること、ウェアハウスの利用分の従量課金であること*1が特徴となっています。また、各クラウドプロバイダー上でサービスを展開しているため、Snowflake にデータを入れる際に無駄なデータ転送量がかからないことも特徴です。

その他、SnowPipe という自動データロードの機能や、データクリーンルームという他のプロダクト・企業間での安全なデータの共有・分析を可能にする機能など、他の DWH にはない革新的な機能も提供されています。

*1 ウェアハウスの他にストレージ料金も従量課金で保持しているデータ量に応じて請求されます。

Snowflake に移行しようと思った理由

AIR TRACK での Redshift の用途

AIR TRACK では位置情報を使ったターゲティングや計測を行なっているため、大量の位置情報の保有および分析を日夜行っています。また、広告配信ということもあり大量の広告配信ログも保有しています。

特に位置情報データは簡単な前処理をした上で数千億行程度のレコードを保持していており、それ相応のスペックの DWH が必要不可欠です。

これらの課題を解決すべく AIR TRACK では Redshift の ds2 ファミリーのクラスターを運用してきました。

Redshift の苦戦ポイント

不定期に発生する計算負荷の高い集計処理が、容易にかつ低コストでスケールアウトしにくい という点でRedshift と相性が悪く、AIR TRACK ではコスト面や保守運用面で問題を抱えていました。

具体的には、データを運用する中で最も難易度の高い集計処理は、位置情報データをフルスキャンせざるを得ない計算負荷の高い集計処理です。そして、集計処理がビジネス的な要求により不定期に実行されることも難易度を高めている要因です。

そのため Redshift では、事前に計算リソースを用意する都合上、余剰にリソースを用意しておく必要がありコストがかさんでしまっていたという問題がありました。また、余剰にリソースを用意していても一部計算リソースが足りずに別の AWS リソースによる処理を行っていて、集計処理のタスク管理が煩雑という問題もありました。

Redshift でのクエリをチューニングしクラスターサイズを最適化したり、Redshift のオートスケーリングを利用したりという選択肢もありますが、リザーブドインスタンス(RI)を購入していた都合上、コスト最適化の面でリスクが高いと判断しました。

前者に関しては RI の契約中に要件が変わりクエリの最適化が効かなくなる変更リスクです。後者に関しては、RI が効かないクラスターでのインスタンス利用料金の増加リスクです。AWS から1日あたり1時間分のスケーリング用のクレジットが付与されるようですが、大幅にコストが増大するリスクを考え利用を見送ることにしました。(またこの問題は ra3 に移行しても解決できないと判断していました。)

Snowflake の検討

データウェアハウスによってスケールアップ・アウトしやすいという点が上記の Redshift の課題点を解決できるだろうと思い、Snowflake の検証を進めることに決めました。

その他の DWH の検討

Redshift と Snowflake 以外の対抗馬として Big Query がありますが、データ転送料がネックになること、Big Query Omni  は検討段階では利用することができなかったことを踏まえて候補からは外していました。

Snowflake の検証

上記の問題を解決すべく Snowflake の検証を行い Snowflake が適任であるという結論に至りました。 検証を行った際の論点は以下です。

  • クエリの実行速度は Redshift に比べて遜色ないのか
  • ウェアハウスという従量課金の仕組みによってコスト最適化ができるのか
  • 計算リソースが足りずに外部の AWS リソースを使っていた処理を統合することは可能か

結果としては、コストの最適化に関しては可能という結論*1になりました。クエリ速度に関しては、遜色はなくむしろ Snowflake の方が平均的に処理が早いような印象を受けました。最後の論点はウェアハウスが容易にスケールできる点から全く問題ないという結論にいたりました。

*1 Redshift で3年のリザーブドインスタンスを購入すれば同等のパフォーマンスになる試算でしたが、移り変わりの激しい昨今の広告業界で3年の固定費というリスクは取れないと判断しました。

クエリの実行速度は Redshift に比べて遜色ないのか

体感ですが、一部の位置情報データを用いた重いクエリを除いてむしろ Redshift より早くなりました。マイクロパーティションのおかげで勝手に Snowflake が最適化をしてくれてクエリのパフォーマンスがよいのだと思います。

ウェアハウスという従量課金の仕組みによってコスト最適化ができるのか

上述の通りクエリのパフォーマンスがよく従量課金の恩恵を受けることができ、コストの最適化が満足できました。また、無限に(厳密には無限と錯覚するほど高速に)ウェエアハウスがスケーリングしてくれるので、リソースが足りなくなるような事態は一度も出会ったことがありません。

計算リソースが足りずに外部の AWS リソースを使っていた処理を統合することは可能か

これまでに話に上がっているように満足にスケーリングしてくれるので、外部リソースを Snowflake に統合することは可能と判断しました。

 

これらの点を踏まえて、移行のための工数よりもコスト面・保守運用面でインパクトが大きいと判断し Redshift から Snowflake への移行を決断しました。

Snowflake に移行してどうだったのか

結論、移行して上記の課題は解決できており、移行から数ヶ月経ちますが今なお満足しています。後述のように課題は多少はありますが、大局的な目標は達成できました。

移行後に感じた Snowflake のメリット

Stage

Stage という機能を使うことによってクエリが簡単にかつ、大抵のケースでは十分なパフォーマンスで実行できて非常に便利です。

 

stage を使ったサンプルクエリ

 

Stage は S3 などのストレージにあるファイルに対してパーティションやデータ構造の定義なくクエリを実行できる機能です。json や csv の他、parquet なども解釈可能となっています。 パーティションがないためデータの探索範囲が大きくなるとパフォーマンスが悪くなりますが、アドホックな分析などのケースでは Stage で十分に事足りています。

また、insert into or copy into を使うことで Stage の参照しているストレージへのアンロードも可能です。

SnowPipe

SnowPipe はデータの継続的なロードを行ってくれる機能で、Fluentd などで収集し S3 上に置かれたログファイルなどを継続的に Snowflake 上のテーブルに取り込むことができて大変便利です。 具体的には以下のように xxx_pipe を定義することで、 xxx_stage という S3 上の csv ファイルから必要な情報を取り出し xxx_table というテーブルに継続的にデータを取り込んでくれます。

 

SnowPipe のサンプルクエリ

 

このクエリを叩くことで、裏側では Snowflake の AWS アカウント上に専用の SQS が作成され、S3 のファイル作成のイベントに発火して SQS にそのイベントのメッセージが送信され、SnowPipe がデータを取り込んでくれるという仕組みです。(詳細な S3 や IAM の設定方法、および他のクラウドプロバイダーでの設定方法は公式ドキュメントをご参照ください。)

また、copy into というステートメントは insert into とは違い一度読み込んだファイルは基本的には複数回読み込まないように設計されています。そのため冪等性があるのでより安全にデータの取り込みが可能です。(FORCE = TRUE というオプションをつけることで上書きも可能です。)

マイクロパーティション

Snowflake にはマイクロパーティションという機能があり、大抵のクエリは何も設定せずに高速に動作してくれます。

詳細な説明は省略しますが、マイクロパーティションの特徴上、created_atrequested_at などある一定期間で作成されるレコード間でデータが偏りやすいカラムは、恩恵を受けやすく非常に高い検索パフォーマンスを発揮してくれます。 一方で、ランダム性の高いカラムでは検索性能が低く、位置情報のカラムはこれの影響を受けやすいです。そのため、一部 clustering key を使った静的パーティションでクエリを最適化している部分もあります。

移行後に感じた Snowflake のデメリット

ほとんどデメリットは感じなかったのですが、もう少しよくなってくれると嬉しいポイントはあったのでまとめてみました。

スキャン量が大きいクエリでのパフォーマンス劣化

大量のデータを複雑に集計しないといけないクエリでは、Snowflake 内のデータ取得のネットワークレイテンシの影響なのかパフォーマンスが悪くなるケースがありました。 Snowflake では計算ノードとデータストレージが分離されているため、ストレージからのデータ取得のネットワークの部分がネックになってしまうのです。

重いクエリの実行計画

このクエリは、過去1年間に渋谷のスクランブル交差点に一定時間以上滞在したことがある人を抽出しようとしたクエリです。重複排除をいれたので distinct で重くなっていそうですが、それでもなおネットワーク IO がネックになっていることがわかります。

この点、 Redshift ではデータストレージと計算ノードを分離しないアーキテクチャでの運用も選択することができ、こういった重いクエリが常に実行されるようなユースケースでは Redshift に軍配が上がるように思いました。 特に、最初に問題視していた「位置情報データをフルスキャンせざるを得ない計算負荷の高い集計処理」に関しては、Redshift の方が良いパフォーマンスでした。

とはいえ、このような結果になってしまうクエリに関しては最適化に問題があり、今までは無理やり動かしていただけので、クエリの最適化(データ構造やクラスタリングキーなど)を今後はやっていこうと思います。

また、この集計処理が他の集計処理に影響を与えることがないのと、よほどのクエリでない限りは大幅にコストがかかることもなかったので、コストの最適化という大局的な目標は達成することができました。

SnowPipe のデバッグが難しい

よしなに Snowflake 側が自動ロードの部分を隠蔽してくれるので簡単に構築できる一方で、ブラックボックスになってしまい「どこまで処理がいったのか」「なぜデータを取り込めていないのか」といった調査が難しい印象を受けました。

SnowPipe の現在のステータスを取得するためのステートメントや、copy into の履歴を参照できるテーブルは存在していますが、どこにも失敗した理由が表示されないケースもあり動くまでに苦労することがありました。定義文を少しずつ変更することで問題の切り分けは可能ですが、もう少しデバッグしやすくなると嬉しいというのが正直なところです。

 

SnowPipe のデバッグ用のクエリ

 

移行の際に苦労したポイント

過去データの移行にも一苦労

当たり前ですが、どのタイミングから完全なデータが入っていて、いつまでは過去の Redshift のデータを入れないといけないのかを把握し、Redshift からデータをアンロードしそれをインサートしてという手順を毎回踏む必要があります。 データが多いレコードではアンロードだけで1日を要したり、失敗するとビジネスに悪影響が出る可能性があったりと、精神的な負担がかなりかかる作業でした。

移行完了の定義が難しい

移行以前とデータの件数が一致すれば完了なのか、どの程度の精度の乖離まで許容するのか、何と何を比較した値が一致していれば完了なのか、ということを都度議論する必要がありました。

また、一致しないデータ郡はどういう特徴を持っているのか、どれぐらいの行が新旧で一致しているのか、といった問題の切り分けを行い、クエリの移行ミスをしている部分を洗い出して修正を行い、また精度の調査からして、という繰り返しです。 時には、過去のクエリにミスが発覚して現在のクエリの方が正しいという結論に至ったり、計算精度の向上で今まで集計できていなかったデータが集計できるようになっているケースもありました。

この辺りの苦労ポイントは内定者バイトで来てくれた松岡くんがまとめてくれているので、ぜひこちらをご覧ください。

AirTrack 内定者アルバイト 「広告ログ集計基盤をSnowflakeへの移行による集計プロセスの改善」

まとめ

3ヶ月程度かかった大規模プロジェクトでしたが、大きな障害なく移行を完了することができました。また、移行完了からすでに2ヶ月以上が経っていますが、以前の問題も解決された上で大きな問題もなくプロダクトを運用できているので移行は大成功でした。

一方で、ワークロードが一定なプロダクトであったり、ワークロードが一定でないプロダクトでも長期のリザーブドインスタンスを購入できるケースでは、 Redshift の方がパフォーマンス・コスト面含めて軍配が上がるケースも大いにあり得るという学びを得ました。

また、Redshift でも計算ノードとストレージが分離されたタイプも出てきており、Redshift が Snowflake のように低コストでスケーリングできるようになる未来は大いにあり得ると思います。今後も引き続き DWH の動向には注目していきたいです。

追記(宣伝)

私が所属する株式会社サイバーエージェント AI事業本部では、サーバーサイド/ML・DS志望の23~24卒以降の学生の方を対象に3Dayインターンシップを開催予定です。
弊社に興味のある方、是非下記よりご応募ください!
https://www.cyberagent.co.jp/careers/students/event/detail/id=26886

2020年度新卒入社のバックエンドエンジニアです。AI事業本部のAirTrackという部署で広告配信システムの開発を行っています。