3年で5パターンの分析基盤を作ってみた

入社してから3年たったので、自分メモということも含め、今までやってきたことのまとめ。

# お断り
開発期間の関係で、一つ一つシステムを細かく理解し、チューニング出来たわけではないです。
個人が期間内に調べられた情報で、構築したものなので
「いやいやきちんとチューニングすればそんな結果にはならない」みたいなことは
多々あるかと思いますがご了承ください。
また、3年前はLinuxやSQLは触ったことがない状態だったので
最初の方に担当したものほど作りが甘かったと思います。

# 流れ
* 第1世代: AmazonRedShiftをベースにした基盤
* 第2世代: AmazonEMRでHiveをベースにした基盤
* 第3世代: AmazonEMRでSparkをベースにした基盤
* 第4世代: MySQLとサーバ上での分散処理(Python)をベースにした基盤
* 第5世代: BigQueryをベースにした基盤(製作中)

# 第1世代: AmazonRedShiftをベースにした基盤
## 概要
弊社のシリーズものゲームのKPIを横断的に見るための分析基盤。
fluentdを使ってRedShiftにデータを入れ、日次バッチで集計、
集計結果をRedShiftの別テーブルに格納していた。
バッチはRuby、フレームワークはCakePHPを使用。
fluentdがRuby製だからプラグインとか作れるようにということでRubyを、
CakePHPは会社の文化。

## 開発期間
2013年10月から2014年3月の約6ヶ月(他業務と並行、検証期間含む)

## 所感
初めて触れるものばかりで学ぶのに必死だったイメージしか…

# 第2世代: AmazonEMRでHiveをベースにした基盤
## 移行のきっかけ
データ量が少ない割には、RedShiftの維持コストが大きかった。
(当時はDenseStorageノードしかなかったためコスパが悪かった)
また、集計時間も思ったより長く「最近Hadoop流行ってるよね、検証してみようか」というノリで検証して
低コストで集計ができることが確認できたので導入。

## 概要
シリーズもの以外のゲームもKPIを見れるようにした分析基盤。
「Pythonは統計ライブラリ豊富だから分析エンジニアならPythonいいんじゃない？」
という先輩のススメがあった。
なのでバッチはPython、フレームワークもPython製のdjangoを採用。

## 開発期間
2014年4月から2015年6月の約14ヶ月(他業務と並行、検証期間含む。可視化は別の人が担当)

## 所感
集計時間は、劇的に変わったわけではなかったと思う(詳細のメモが残っておらず…)
ただ、EMRだと集計時間だけサーバを立ち上げればいいので集計コストは半分くらいまで削減できた。
ここでPythonをやり始めたのは後にSparkや機械学習とかをやる上では正解だったと思う。書きやすいし！

# 第3世代: AmazonEMRでSparkをベースにした基盤
## 移行のきっかけ
新技術を触りたいというのと、ちらほらSparkが話題になりつつあったので先駆けでやってみようかと。
キャッシュを効かせれば集計時間は短くなるし、時間が短ければ集計コストも削減が見込め、更にPythonでSparkの処理をかけるので移行のしやすさもあった。

## 概要
HiveからSparkに変えただけで、第2世代とほとんど変わらず。
Spark1.2でRDDベースのものと、Spark1.4のDataFrameベースのものを作った。

## 開発期間
2015年6月から2015年12月の約6ヶ月(他業務と並行、検証期間含む)

## 所感
ドキュメントが少なかったため、試行錯誤をしながら構築するのが大変だった。
セミナーとか行っても周りでは導入検討段階の会社が多くて相談もあまり出来ず…
慣れない英語の記事を読むために、Google翻訳の結果を翻訳するスキルは身についたと思う。
Sparkはキャッシュ機能を使えば、繰り返し処理は速い(DAUを様々なセグメントに分ける時、ログインログをキャッシュしておくなど)ものの最初の一回目はキャッシュが効いていないため時間がかかるのが難点だった。

