89
MongoDBを用いたソーシャ ルゕプリのログ解析 〜解析基盤構築からフロントUIまで、 MongoDBを最大限に活用する〜 doryokujin 1MongoDB JP & CouchDB JP 合同勉強会 in Tokyo

MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDBを用いたソーシャルゕプリのログ解析

〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

doryokujin

第1回 MongoDB JP & CouchDB JP 合同勉強会 in Tokyo

Page 2: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

自己紹介• [自己紹介]

▶ いのうえ たかひろ( twitter: doryokujin )

▶ 福沢諭吉大学院2年、数学科 25歳

▶ マラソンも好き(ベスト2時間33分)

• [活動]

▶ MongoDB JP 主催者、ドキュメント訳者

▶ ブログ

▶ 芸者東京エンターテンメント GTE

▶ ゕルバト4ヶ月目、ログ解析部隊(1人)

Page 3: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

本日のゕジェンダ

1. ログ解析と MongoDB

▶ なぜ MongoDB を採用したか

2. ソーシャルゕプリのログ解析

▶ 解析バックエンドとフロントエンドでの MongoDB 活用例

3. MongoDB その他のトレンド

▶ MongoDB の先進的な活用事例:Logging、Hadoop、Graph

Page 4: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

1. ログ解析とMongoDB

Page 5: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ソーシャルゲームのログ解析〜GTEの場合〜

• [目的] (もちろん会社によって様々)

‣ 今まで出ていた基本的なデータより、もっと細かく多くのデータを提供する

‣ 明確に取得して見たいデータに加えて、あらゆるデータをとりあえず色々見てみる

‣ 解析のバックエンド(後述)からフロントエンドまでを1人でやる

‣ 解析の結果自身が意志決定を行うのでは無く(機械学習・高度な統計は不必要)、人間の意志決定を支援するための結果を出す

Page 6: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析バックエンドとフロントエンド

‣ 一言に解析の仕事と言ってもバックエンドとフロントエンドで全く異なる仕事になる

‣ 散在するログの収集に始まり、ゕナリスト(フロントエンド)がいつでも所望のデータを取り出せるように適切な形式・場所に格納するための基盤を構築するのがバックエンド

‣ 解析ツールを駆使し、また様々な視点でデータを解析し、人間の意志決定を支援するための結果を導くのがフロントエンド

‣ バックエンドはンフラ、大規模分散処理技術・DB(RDB・NoSQL)の知識が必要。規模や目的に合わせた設計が重要。とても泥臭い仕事

‣ フロントエンドの解析者はいつでもデータが取り出せるという前提のもと、バックエンドを気にせず解析に専念できる状況を想定している

Page 7: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ソーシャルゲームの行動ログ

• [行動ログ]

‣ 個々のユーザーの行動を詳細に知ることができる

‣ ユーザーの行動をいつ・何を・どのような形式でログに出力するのかは開発側が判断・決定

• [出力例]

‣ ログンした

‣ スタミナが 100 回復した

‣ ユーザー A のおみせからゕテム I を勝った

‣ ユーザー B に勝ってゕテム J をゲット

‣ ユーザー C の掲示板に書き込んだ

Page 8: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ソーシャルゲームの行動ログ

• [行動ログの例]

行動のタイプユーザーID 行動の詳細

Page 9: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [行動ログ詳細]

-----Change------

ActionLogger a{ChangeP} (Point,1371,1383)

ActionLogger a{ChangeP} (Point,2373,2423)

------Get------

ActionLogger a{GetMaterial} (syouhinnomoto,0,-1)

ActionLogger a{GetMaterial} usesyouhinnomoto

ActionLogger a{GetMaterial} (omotyanomotoPRO,1,6)

-----Trade-----ActionLogger a{Trade} buy 3 itigoke-kis from gree.jp:00000 #逆からみれば売った事に

-----Make-----

ActionLogger a{Make} make item kuronekono_n

ActionLogger a{MakeSelect} make item syouhinnomoto

ActionLogger a{MakeSelect} (syouhinnomoto,0,1)

-----PutOn/Off-----

ActionLogger a{PutOff} put off 1 ksuteras

ActionLogger a{PutOn} put 1 burokkus @2500

-----Clear/Clean-----

