SnowflakeのDATA CLOUD SUMMIT 2020で登壇したものです https://snowflake.events.cube365.net/snowflake/summit-2020-ja/content/Videos/H7PMNwk7Ru2xCYFsY
広告配信プロダクトのSnowflakeへの移⾏株式会社サイバーエージェント AI事業本部 黒崎 優太 (@kuro_m )@Snowflake DATA CLOUD SUMMIT
View Slide
黒崎 優太• 株式会社サイバーエージェント Dynalyst 開発責任者• 業務は Scala + AWSが中⼼• イラスト図解でよくわかる ITインフラの基礎知識•書きました• ⾃宅サーバなどが好きです@kuro_m @kurochan
Contents• 広告配信プラットフォーム Dynalystについて• Snowflakeを採⽤してどうだったか• Amazon RedshiftからSnowflakeへの移⾏にあたり検証したこと• 移⾏作業で⾏ったこと• 今後挑戦したいこと
広告配信プラットフォーム Dynalystについて
Dynalystについてhttps://www.dynalyst.io• Dynamic Retargeting for Games•DSP事業者•スマホ向けリターゲティング広告配信プラットフォーム•トップセールス @⽇本のスマホゲームの中でも⾼いシェア•ユーザごとに最適化した広告を配信
開発しているシステム概況• ⼊札リクエスト量: 数⼗万リクエスト / 秒数千億リクエスト/⽉• ⼊札トラフィック: 約8Gbps• レスポンスタイム: 100ms以内• ログの量: 数TB / Day(圧縮状態)• ALL AWSຊͷೖࡳϦΫΤετඵ ຊΞϝϦΧͷϨεϙϯελΠϜ NTFD
DynalystでのDWHの活⽤• アドホックな分析⽤途• 主にデータサイエンティストが分析で利⽤• 機械学習バッチのデータソース• 条件に合うデータを抽出する• Tableau(BIツール)上での分析や可視化• など
Tableauでの可視化
Snowflakeを採⽤して どうだったのか
Snowpipe• S 等にデータをアップロードするとそのイベントをきっかけにファイルをSnowflakeに取り込む機能が⾮常に便利だった• ETLを⾃前実装する必要がない, 5TB/⽇程度の流量でも取り込み遅延は1〜2分程度アップロードS イベント通知subscribeSQSSNSS⾃分のAWSアカウント SnowflakeのAWSアカウント取り込み
Task• 定期実⾏したいようなクエリ(定時集計やテーブルのメンテナンスなど)がSnowflakeで完結する
ログのローテーションのしやすさ• TBくらいのテーブルに対して2TB分くらいの削除をした• DELETE FROM table WHARE logged_at >= ...• 数秒でクエリが終了した• メタデータ更新のみで、バックグラウンドで削除が⾏われるようで、 ⼤量のデータの削除が楽• ⼀定期間経過するとexpireするような機能もあるとさらに嬉しいところ。。
Externlal Tables• S 等にあるオブジェクトをテーブルに⾒⽴てて、直接スキャンが可能• Snowflakeのストレージに取り込んだ時よりクエリ速度は遅いが取り込まずにクエリが可能• カラム変換やパーティションの定義に柔軟性があるため扱いやすい
シングルサインオン• 社内のID基盤とSAML認証により連携することでパスワードレスなログイン環境を実現(Macの指紋認証など)• 部署異動時に⾃動で権限が付与されたり、退職時に⾃動でアカウントが停⽌されるため、アカウントのメンテナンスが⾮常に楽• アカウント作成や職種に応じて違う権限を付与する仕組みは⾃社で実装しました
Work Sheets
Work Sheets• 実⾏計画がわかりやすい• 重いクエリの例
Snowsight• 新しいUI(preview)• 簡単なグラフやダッシュボードの作成はUIで完結してしまうので便利
Snowsight• 新しいUI(preview)• クエリ結果をグラフで確認するのも簡単
Amazon RedshiftからSnowflakeへの 移⾏にあたり検証したこと
クエリ性能• 普段分析で使うようなクエリが許容範囲の性能かどうか• ⽇常的に使う重めのクエリで1-2分以内に応答してほしい• 1ヶ⽉分のデータをインポートして性能を計測後3ヶ⽉分, 半年分とデータ量を増やしていき、性能が⼤幅に悪化しないことを確認• ウェアハウスのサイズを2倍にすると、多くのケースでクエリ時間もおおむね半分になることを確認• 普段はM〜L, 重いクエリはXLで運⽤することに• 結論: 問題なし
DWHの安定性• クエリが集中したり、重いクエリが⾛っているときにクエリ時間が極端に遅くなる状況は利⽤者にとってストレスなので避けたい• Snowflakeは⽤途ごとにVirtual Warehouseが作成でき、それぞれのWarehouseは独⽴しているため、負荷の影響を受けない• 結論: 問題ない
コスト• RedshiftからSnowflakeに移⾏するにあたって、 コストが上がることは避けたい• Redshiftは1〜3年のリザーブドインスタンスを購⼊するのが⼀般的• あらかじめコンピュートリソースを買い切る要素が強い, Redshift Spectrumは従量課⾦• Snowflakeは従量課⾦の要素が強い• ウェアハウスが従量課⾦でコストの⼤半を占める• Redshiftのクエリログのテーブルを集計することでクエリの頻度や量を概算• ⼈間以外が投げるクエリ(バッチ処理, Tableauなど)が多く⾒直しの必要性があることがわかった• 結論: クエリを投げるタイミングを集中させてウェアハウスの利⽤効率を 上げたり、クエリの頻度を⾒直したりする必要がある• 結果的にコストは下がった
データ転送料• AWSではInboundトラフィックは無料、Outboundトラフィックは有料• AWS上で⼤量のデータを扱うプロダクトにとって外部のサービスを使う上でデータ転送量が問題になりがち• 例: 東京リージョンからインターネットに1⽇5TB転送: 約 $9,000/⽉• Snowflakeはクラウド事業者とリージョンが選べるので、同⼀リージョン内の通信にすることができる• AWS TokyoリージョンのS からSnowflakeに 転送する料⾦は無料(S のAPI料⾦は発⽣)• 結論: 問題ない
運⽤のしやすさ• クラスタのバージョンアップ作業などが不要(基本的にダウンタイムがない)• 異常に重いクエリを投げてしまっても他のウェアハウスに影響が出ない• Virtual Warehouseを⽤途ごとに分ければよい• ほぼすべての設定がSQLからも操作できて統⼀感がある• Web UIが充実しており、設定項⽬の確認も楽• MySQLやPostgreSQLプロトコルが使えないのは⽋点• Web UIが充実している• アダプタやインテグレーションが充実している• 結論: 問題なし(運⽤負荷は軽減した)
セキュリティ⾯• おもにSnowflakeへの各種アプリケーションからのアクセス⽅法• Snowflakeはインターネットに公開される前提で認証/認可や通信が暗号化されているため、どこからでもアクセスができ楽になった• 以前はVPN経由でしかDWHにアクセスできなかった• IPアドレス制限やAWS Private Linkによるインターネットを経由しない通信も可能• PostgreSQLプロトコルなどオープンなプロトコルが利⽤できない代わりに、 「ゼロトラスト」な環境になった• 結論: 問題なし(運⽤負荷は軽減した)
クエリの互換性• Redshiftで使っていたクエリをできるだけそのまま使いたい• アプリケーションから接続するドライバ• JDBCドライバが提供されているのでドライバの差し替えと設定項⽬の変更で補う• IPアドレスをパースして正規化できるような関数など、Snowflakeの⽅が便利な関数も⾒つかった• 結論: おおよそ問題ないが、⼀部書き換えが必要な部分があった• 今回の移⾏では機能的に不⾜しているケースはなかった• 移⾏前と移⾏後で同じ結果が返ってくるか確認する必要がある• 具体的に対処した部分については後述
移⾏作業で⾏ったこと
DB作成〜データのimportまで• create database• AWSのIAM Role作成• S インテグレーション作成• AWS IAM Roleの信頼関係の更新• ログフォーマット作成• External Stageの作成• テーブル作成• テーブルへS からデータをinsert
データ移⾏• S にあるファイルを移⾏しました• ⼤きめのWarehouseを複数使い並列に取り込むことで数時間で移⾏が完了• computeとstorageが分離されている恩恵を受けました
クエリの互換性を保つための修正• 整数どうしの除算が⼩数で返る• 1 / 100が0ではなく、0.01になる• 整数も⼩数もnumber型で統⼀されているためこうなると思われる• floor関数で切り落とすことで互換性を維持• random()関数が0〜1の範囲外の値を返す• uniform( . , . , random())で0〜1の範囲に丸める• snowsql(cli)にて• empty_for_null_in_tsv=true を指定しないと nullが空⽂字として出⼒されない• exit_on_error=true を指定しないとクエリ失敗時に コマンドの終了ステータスが成功になる
バッチ処理をしているアプリケーションの修正• JDBCドライバを差し替えてリリース• jdbc:snowflale:// で始まる場合にSnowflakeのドライバを読み込むように修正• Redshiftと並⾏稼動期間を作ったため、無停⽌で移⾏ができました
Tableauのデータソースの切り替え• OAuth認証に対応しているため、 Tableauのワークシートにクレデンシャルを 埋める必要がないため安全• 認証情報の使いまわしも防げる
Tableauの移⾏で困ったこと• Snowflakeのint型がTableauだと⼩数点つきで解釈されてしまう• 100, 200などが100.0, 200.0のようになり、別のDBとJOINできなくなる• Snowflakeのint型はnumber( , )であり、最⼤桁数が⼤きいのが原因• number( , )であれば問題が置きなかった• Snowflakeのテーブル定義のintを全てnumber( , )に置換することで解決• 実⽤上number( , ) = 百京まであれば⼗分だった
今後挑戦したいこと
データレイクとしてのSnowflake• 現状はS をデータレイクとして利⽤していて、Snowflakeは分析⽤のログの格納場所としての利⽤に留まっている• S とSnowflake両⽅にログを格納しているためストレージコストが2重にかかっている• 安定稼働しつづけ、S 上のログを直接参照する必要がなくなったらSnowflakeをメインのデータソースという位置づけを検討したい
Apache SparkのSnowflake Driver• Apache Spark: クラスタコンピューティングフレームワーク• 集計はApache Sparkを使って256コア, 512GB程度のクラスタで実⾏• データソースとしてSnowflakeを使うことで集計対象のデータ抽出や簡単な 前処理をSnowflakeに寄せることができるhttps://docs.snowflake.com/ja/user-guide/spark-connector-overview.html