# 第4世代: MySQLとサーバ上での分散処理をベースにした基盤
## 移行のきっかけ
色々作っているうちに、「あれ、このデータ量ならそもそもHiveやらSparkやら必要ないんじゃないか？」と思ったのがきっかけ。
集計アルゴリズムの見直しや、DBのテーブル設計とかちゃんと考えたら現状のデータ量なら問題ないことが検証しても確認できた。
またSparkの最初の一回はキャッシュが効かないという影響で、DBやサーバ上での処理の方が集計時間の短縮もできそうだった。

# 概要
処理内容は、前世代と変わらず。
Pythonでマルチプロセスで処理するようにした。ログを全てDBに入れるのではなく
集計に必要なログだけを入れて、使わなくなったら消すようにしていた。
(S3にログファイルは残っている)

## 開発期間
2015年12月から2016年2月の約3ヶ月(他業務と並行、検証期間含む)

# 所感
Sparkと比較して、集計時間は半分以下になった。
別用途で常に立ち上がっているサーバとDBを使ったため追加コスト0。
1日数GBくらいならこれでなんとかなるなという感じ。

# 第5世代: BigQueryをベースにした基盤(製作中)
## 移行のきっかけ
今後データ量が増えていってもある程度は捌けるものの、分析の幅が広がって一気にデータ量が増えた時に使えなくなるのではないかという心配と、アドホック分析でデータ量が多い時にSparkクラスタを立ち上げて…とやっていたが
BigQueryで日次バッチもアドホック分析もできれば楽じゃないかということで検証。

## 概要
処理内容は、前世代と一緒。
バッチにPython製のデータパイプライン構築用のフレームワークである[Luigi](https://github.com/spotify/luigi)を使った。

## 開発期間
2016年2月から現在

## 所感(途中段階)
テーブルを作るのにかなりの時間がかかる。Googleの方に聞いてもそこは時間かかるとのことなので、今後に期待。
1クエリ1000テーブル制限も現状使いにくい点。X月Y日時点のユーザ毎の累積課金額を求めるようなものは、リリースから1000日を超えるタイトルは単純には出来ない。
日毎に「前日までの累積課金額+当日分の課金額」でテーブルを作るなど、1000テーブル制限にかからないようにする必要がある。

ただ、集計にかかる時間は短いし、全データを入れておいても管理コストはほとんどかからないため、アドホック分析もしやすいのは大きなメリット。
毎月最初の1TB分の集計コストは無料ということでデータ量が少なければ集計コストもほとんどかからない。

# まとめ

集計対象のログが数GBくらいの場合

項目 | 導入コスト | 運用コスト | アドホック分析のしやすさ
:----:|:----:|:----:|:----:
RedShift | ◯ | ✕(SSDの方を使えば△くらい) | ◯
Hive | ◯ | △ | △
Spark | △ | ◯ | △
SQLと分散処理 | △ | ◎ | △
BigQuery | △(テーブル作成が遅い) | ？(最終的なコストはまだ不明。おそらく◯) | ◯

[導入コスト]
◯ : SQLが書ければほとんどコストがかからない
△ : SQLを書く以外にも考慮する点がある

[運用コスト]
◎ : 別用途で常に立ち上がっているサーバとDBを使ったため追加コスト0
◯ : 5万以下
△ : 10万弱
✕ : 10万以上

[アドホック分析のしやすさ]
◯ : SQLがかければ特に問題なし
△ : 多少難あり。レスポンスが遅いとかキャッシュを考慮する必要があるとか

---
データ量だったり、分析用途によって合う合わないがあると思います。クラウドじゃなくてオンプレの方がいいところもあると思いますし。結局、適材適所って感じですね。
個人的にはSparkかBigQueryが良いなと思ってます。
Sparkは機械学習のライブラリがあったり、SQL以外にもScalaやPythonで処理がかけるので柔軟性がある点でいいですね。後は処理速度が向上されれば。
BigQueryは細かいチューニングが特にいらないし低コストなので気軽さがあるところが良い。現状の問題点が早く改善されるといいな。
振り返ってみると、半年に1回のペースで大幅改修を行っていた。1つ1つ深掘りはできていないものの、3年でこんなにたくさんのことを経験できた環境に感謝。