ActionLogger a{ClearLuckyStar} Clear LuckyItem_1 4 times

-----Gatcha-----ActionLogger a{Gacha} Play gacha with first free play:わくわくおみせ服ガチャActionLogger a{Gacha} Play gacha:わくわくおみせ服ガチャ

行動タプ[actionType]

行動の詳細[actionDetail]

※行動の詳細の値は様々:頻度・変化・対象・複合要素

※行動タプごとに適切な整形が必要

ソーシャルゲームの行動ログ

Page 10: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ソーシャルゲームのログ解析• [行動ログ解析で重要なこと]

‣ どの項目が関係し合っていて、また後で重要になるかがわからないので全て取得しておきたい

‣ そのため解析過程において、ログの持つ情報や構造が失われないことが重要

‣ 集約したログの情報を一元管理するデータサーバーが必要

• [解析データサーバー]

‣ ログから情報を抽出し、それを格納しておく仕組み

‣ 格納場所はDB・HDFS・デゖレクトリ(フゔル)等…

‣ 蓄積された解析データはゕナリスト(フロントエンド)が取り出して解析を行う

Page 11: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ランキング課金情報登録日

解析データサーバー

行動ログ

アクセスログ

各種ログ�������

ゲームセーブ

データ

解析

可視化

解析データサーバー

バックエンド フロントエンド

情報量や構造を失わないように

解析対象となるデータは全て解析データサーバーに

Page 12: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ランキング課金情報登録日

解析バックエンド for GTE

行動ログアクセスロ

ゲームセーブ

データ

MySQLCassandra

Dumbo (Python + Hadoop )整形・フゖルタリング・簡易集計

全集計結果はMongoDBに格納

Python Script

整形・集計データ

scribe でローカルのHDFS上に格納

Thrift & PHP(API)

解析フロントエンド

Sharding×3Replica Set×3

Server× 3

