8月 17

はじめに

さくらの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()で抽出→コレクションとして保存→そこから再集計という実装にしています。

Tagged with:
12月 08

yubitter』という携帯電話向けのTwitterクライアントサービス(ゲートウェイ)をsymfonyで作りました。(サービスの詳細はリンク先でご確認下さい。)

yubitter

cloudrop発のアウトプットとして開発に取り組んだもので、初めてのリリースとなります。
タイトルにはsymfonyと書きましたが、開発には数多くのオープソースソフトウェアのお世話になっています。

できる事ならyubitterもソースを公開したいのですが、利用しているライブラリのライセンスの確認、環境依存部分の抽象化、symfony1.4系への対応、ドイヒーなコードの修正などを行う必要があり、今は難しいところです。
最終的にはそういう諸々を乗り越えての公開を目指して行きたいと思っています。

事実上のモバイル向けクライアントの標準であるモバツイッターや、多機能でアジャイルなMovatter、さらには公式の携帯版がある中で、いまさら感の否めないサービスですから、サービス自体による貢献というよりも、サービスやシステムの内部を公開することによる貢献を目指していくつもりです。

そういう意味でも、開発・運用をするにあたっての裏話はどんどん公開していきたいと思います。

もちろん、魅力のないサービスは、システムとしても魅力がないのと同じなので、
サービスとしておざなりにするということではありません。

