SlideShare a Scribd company logo
落ちて分かるBigQuery
の落とし穴
芝尾幸一郎(Aiming)
/42
このスライドの趣旨
• ゲーム会社のデータ集計・分析基盤にBigQueryを
導入した。
• 幾つかのゲームタイトルをBigQueryに入れて、実
際に分析していく中で、どのような落とし穴に落ち
てどのようにそれを回避したか、教訓を共有する。
2
/42
発表者紹介
• 芝尾幸一郎
• Aimingにてデータ分析基盤作
成、データ分析担当
• ニコニコ動画のランキングサ
イト作成
• twitter:@shibacow
• 写真とったら送ってね
3
/42
発表者紹介
• bigqueryとre:dashを使って、
ニコニコ動画データセットの
分析をweb経由で行なうシス
テムを作っている
• http://nicodata.info/
4
/42
Aiming
• オンラインMMOゲーム作成に
強いスマホ向けゲーム開発会
社
• 剣と魔法のログレス 古の女神
• 積極採用中です
5
/42
ゲーム開発が変わる! Google Cloud
Platform 実践インフラ構築
• GCPに関する本を書きました(
共著)。
• AimingでのBigQuery=データ
分析基盤構築について
6
/42
内容
・過去の分析環境からの変遷
・BigQueryによる新分析環境
・データ分析システムの比較
・データ分析環境を作る
・実際にログを収集する
7
・実際に集計、可視化する
・収集したデータの活用とKPI
・BigQueryのコスト
・SQL実例あれこれ
・データ分析環境を作ってみ
ての変化
・まとめ
/42
類書にない特徴
• ゲーム分析で役立つ実際に近いテーブルスキーマを
載せている。
• プロデューサーを説得しやすいように、実際に近い
コストを載せている(注、概算)
• 実際に近いSQLが載っている(FQ5とかDAUとか)
8
落ちて分かるBigQuery
の落とし穴
/42
BigQuery悩み所
• テーブル構造やスキーマ構造
• 時刻の表現
• データロード
• データ集計
• バッドデータ
• コスト
10
テーブルと
スキーマ構造
/42
テーブル分割
• アクションで分割
• action <- すべての行動をactionとする
• login,gacha,等細かく分ける
• 日にちで分割
• テーブルを日付で分割 or 日付で分けない
12
/42
テーブル増えすぎ問題
• 1SQL 1000テーブルまで
• 1テーブル増えるごとに50ms増える
• GCP Next 2016 で Table Partitions 発表
13
/42
Table Partitions v1
14
/42
JSON vs カラム分割
• すべてをJSONで入れる
• JSON_EXTRACT で値を取り出す
• すべてをカラムに分ける
• データを挿入時に、予めカラムに分ける
15
スキーマレス カラム分割
実現方法 JSON(STRING型) インサート時分類
性能 やや悪い 良い
コスト 悪い 良い
SQL 冗長 シンプル
手軽さ お手軽 設計あり
カラム追加 容易 やや不便
カラム削除 容易 出来ない
/42
record型使う?
• Tableにhash,Arrayを使うか?
• Aimingでは使っていない
• カード配列等は、split(”1,2,3,4,5”,”,”)
17
/42
そのたハマりポイント
• カラム名を、数字で始めるとNG
• 1vs1みたいなカラム名をつけると、テーブル作れ
ない。
18
時刻
/42
timezone
• UTCが基本
• UTCとして入れて、集計時にJSTに直す
• where date_add(time,9,’hour’) みたいなdate_addが
頻発する
20
/42
時刻関連関数一々長い
• STRFTIME_UTC_USEC とか
• STRFTIME_UTC_USEC(UTC_USEC_TO_WEEK(d
ate_add(time,9,’hour’),1),”%Y-%m-%d”) <- 週単位
の集計とか、人が書くことをあまり想定していない
。
• TD_TIME_FORMAT(time,”yyyy-MM-DD”,’JST’)のほ
うが、親切。
21
/42
Ruby time.to_s
• bigqueryのtimezone表現と合わない
[INSERTされない]
"2013-08-04 22:14:30 +0900”
[INSERTされる]
"2013-11-08T16:26:34+09:00"
Time.now.iso8601 を使おう
22
/42
テーブル区切りはJST
• 中のデータはUTC,テーブルの区切りはJSTで区切
っているので混乱する
23
データロード
/42
ストリーミングインサート
• flunetd -> flunet-bigquery-plugin -> bigquery
• 数万件に一件くらいの割合でレコードが欠ける。
• ロードでは起こらない。
• 全部入らないか、全部入るかのどちらか。
25
/42
Aimingでの推奨方法
• テーブルは、日ごとに分割
• 当日は、ストリーミングインサートを使い、次の日
になったら、前日のテーブルは消して、ロード。
26
Login20160320ストリーミング
Login20160320ロード
flunetd
Login20160320
/42
この方法の利点
• 当日は参考値として扱い、次の日に正確な値にする
• 当日はリアルタイムの値が見たい
• サポートに使うのは翌日以降
27
/42
その他あるある
• スキーマミスマッチ
• Hive booleanがある、BigQuery boolean無い。->
jsonで出して、trueが解釈できず、ロード出来な
い。
28
データ集計
/42
SQLぽくない
• COUNT(DISTINCT(user_id)) ->
EXACT_COUNT_DISTINCT(user_id)
• STRFTIME_UTC_USEC -> date_format
• UTC_USEC_TO_WEEK -> week
30
/42
window関数告知不足
• FQ5とか一発で集計できるが、広報やサンプルが足
りず、なかなか認知されない。
31
10年戦えるデータ分析入門 SQLを武器にデータ活用時代を生き抜く(青木峰郎)p 188
select exact_count_distinct(user_id) as value,
STRFTIME_UTC_USEC(date,'%Y-%m-%d') as date
FROM (selectuser_id,date,
count(*) OVER (PARTITION BY user_id ORDER BY date RANGE BETWEEN 4 *2
FROM ( select user_id,UTC_USEC_TO_DAY(date_add(time,9,'HOUR')) as date F
バッドデータ
/42
バッドデータハンドブック
• BigQueryは、テーブルやレコ
ードの修正や削除が難しい。
• どんなに対策を練っても実際
に運用すれば、おかしなデー
タが入ってくることは避けら
れない。
34
/42
おかしなデータ
• カラムの型が異なる(IntegerのはずがStringが来る)
• カラムの意味が違う。3番めの値と4番目の値を取
り違う。
35
/42
期待値のコントロール
• 会計処理の様な厳密なシステムは、別で組む
• あくまで傾向値が分かる集計・分析ツールですと宣
言。
• ゴミデータが入ったら、諦めてもらう様に促す
• 再集計しやすいアーキテクチャーにしておく
36
コスト
/42
cost controlがいけてない
38
何故、問い合わせフォームベースなのか?
developer consoleでも良くない?
https://support.google.com/cloud/contact/bigquery_custom_quota_req
/42
過去のコスト履歴が見たい
• 今月のコストしか分からない
• 前月のコストも分かるようにしてほしい
39
/42
BigQuery悩み所まとめ
• テーブル構造やスキーマ構造
• 時刻の表現
• データロード
• データ集計
• バッドデータ
• コスト
40
/42
素晴らしいプロダクト
• データがいくらでも入る
• 集計レスポンスが速い
• window関数などが充実
• BQなしでデータ分析基盤を作ることは考えられな
い。
41
有難うございました
/42
質疑応答
43
買って!!
来て!!
@shibacow

More Related Content

Bq sushi(BigQuery lessons learned)

Editor's Notes

  1. もう、BigQueryに慣れている人は、あー、あるあると思ってくれれば良いし、BigQueryをまだ導入していない人は、こんな落とし穴があるのねと思ってくれればよいです。
  2. 本を書きました。