データセンター(ホステゖング

Page 13: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析フロントエンド for GTE

Sleepy.Mongoose

解析対象データ

GraphDB

WebUI

解析ツール

ソーシャルデータゕクセスログ(遷移データ)

Page 14: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

最適な解析データサーバーとは?

工程・時間

情報量

DB:SQL、NoSQLフゔル群:NFS、HDFS

各種ログ

解析データサーバー

‣ 解析過程でいかに情報量を失わせないかが重要

‣ しかし様々な要因によって満足な情報を持ったデータ保存が行えない

Page 15: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

要因2:集計処理が複雑・時間がかかる

要因1:散在するログの集約に時間がかかる

要因4:データの取得・表示に手間と時間がかかる

工程・時間

情報量

各種ログ

解析データサーバー

要因3:SQLならスキーマの制約やファイル・テーブルが多く複雑になる

最適な解析データサーバーとは?

‣ 解析過程でいかに情報量を失わせないかが重要

‣ しかし様々な要因によって満足な情報を持ったデータ保存が行えない

Page 16: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析データサーバーとしてのMySQL

[メリット]

• ドラバの充実

• ノウハウが多数蓄積

• 安定動作

[デメリット]

• スキーマ制約

• スケールがそこそこ大変

フロントエンドバックエンド

[メリット]

• ゕプリ側との親和性

• 検索クエリの充実

• JOINが可能

[デメリット]

• 特に無し

Page 17: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析データサーバーとしてのHadoop・HIVE・Pig

[メリット]

• 大規模分散処理

• 集計時にJOINが可能

• 簡単なスクリプト言語で記述ができる

[デメリット]

• 処理フローの管理

• 詳細な処理がやや面倒(Hive・Pig)

フロントエンドバックエンド

[メリット]

• 特に無し

[デメリット]

• HDFSの信頼性に不安

• データ取得に手間

• データの検索性が悪い

• フゔル管理が面倒

Page 18: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析データサーバーとしてのCassandra・HBase

フロントエンドバックエンド

[メリット]

• 特に無し

[デメリット]

• 検索クエリが貧弱

• ンデックスはキーのみ

• コマンドランでの手軽な操作ができない(データのゕクセス性)

[メリット]

• スキーマフリー

• 高い Write 性能

• スケーラビリテゖ

• ドラバの充実

[デメリット]

• 特に無し

Page 19: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析データサーバーとしてのMongoDB

[メリット]

• スキーマフリー

• ドキュメント指向

• ドラバの充実

• Replica Sets

• Auto Sharding

[デメリット]

• HDD・メモリ消費

• 動作が不安定

[メリット]

• コマンドラン操作の充実

• 豊富な検索クエリ

• 完全ンデックスサポート

• REST・Node.js・ORMが充実

[デメリット]

• 特に無し

フロントエンドバックエンド

Page 20: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB が最適な理由

[メリット]

• スキーマフリー・ドキュメント指向

‣ MONGODB RIAUNLEASHED 2010

• 豊富な検索クエリ

‣ Creating, Updating and Deleting Document in MongoDB

• コマンドラン操作の充実 (JavaScript)

‣ 必要な関数は定義して保存しておける

‣ 必要な時にすぐにデータを取り出し、見せることができる

→ データを見せながら会話ができる

Page 21: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

[メリット]

• 完全なンデックスサポート

‣ あらゆる項目でデータの取得が高速(10億レコードでも高速検索)

‣ Indexing and Query Optimizer (Aaron Staple)

• Replica Sets・Auto Sharding

‣ データのバックゕップが容易→解析者の負担が軽減

‣ MongoDB Replica Sets

‣ Kristina Chodorow's Blog ( Part1 Part2 Part3 )

‣ MongoDB Auto-Sharding at Mongo Seattle

MongoDB が最適な理由

Page 23: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

2. ソーシャルゕプリのログ解析

※データの数値は正しい値はないのでご注意下さい

Page 24: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

おみせやさん

▶ 会員数累計300万を誇る弊社ソーシャルゕプリのGREE版

▶ ゕクセスログ12GB / 日、行動ログ5GB / 日

▶ MySQL + Cassandra + Scala ( Lift ) による実装

▶ MongoDB + GraphDB によるデータ解析

▶ gumiStudy#6 300万人が遊ぶソーシャルゕプリ「おみせやさん」の作り方 →ンフラ関連のおはなし

Page 26: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

2-1.ログ解析バックエンド

Page 27: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Hosting Server

Flash ComposeServer

Cassandra18ノード

MySQL

Webserver(nginx)

7台

Appserver(Tomcat)

27台

ゲームセーブデータ(ユーザーステータ

ス)

アクセスログ

ランキング課金情報登録日

行動ログ

ゕクセスの流れ

主に4種類のデータが解析対象

Page 28: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ランキング課金情報登録日

解析バックエンド

行動ログアクセスロ

データセンター(ホステゖング

ゲームセーブ

データ

MySQLCassandra

Dumbo (Python + Hadoop )整形・フゖ

ルタリング

全集計結果はMongoDBに格納

Python Script

整形・集計データ

scribe でローカルのHDFS上に格納

Thrift & PHP(API)

解析フロントエンド

Sharding×3Replica Set×3

Server× 3

Page 29: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

前処理としてのHadoop

• データの整形

‣ MongoDB に格納するためにフォーマットの統一

• データのフゖルタリング

‣ 1日約1億レコードある行動ログの情報削減

→ 解析を進めていく上で判明した不要項目は読み飛ばし1日1000万レコード程度に削減

• 簡単な集計

• 今後のデータ増大に備えて

‣ サービスが増えてもスケールゕウトできるように

Page 30: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Dumbo

• [説明]

‣ Python + Hadoop = Flying Circus Elephant

‣ Last.fm で使用

‣ Hadoop Streaming を実行

‣ map/reduce の記述が楽

‣ 簡単な join もできる

‣ デバッグが容易

http://github.com/klbostee/dumbo

Page 31: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] Dumbo で Word Count

行動ログ集計:Dumbo

def mapper(key, value):

for word in value.split(): yield word,1

def reducer(key, values):

yield key,sum(values)

if __name__ == "__main__":

import dumbo

dumbo.run(mapper, reducer)

dumbo start wordcount.py ¥

-hadoop /path/to/hadoop ¥

-input wc_input.txt -output wc_output

「wordcount.py」

Page 32: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Dumbo

• [メリット]

‣ MapperとReducer、Combinerも1フゔルに記述可

‣ Hadoop Streaming のオプションを引継ぐ

‣ HDFS上のフゔルの操作も可能(fs -ls や –put 等)

‣ Hadoop オプションを指定しない場合は、以下のパプラン処理となり、デバッグ容易

python wordcount.py map < wc_input.txt | sort | ¥

python wordcount.py red > wc_output.txt

Page 33: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Hadoop 処理1.Map:

‣ レコード内の必要な項目のみを抜き出す

‣ 不要なレコードはフゖルタリング

‣ 集計対象となる部分の整形処理(頻度・変化量・対象・複合)

2010-07-26 00:00:02,446 INFO catalina-exec-483 ActionLogger – userId a{Make} make

item onsenmanjyuu

2010-07-26 00:00:02,478 INFO catalina-exec-411 ActionLogger – userId a{LifeCycle}

Login

userId をkeyに、行動詳細部分をJson整形オリジナルンプット

マップからの出力

userId 2010-07-26 00:00:02,446 a{Make} {onsenmanjyuu:1}

userId 2010-07-26 00:00:02,478 a{LifeCycle} {Login:1}

userId 2010-07-26 00:00:02,478 a{GetMaterial} {omotyanomotoPRO:5}

userId 2010-07-26 00:00:02,446 a{putOn} {item:A,user:B}

Page 34: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

行動ログ集計

2.Reduce:

‣ [簡易集計] 同じ行動タプはユーザー毎に集計

‣ [デバッグ] 異常値(システムエラー・不正行動)の判定もここで行う

‣ 非数値は頻度集計・数値は合計

‣ 複合要素はそれに応じた集計

‣ [Output] 最終的な出力はMongoDB

‣ HDFS上にはセッションログが書き出される

Page 35: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB Collection

デリー集計

user_charge

課金情報登録日

行動ログ

アクセスログ

ユーザーステータス

user_trace

user_savedata

user_access

ユーザー毎・日付毎

daily_charge

daily_trace

daily_savedata

daily_access

Page 36: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB Collection

デリー集計

user_charge

課金情報登録日

行動ログ

アクセスログ

ユーザーステータス

user_trace

user_savedata

user_access

ユーザー毎・日付毎

daily_charge

daily_trace

daily_savedata

daily_access

Page 37: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] ユーザー×日付×タプ:user_trace

