はじめに
さくらのVPSをベータ*1として使わせてもらっているのに何もしないのはもったいない&申し訳ないので、Twitter Client Ranking by Streaming APIというのを、さくらのVPSのパフォーマンスとMongoDBのパフォーマンス・使用感をテーマに実験的に作ってみました。
TwitterのStreaming APIからツイートを取得、保存、解析してどんなクライアントが使われているかをランキング形式に表示するという単純なものです。
解析結果をブログで公開している例があるものの、なかなか直近で連続的なデータを公開しているところがなかったので、勢いで作りました。
さくらのVPS
さくらのVPSの仕様は以下の通りです。
メモリ | 512MB |
---|---|
HDD | 20GB |
回線 | 100Mbps |
OS | CentOS 5 x86_64 |
グローバル IP アドレス | IPv4 アドレス×1 個 |
データ転送量 | 無制限 |
管理者権限 | root 権限付与 |
データを継続的に保存するのにHDDが20GBと心許ないので古くなったデータはどんどん削除していく必要がありそうです。一方でデータ転送量が無制限となっているので、APIからの取得に(料金的な意味で)気を使う必要はなさそうです。
OSは最新のCentOS5.5で、サービスはsendmailとssh以外は何も入っていないので、httpdなどを自由に追加して利用します。また、ポートはすべて公開状態なのでiptablesを設定、有効にすることも必要です。
Twitter Streaming API
Twitter Streaming APIのstatuses/sampleメソッドを利用します。sampleメソッドは公開タイムラインの1%未満がサンプリングされたデータとなります。実際にアクセスをしてみると1分間に350〜650ツイート取得でき、量にかなりムラがあることがわかりました。
HDDの容量を考えて、データはcronで6分毎に1分間取得することにしたので、サンプルは1/6%、全ツイートの約0.167%未満になりそうです。数日間取得してみたところ、1日で約10万〜12万ツイートをサンプリングできています。
MongoDB
MongoDBはドキュメント指向DBと呼ばれる仲間で、Key-Value StoreにRDBMSの色を少し足したようなイメージです。スキーマはダイナミックに変更できる一方で、SQLこそ使えないものの、where, sort, limit, group(by), max, min,などが用意されていて、RDBMSに慣れている人にもとっつきやすいと思います。
さらに、スケールアウトを容易にするSharding機能を標準装備していて、分散したデータベースから複雑な集計ができるMap/Reduceが利用できます。
RDBMSでDBやテーブルにデータを入れようと思った時はあらかじめCREATEしておく必要がありますが、MongoDBは必要ないので存在しないDBやコレクション(RDBMSでいうテーブル)にいきなりデータを投入してもエラーは出ず、コレクションやDBすらダイナミックに作られます。この辺りの挙動はファイル操作に近いので、日付ごとにダイナミックにコレクションを作ることもでき、今回のログの保管などの用途にも適しています。
日付ごとにコレクションを作り、値にはtimestamp, date, source, source_url, time_zone, utc_offset, langを保存することにしました。Sharding環境ではないのでMap/Reduceの力を発揮することもできないのですが、実験的な意味で、データの集計にはMap/Reduce*2を利用しています。
使い方
デフォルトは1日前のサンプリングしたすべてのデータが表示されます。そこから、日付、Lang、Time zone、UTC offsetで絞り込みすることで様々な形で抽出することができます。
例えば、「8月12日のツイートの中から東京(time_zone=Tokyo)で日本語(lang=ja)のツイートをするのに利用されているクライアント」などを抽出・集計することができます。
ランキングだけでは味気ないので、TOP10を円グラフで表すのと、各クライアントが時間ごとにどのくらい利用されているのか3つまで比較出来る機能を用意してみました。住んでいるところやクライアントの種類で利用されている時間外が全然違うのがわかります。
現状、なかなかもっさりとした感じなので、イライラするかもしれません。
実験なので、負荷の問題でサービスを終了するかもしれませんし、逆に、作っただけではなくMongoDBのTipsやチューニングなどで改善し、それをさらにネタにして行きたいとも思っています。
*1 7月15日〜8月31日までクローズドベータとして会員限定でプレリリースされたホスティングサービス。2010年9月1日から初期費用無料、月額980円の「さくらのVPS 980」として正式リリースされる。
*2 今回の実験ではmapReduce()よりgroup()を使った集計の方が速度が速いことが多かったので、当日分のリアルタイム集計ではgroup()を利用しています。mapReduce()の結果は新しくコレクションとして保存することができるので、過去分に関してはmapReduce()で抽出→コレクションとして保存→そこから再集計という実装にしています。