MakingSenseofStreamProcessing / Example Implementing Twitter


Example: Implementing Twitter

要約

詳細

実例をもとに、もう少し具体的に考えてみよう。 第1章では、Twitterっぽいメッセージングサービスを実装するとしたら…ということを考えた。 読み込み操作の中でいちばん多いのが、いわゆる「ホームタイムライン」の表示リクエストだろう。 自分がフォローしているすべてのユーザーの最近のツイート(と、ユーザー名やアイコン画像)を表示するものだ(図1-17参照)。

そんな場合に使うSQLクエリを図1-18で見たが、あんなのを毎回実行するのでは速度が遅くなってしまうという結論だった。 事前にホームタイムラインの内容を算出して取得しておけば、ユーザーからのリクエストにすぐに答えられるようになる。 なんとなくマテリアライズドビューっぽく聞こえないだろうか?

Twitter並みの規模でマテリアライズドビューを作れるデータベースは存在しない。 でも、ストリームプロセッシングツールを使えば、マテリアライズドタイムラインを実装できる*1。 その概要を図5-20に示す*2

msos_0520.png

図5-20. ストリームプロセッシングツールを用いたTwitterタイムラインの実装

まずはすべてのデータソースをイベントストリームとして扱えるようにしなければいけない。そのためには、第3章でとりあげたCDCを用いるか、あるいは第2章で考えたようにイベントを直接ログに書き出せばいい。今回の例では、これら三つのデータソースからのイベントストリームを利用する。

Tweets
個々のツイートやリツイートがイベントとなる。ふつうに考えれば、これらはストリームとして扱えるものだ。
User profiles
ユーザーが表示名やプロフィール画像を変更するたびに、更新イベントが発生する。このストリームはログ圧縮しておく必要がある。そうすれば、すべてのユーザーの最新のプロファイルをストリームから再構築できるようになる。
Follow graph
誰かが他のユーザーをフォローしたりフォロー解除したりしたときにイベントが発生する。このストリームの履歴をたどれば、ある時点で誰が誰をフォローしているかを判断できる。

これらのストリームをKafkaに入れれば、マテリアライズドビューを作れる。 Kafka StreamsあるいはSamzaを使って、ストリームプロセッシングジョブを書けばいい。 たとえば、あるツイートが何回リツイートされたかを数えるジョブを書けば、マテリアライズドビュー"retweet count"を作れる。

ストリームをjoinすることもできる。 tweetsとuser profilesをjoinした結果は、一連のツイートに非正規化されたプロファイル情報(ユーザー名やプロファイル画像など)がぶらさがったストリームになる。 誰かがプロファイルを更新したときにそれをどこまで反映させるか(変更後のツイートにだけ繁栄させるのか直近の100ツイートにだけ反映させるのか、あるいは過去にさかのぼってすべてのツイートに反映させるのかなど)は、ストリームプロセッサの実装しだいでいかようにでもできる (まあ過去にさかのぼってすべて更新するのは非効率的だろうけど、そのへんはなんとでもなるでしょう)。

次に、ツイートとフォロワーをjoinしてみよう。 フォロー/アンフォロー イベントをとりまとめれば、あるユーザーXをフォローしているユーザーのリストを作ることができる。 Xが何かをツイートしたらそのリストをスキャンして、それぞれのホームタイムラインに新しいツイートを配送すればいい (Twitterではこれを"fan-out"*3と呼んでいる)。

「ホーム」タイムラインはいわばメイルボックスのようなもの。次にログインしたときにユーザーが見るべきすべてのツイートが、そこに含まれている。 ここでは、図1-18のSQLに相当するマテリアライズドビューを効率的に作った。 注目すべきは、SQLのふたつのjoinが図5-20におけるストリームのjoinに対応していること。 ストリームプロセッシングシステムは、いわばクエリを継続的に実行し続けているようなもの。

担当者のつぶやき

みんなの突っ込み



*1 Raffi Krikorian: "Timelines at Scale," at QCon San Francisco, November 2012.
*2 Martin Kleppmann: "Samza newsfeed demo," github.com, September 2014.
*3 Raffi Krikorian: "Timelines at Scale," at QCon San Francisco, November 2012.