サービスに関する質問や不具合の報告などは、Twitterで受け付けております。
お気軽にお問い合わせください。(@ms76

最後に、利用させていただいているサービスやソフトウェアを紹介いたします。(順不同)
この場を借りて、感謝いたします。ありがとうございます。

インフラ

Rackspace Cloud Servers

Webサーバー、アプリケーションサーバー、DBサーバー、セッションサーバーとして利用。

Amazon S3

メールによる写真アップロードを受け取るストレージサーバーとして利用。

Amazon CloudFront

ストレージサーバーのフロントエンドとして利用。

OS・サーバー・ミドルウェア

CentOS 5.3

Rackspace Cloud Serversにて標準で選択できるOSを利用。

Apache 2.2.13、PHP 5.3.0

Webサーバー、アプリケーションサーバー(mod_php)として利用。

MySQL 5.0.77

DBサーバーとして認証用ユーザー情報、設定情報などの保存に利用。

Squid 2.6.STABLE21

外部API接続時のプロキシキャッシュサーバーとして利用。

Postfix 2.3.3

メール投稿、メール登録、メール送信時のメールサーバーとして利用。

flare 1.0.8

セッションサーバーとして利用。

PHP、PEARライブラリ

symfony 1.2.10

Webフレームワークとして利用。

携帯向けに下記プラグインを利用。

Mail_Mime 1.5.2、Mail_mimeDecode 1.5.1

受信したメールの処理に利用。

Net_IPv4 1.3.1

IPアドレスが特定のネットワークアドレスの範囲にあるかどうかの計算に利用。

Net_UserAgent_Mobile 1.0.0

携帯電話のUser Agentの取得に利用。

Amazon S3 PHP class 0.4.0

Amazon S3 APIとの通信に利用。

qdmail 1.2.6b

メール送信に利用。

TwitterOAuth library

Twitter APIのOAuth認証に利用。

QRcode image PHP scripts version 0.50g

QRコード生成に利用。

HTML_CSS_Mobile

外部CSSをインラインCSSに変換する際に利用。

Tagged with:
9月 14

ブログの更新をTwitterへ通知するのにFriendFeedを利用しているのですが、FriendFeedのクローラ―がフィードを取得しにくるまでTwitterへは通知されず、ひどい時は1日経っても通知されないことがありました。

これを解消するために、最近Googleによって開発・公開された新しいプロトコルPubSubHubbubに対応させました。

PubSubHubbubとは

PubSubHubbubは、今までの配信者(Publishers。以下、ブログ)と購読者(Subscribers。以下、RSSリーダー)が直接やり取りをしていたその間に、ハブ(Hubs)と呼ばれる中間サーバーを配置して、そのハブを介してメッセージのやり取りをWeb Hooksの仕組みで行うものです。
Web Hooksはある決められたアクション(たとえば、「ブログの公開ボタンを押す」など)をきっかけに動作して、決められたデータを決められたURLに決められた方法で送信する仕組みです。

いままで「更新されました?」「いや、まだです。」と304の繰り返しだったフィードの世界に、「更新したしました」きっかけで、購読者に一斉に通知が行くわけですから、こんなエコな仕組みはないと思います。

WordPressで対応するには

簡単です。プラグインを入れるだけです。
現在PubSubHubbubに対応させるためのプラグインは2つ出ていて、どちらも最新の2.8.4に対応していますし、機能的には同じですので好みで導入しましょう。

ハブのURLを登録するだけの簡単な設定画面で、しかもすでに2つのハブが登録されているので特に設定することはありません。

プラグインを有効にすると、出力されたAtomに
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="http://superfeedr.com/hubbub"/>
とハブへのリンクが追加されます。

ここから以下の流れで更新の通知がされるようになります。

  1. この新しいフィードを取得したPubSubHubbubに対応したRSSリーダーがハブへのリンクを読み取って、ハブに購読の依頼を行います。
  2. ハブは本当にRSSリーダーが依頼してきたのか確認します。確認ができたら次回の更新から通知するように動作します。
  3. WordPressで新しく記事が公開されたタイミングで、プラグインがハブに対して公開の通知を送信します。
  4. ハブは本当に記事が公開されたのか確認します。確認ができたら購読の依頼があったRSSリーダーへ通知を行います。

PubSubHubbubの実力

実際に前回の投稿がどのようになったかを追ってみました。

まず投稿後、ハブからチェックがきます(apacheのログ)。

64.233.172.18 - - [12/Sep/2009:18:42:23 +0900] "GET /feed HTTP/1.1" 200 14246 "-" "AppEngine-Google; (+http://code.google.com/appengine; appid pubsubhubbub)"

ハブのデバッグツールでハブにどのように登録されているか確認してみると、

ハブのデバッグツールのキャプチャ

無事登録されているようです。(クリックで拡大)

ではFriendFeedの方はというと、

FriendFeedのキャプチャ

WordPressの投稿ボタンを押して、登録が終わってから一拍おいてすぐ画面に現れたくらいの感覚です。

さて、本題のTwitterは

Twitterのキャプチャ

素晴らしい!画面の更新タイミングに影響していますがが、ほぼリアルタイム。

その他のPubSubHubbub対応サービス

FriendFeed以外にも、Google ReaderGoogle Alertslivedoor Readerなどが対応していて、確認できるGoogle Readerとlivedoor Readerでも確認してみました。

Google Reader

PubSubHubbubへの対応という記事は共有機能からということだったので、対応していないかもしれないと思ったんですが、

Google Readerのキャプチャ

時差なしできっちり更新に上がってきました。(クリックで拡大)

livedoor Reader

こちらは更新がされず…。

ライブドアリーダーのキャプチャ

PubSubHubbub対応後にlivedoor Readerのクローラが来ていることは確認しているので、腑に落ちないところです。

(※ 最初の更新でLDRがそのブログのpubsubhubbub対応を検出し,次の更新から更新情報を受けるようになるので,二回目の更新から反映が最速になります。)
PubSubHubbub で最速に更新を通知しつつ,舌をかまないためのテスト : nabokov7; rehash – livedoor Blog

ということなので、この更新から反映されるようになるかもしれません。
今回は確認できず。

2009/9/15 追記
やはりlivedoor Readerではすぐに更新されませんでした。
時間が経ってからの更新だとクロールによる更新なのか、ハブからの通知によるものなのか判断できないので、やはり確認できず。
livedoor Readerでちゃんとリアルタイムで更新されてるというパブリッシャーはいらっしゃるんでしょうか。livedoor Blog以外で。
ざっと調べてみたところ実践している方はいらっしゃいましたが、やはりリアルタイムでの更新は確認できていないようです。

わかりにくいPubSubHubbub

読み方の話ではなく。
複数の要素が絡まっているため、仕様が明らかとは言え、ブログ側からするとハブやRSSリーダーの挙動がわからず、更新が通知されない場合に理由がわかりにくい側面があります。

例えば、ハブへ購読依頼をするRSSリーダーが、エントリーが更新されているかどうかにかかわらず、フィード内にハブへのリンクを検出したらハブへ購読依頼をする仕様なのか(FriendFeedはこちらのようです)、エントリーが更新されたタイミングで検出・通知する仕様なのか(livedoor Readerはこちらのようです)、などです。

FriendFeedは前者のようなので、PubSubHubbub対応を行った後に、1度フィードを手動で読み込ませれば次のポストから反映されるはずです。

FriendFeedでフィードの手動取得

設定→サービス 追加/編集→マイサービスのリンクをクリック→Blogを更新(クリックで拡大)

まだまだ新しい仕組みなので、確立されるまでもう少し時間がかかるかもしれませんが、多くのサービスが対応してさらに便利になることを望みます。

参考サイト

FriendFeed→Twitterの詳しい説明が載っています。

PubSubHubbubに関する参考サイト

Tagged with:
preload preload preload