行動データ

> db.user_trace.find({date:"2010-11-

10”,actionType:"a{Make}",userId:”7777"}).forEach(printjson)

{

"_id" : "2010-11-10+7777+a{Make}",

"date" : "2010-11-10"

"lastUpdate" : "2010-11-11",

"userId" : ”7777",

"actionType" : "a{Make}",

"actionDetail" : {

"make item ksutera" : 3,

"make item makaron" : 1,

"make item huwahuwamimiate" : 1,

"make item ringoame" : 3,

}

}

ユーザー・日付・行動タプごと

行動タプによっては配列や入れ子

の辞書が入る

Page 38: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] 全ユーザー×日付×タプ:daily_trace

行動データ

> db.daily_trace.find({date:{$gte:"2010-11-10”,$lte:”2010-11-20”},actionType:"a{Make}"}).forEach(printjson)

{

"_id" : "2010-11-10+group+a{Make}",

"date" : "2010-11-10",

"lastUpdate" : "2010-11-12",

"actionType" : "a{Make}",

"actionDetail" : {

"make item kinnokarakuridokei" : 615,

"make item banjo-" : 377,

"make item itigoke-ki" : 135904,

"make item wadaiko" : 40,

"make item ha-pu" : 11,

"make item ribontore-sunohigasa" : 13621

...

},

...

}…

11-10から11-20までの範囲指定

Page 39: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] ユーザー×日付×行動タプ:user_charge

課金データ

// 11/10に最も課金してくれたユーザーTOP10

> db.user_charge.find({date:"2010-11-10"}).sort({totalCharge:-1}).limit(10)

.forEach(printjson)

{

"_id" : "2010-11-10+7777+Charge",

"date" : "2010-11-10",

"lastUpdate" : "2010-11-10",

"totalCharge" : 10000,

"userId" : ”7777",

"actionType" : "Charge",

"boughtItem" : {

"アクセサリーの素EX" : 13,

"コネルギー+6000" : 3,

"アクセサリーの素PRO" : 20

}

}

{…

ユーザーごとに内訳が変わってくる

Page 40: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] 全ユーザー×日付×タプ:daily_charge

課金データ

> db.daily_charge.find({date:"2010-11-10",T:"all"}).limit(10).forEach(printjson)

{

"_id" : "2010-11-10+group+Charge+all+all",

"date" : "2010-11-10",

"total" : 100000,

"UU" : 2000,

"group" : {

"わくわくポント" : 1000000,

"アクセサリー" : 1000000,

...

},

"boughtItemNum" : {

"料理の素EX" : 8,

"アクセサリーの素" : 730,

...

},

"boughtItem" : {

"料理の素EX" : 10000,

"アクセサリーの素" : 100000,

...

}

}

ゕテムのカテゴリ別の内訳

Page 41: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB Collection

user_registration

課金情報登録日

行動ログ

アクセスログ

ユーザーステータス

user_category

user_error

ユーザーの登録日・最終ログン日・総課金額・初課金日 etc…

属性で分類したカテゴリごとの内訳(人数・

課金額)etc…

異常値:ex. システムエラー・欠損値・不正行

動 etc…

ユーザー属性抽出

Page 42: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB Collection

user_registration

課金情報登録日

行動ログ

アクセスログ

ユーザーステータス

user_category

ユーザー属性抽出

user_error

ユーザーの登録日・最終ログン日・総課金額・初課金日 etc…

属性で分類したカテゴリごとの内訳(人数・

課金額)etc…

異常値:ex. システムエラー・欠損値・不正行

動 etc…

Page 43: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] ユーザー毎の属性データ:user_registration

ユーザー属性データ

> db.user_registration.find({userId:”7777"}).forEach(printjson)

{

"_id" : "2010-06-29+7777+Registration",

"userId" : ”7777"

"actionType" : "Registration",

"category" : {

“R1” : “True”, #直近1週間ログンしていない場合 = True

“T” : “ll” #プレ期間が長期のユーザー

},

“firstCharge” : “2010-07-07”, #初課金日

“lastLogin” : “2010-09-30”, #最終ログン日

“playTerm” : 94, #プレ期間

“totalCumlativeCharge” : 50000, #総合課金額

“totalMonthCharge” : 10000, #直近1ヶ月の課金額

}

課金額・期間・登録日等に応じてカ

テゴラズ

Page 44: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] 属性毎の内訳を計算:user_category

属性カテゴリデータ

> var cross = new Cross() //ユーザー定義関数

//月額課金×プレ期間(退会ユーザー)

> MCResign = cross.calc(“2010-10-08”,“MC”,1)

課金/期間 0円(z) ~1000円(s) ~10000円(m) 10000円~(l) 合計

~1日(z) 50000 10 5 0 50015

~1週間(s) 50000 100 50 3 50153

~1ヶ月(m) 100000 200 100 1 100301

~3ヶ月(l) 100000 300 50 6 100356

3ヶ月~(ll) 0 0 0 0 0

//月額課金×プレ期間(現役ユーザー)

> MCNotResign = cross.calc("2010-10-08","MC",-1)

課金/期間 0円(z) ~1000円(s) ~10000円(m) 10000円~(l) 合計

~1日(z) 50000 10 5 0 50015

~1週間(s) 50000 100 50 3 50153

~1ヶ月(m) 100000 200 100 1 100301

~3ヶ月(l) 100000 300 50 6 100356

3ヶ月~(ll) 0 0 0 0 0

user_registraton.catagory のタグごとに集計する関数

Page 45: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

//ユーザー定義関数

> access = getAccessData(“tutorial”,“2010-12-01”)

UU PATH

10000 /playshop2-gree/tutorial/FirstTopPage

9500 /playshop2-gree/tutorial/Tutorial01Page

8000 /playshop2-gree/tutorial/Tutorial02Page

7700 /playshop2-gree/tutorial/Tutorial03Page

7000 /playshop2-gree/tutorial/Tutorial04Page

4000 /playshop2-gree/tutorial/make/avatar

3800 /playshop2-gree/tutorial/Tutorial05Page

• [例] チュートリゕルページの離脱状況を確認:daily_access

ゕクセスデータ

daily_access から“tutorial”を含むゕドレスの値でソー

トして表示

01Page、04Pageに問題

Page 46: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

データを格納する時のポント

• [形式]

‣ どのコレクションも1レコードあたり「ユーザー×日付×行動タプ」で統一

‣ デリー集計の場合は userId = “group”

‣ _idも”{userId}+{date}+{actionType}”で統一して記述

• [メリット]

‣ ユーザー・日付・行動タプの3軸で集計できる

‣ 検索時、collection間で統一したクエリーで記述できる

‣ _idの明確なルール化で容易にレコード特定

Page 47: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

2-2.ログ解析フロントエンド

Page 48: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

解析フロントエンド

Sleepy.Mongoose

解析対象データ

GraphDB

WebUI

解析ツール

ソーシャルデータゕクセスログ(遷移データ)

Page 49: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI

• [目的]

‣ 社員全員で共有できるようにWebでデータを公開

‣ 基本はデリーの課金・行動データを出力

‣ 社内ツールなので無駄な作り込みは不要

‣ 取得している全てのデータにゕクセス可能

‣ 要望に応じて柔軟に項目追加できる仕様

Page 50: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:検討した仕様

• ① MVC + MongoDB → Ming

• ② node.js + MongoDB → Mongoose

• ③ REST Interface + MongoDB →

sleepy.mongoose

Page 52: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] スキーマの使用例

MVC+MongoDB

from ming.datastore import DataStore

from ming import Session

from ming import Document, Field, schema

bind = DataStore('mongo://localhost:30000/playshop')

session = Session(bind)

class UserTrace(Document):

class __mongometa__:

session = session

name = ‟user_trace‟

_id = Field(str) #標準のBSONオブジェクトなら Field(schema.ObjectId)

userId = Field(str)

actionType = Field(str)

#trace.py として保存

db

collection

Page 53: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] スキーマの使用例

MVC+MongoDB

import trace

#Ming provides a standard attribute .m, short for “manager”

>>> trace.userTrace.m.find().first()

{ "_id" : "2010-11-10+38733015+a{Make}",

"date" : "2010-11-10"

"lastUpdate" : "2010-11-11",

"userId" : ”7777",

"actionType" : "a{Make}",

"actionDetail" : { "make item ksutera" : 3,…}

}

Page 54: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:検討した仕様 ②

• ②:[node.js + Mongo]

‣ サーバサド Java Script

‣ クラゕントのリクエストをサーバー側で実行して結果を返す

‣ Mongoose は数種ある中で代表的なサーバサドJSラブラリ。

‣ Node.js 内で動くJava Script Library

‣ 未実装部分もあるが、十分使える

‣ Hummingbird がMongoDB+node.jsを使用した実例

‣ 参考になるページ

‣ Node.js and MongoDB

‣ node.js + express + mongodb + mongoose を試してみた

‣ Real time ecommerce analytics with MongoDB at Gilt Groupe

Page 55: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] もっとも簡単な例

node.js+MongoDB

var mongoose = require('mongoose/').Mongoose,

db = mongoose.connect('mongodb://localhost/playshop'),

Collection = mongoose.noSchema(‟user_trace',db);

Collection.find({„date‟:‟2010-11-10‟}).each(function(doc){

// do something

});

Page 56: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] Modelを利用した例

node.js+MongoDB

var mongoose = require('mongoose/').Mongoose,

db = mongoose.connect('mongodb://localhost/playshop');

mongoose.load('./models/');

User = mongoose.get(‟UserRegistration',db);

var user = new User({userId :‟7777', totalCharge : 10000, …});

user.lastLogin = „2010-11-10‟; // change a key value

user.save()

User.find({„date‟:‟2010-11-10‟}).each(function(user){

// do something…

});

Page 58: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:検討した仕様 ③

• ③:[REST Interface + Mongo]

‣ HTTP GET/POSTリクエストでデータを受け取る

‣ sleepy.mongoose

‣ /db_name/collection_name/_command 形式でリクエスト

‣ 10genのエンジニゕ @kchodorow さんが作った純正ツール

‣ Pymongo、pyOpenSSL を内部的に使用

‣ 参考になるページ

‣ Sleepy.Mongoose: A MongoDB REST Interface

Page 59: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] 使用例

REST Interface + Mongo

//server起動

> python httpd.py

…listening for connections on http://localhost:27080

//MongoDBに接続

> curl --data server=localhost:30000 'http://localhost:27080/_connect‟

//クエリー の例

> curl -X GET 'http://localhost:27080/playshop/daily_charge/_find'

> http://localhost:27080/playshop/daily_charge/_find?criteria={}&limit=10&batch_size=10

{"ok": 1, "results": [{“_id": “…”, ”date":… },{“_id”:…}], "id": 0}}

Page 60: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [例] 使用例

REST Interface + Mongo

//細かい条件でリクエストが可能

>http://localhost:27080//playshop/daily_charge/_find?criteria={“date”:{$gte:”2010-11-

01”,”$lte”:”2010-11-13”}}&sort={“date”:1}&limit=100&batch_size=100

{"ok": 1, "results": [{"date": "2010-11-01", "_id": "2010-11-01+group+Charge+all+all", "group":

…},{…},…,”id”:1}

Page 61: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

フロントはsleepy.mongoose

• [結論] sleepy.mongoose を採用

‣ 最も手軽(基本実装1日で完了)

‣ Ajaxと併せて非同期通信

‣ 今回必要な検索条件は全て使用できる事を確認

‣ 1回のデータ量もそれほど大きくない

‣ MongoDBとHTMLを仲介するフゔルが不要

Page 62: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:テーブル・グラフ

• [テーブル]

‣ 日毎の集計値を表で出力したい

‣ 各項目でソートしたい

‣ できるだけ簡単に実装したい

‣ jQuery.DataTables

‣ 項目ごとのソート機能

‣ 表示数指定・ページネーション機能

‣ 検索機能

‣ 精錬されたデザン

‣ $(document).ready(function(){ $(’#tableArea').dataTable();});

Page 63: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:テーブル・グラフ

• [グラフ]

‣ データの可視化

‣ 主に時系列チャート

‣ できるだけ簡単に実装したい

‣ jQuery.HighCharts

‣ 多数のグラフが用意されている

‣ 精錬されたデザン

‣ ンタラクテゖブなグラフも可能

‣ ドキュメントが充実

Page 64: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:まとめ

• データ取得・描画がJSON形式でほぼダレクトにやりとり

• 非常に手軽かつ高性能

JSONSleepy.Mongoose

jQuery

Page 65: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:実例

‣ デリーの全ての課金内訳、行動内訳が閲覧可能

‣ CSVダウンロードリンク

‣ 特定のユーザーの課金、行動履歴を全てトラッキング可能

‣ 属性ごとのユーザー数内訳、分布

Page 66: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:実例

Page 67: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:実例

Page 68: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

WebUI:実例

Page 69: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

2-3.まとめ

Page 70: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

• [まとめ]

‣ 3ゲーム・計500GB・10億レコードでも余裕

‣ スキーマレスかつ検索クエリが豊富なのが強い

‣ 自前スクリプトも定義でき、コンソールから様々な操作ができる

‣ データの増加に対しても容易にスケールできる

‣ 解析目的では、コレクション数やンデックス対象になる項目がそれほど多くない

ログ解析 + MongoDB:ベストプラクテゖス

Page 71: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

3. MongoDB その他のトレンド

Page 72: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

3-1. Log to MongoDB

Page 73: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Log to MongoDB

• Logging Application Behavior to MongoDB

‣ ゕプリケーションのログを中央管理できる

‣ フゔルの場合と比べてリモートでゕクセスしやすい

‣ ドキュメント指向と相性がよい。(フゔルログの各項目をキーに、値をバリューにできる)

‣ スキーマレスなので様々なログ形式に対応

‣ ンデックスと豊富なクエリーを活用

‣ Capped collection がこの用途において非常に効果的

‣ JavaScript MapReduce によってデータ集約が可能

Page 74: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

Log to MongoDB

• [Capped Collection]

‣ 固定サズのコレクション(古いデータから削除される)

‣ insert処理に特化、非常に高パフォーマンス(update処理不可)

‣ ンデックス無・検索結果はinsert順(log tailing)

• [JavaScript Map Reduce※]

‣ MongoDB の Map Reduce、JavaScript で記述

‣ Sharding 間でスケールが可能

※現在1つのmongodプロセスでのMapReduce処理はシングルスレッドの制約がある

Page 75: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ランキング課金情報登録日

解析バックエンド(今)

行動ログアクセスロ

データセンター(ホステゖング)

ゲームセーブ

データ

MySQLCassandra

Dumbo (Python + Hadoop )整形・フゖ

ルタリング

全集計結果はMongoDBに格納

Python Script

整形・集計データ

scribe でローカルのHDFS上に格納

Thrift & PHP(API)

解析フロントエンド

Sharding×3Replica Set×3

Server× 3

Page 76: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

ランキング課金情報登録日

解析バックエンド(案)

MySQL

Python Script

行動ログ

アクセスログ

ゲームセーブ

データ

user_trace

user_savedata

user_access

capped collection

capped collection

capped collection

JavaScript MapReduce

Update/hour

Update/hour

Update/hour

Modifier Operations

RealTime

RealTime

RealTime

Page 77: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

3-2. MongoDB + Hadoop

Page 78: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB + Hadoop

The Elephant In the Room: MongoDB + Hadoop [pdf]

Page 79: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB + Hadoop

• [Hadoop]

‣ github: mongo-hadoop

‣ 現在は Java ドラバのみ

‣ Hadoop の入力として MongoDB のコレクションを指定できる

‣ Hadoop の出力先にも MongoDB のコレクションを指定できる

‣ MongoDB 独自のJavaScript MapReduce より柔軟で強力な大規模分散処理が可能になる

Page 80: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

MongoDB + Hadoop• [Pig]

‣ 現在は MongoDB を出力先でのみ指定可能

‣ 将来的には入力先でも指定可能になる予定

-- Use the PigStorage function to store the results.

--Output:(hour, n-gram, score, count, average_counts_among_all_hours)

> STORE ordered_uniq_frequency ¥

INTO ’mongodb://localhost/test.pig.output‟ ¥

USING com.mongodb.hadoop.pig.MongoStorage;

> db.pig.output.find()

{

"_id" : ObjectId("4cbbbd9487e836b7e0dc1052"),

"hour" : "07”, "ngram" : "new”,"score" :2.4494897427831788,

"count" : NumberLong(2), "mean" : 1.1428571428571426

}

Page 82: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

3-3. グラフ構造データ解析

Page 83: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

グラフ構造データ解析

• [グラフ構造を持ったデータ]

‣ ノードとエッジとその属性値で表現できるような構造を持ったデータ

‣ ソーシャルデータ:TwitterのFollow関係、mixiのマミク関係

‣ ゕクセスログ:ページ間の遷移データ・コンバージョン

‣ リコメンドエンジンで使用するデータ

‣ その他多くのデータが実はグラフ構造で表現可能

Page 84: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

グラフ構造データ解析• [特殊な検索方法]

Building a Social Network with MongoDB[pdf]

Page 85: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

グラフ構造データ解析

• [特殊な検索方法]

‣ 近傍検索(友達の友達を探索)

‣ 重み付け検索(エッジの属性値で重み付け)

‣ こういった検索を GraphDB 以外でやるのは面倒

> SELECT ?person WHERE {

?person KNOWS ?friend

?friend KNOWS ?classmate

?classname name “Takahiro Inoue”

}

MongoDBとAjaxで作る解析フロントエンド&GraphDBを用いたソーシャルデータ解析 (from 55 page)

Page 86: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

グラフ構造データ解析

• [MongoDB でグラフ構造を扱う]

‣ Building a Social Network with MongoDB

‣ MongoDB でソーシャルデータの解析方法を述べたチャレンジングな資料

‣ 近傍のデータを配列に格納、$in で検索可能に

‣ 工夫次第でグラフデータの解析も

‣ しかし、パフォーマンスは不明、かつレコードの保存形式が複雑になる場合も

Page 87: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

4. 最後に

Page 88: MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜

今後の活動

• [解析者の存在価値を高めて行きたい]

‣ 到来する”BigData”の時代において、解析者が非常に重要な存在になっていく事を証明していきたい

‣ それは自分の居場所をかけた戦いでもあり…

‣ 解析バックエンドを担える人は非常に重要。そしてその強力な武器となるのがHadoopやNoSQL

‣ MongoDBと出会いで色んな可能性が見えてきた

‣ なのでMongoDBやデータ解析の話をさせてくれる機会があればいつでも声をかけて下さい