@kyanny's blog

My thoughts, my life. Views/opinions are my own.

highscalability.com の Tumblr のアーキテクチャについての記事を読んだ

High Scalability - High Scalability - Tumblr Architecture - 15 Billion Page Views a Month and Harder to Scale than Twitter を読んだ。すごく面白かった。 Kindle で引用したところを中心にメモ。

Tumblrソーシャルグラフの特徴

The graph for Tumblr users has hundreds of followers. This is different than any other social network and is what makes Tumblr so challenging to scale.

Tumblr だと follower が数百人いるユーザーはザラにいる。 follower の多いユーザーの post は多くのユーザーの Dashboard に表示されるのでスケールさせるのが難しい。これは他の著名なソーシャルネットワーキングサイトに比べて特徴的な部分だという。

Tumblelogs と Dashboard

Public Tumblelog is what the public deals with in terms of a blog. Easy to cache as its not that dynamic.

インターネットに公開されるブログの部分は簡単にキャッシュできる。

Dashboard is similar to the Twitter timeline. Users follow real-time updates from all the users they follow.

対して Dashboard は Twitter のタイムラインのようなもので、ユーザーごとに違うデータを表示しなければならず、高いリアルタイム性が要求される。削除された post が誰かの Dashboard に残ってしまうなどを避けるため一貫性も重要。ここが Tumblr のシステムで一番キモとなる難しい部分らしく、後のほうでかなりの文量を割いてどのようにスケールさせているか詳しく説明されている。

Old Tumblr

When the company started on Rackspace it gave each custom domain blog an A record. When they outgrew Rackspace there were too many users to migrate. This is 2007. They still have custom domains on Rackspace. They route through Rackspace back to their colo space using HAProxy and Varnish. Lots of legacy issues like this.

最初はユーザーの独自ドメインブログに A レコードを設定していたので、データセンターを変えるとき移動させることができず、いまもそれらの独自ドメインは Rackspace のサーバを指したままだとか。 HAProxy と Varnish を使って新データセンターで稼働しているアプリケーションにルーティングしている。こういうレガシーなアレが他にもたくさんあるよ、と。ここはたぶん、薄ら笑いを浮かべるところ。

New Tumblr

Changed to a JVM centric approach for hiring and speed of development reasons.

(コアなアプリケーションが PHP で書かれてる現状から) JVM を中心に置いたアーキテクチャになった。理由は採用と開発スピードアップのため、と読んだけど、ここはちょっとよくわからない。 PHP プログラマより Scala プログラマのほうがマシだから、みたいな dis りなのか?(たぶん違う、けどいま Scala をばりばり大規模システムの業務で書けるプログラマは優秀だろうとは思う)

このあと Scala と、 Twitterオープンソースにした Finagle を使って非同期システムを作って運用してるぜ、という話が続く。あと Thrift がどうとか。正直 JVM まわりの話はサッパリなのでななめ読みしたし、よくわからなかった。 Finagle はあの Twitter の production 環境で動作実績があるから信用できる、とか言っていた。なんで Scala なのかというのは、 JVM な世界のミドルウェアとかは実績もあるから使いたいけど but wanted out of Java なんだそうで。

Node.js wasn’t selected because it is easier to scale the team with a JVM base. Node.js isn’t developed enough to have standards and best practices, a large volume of well tested code.

Node.js は選ばなかった。 JVM ベースのアーキテクチャで十分スケールしてるから。 Node.js はまだ標準と呼べるほど完成されていないし、ベストプラクティスも不十分だ(大規模環境での稼働実績とかノウハウが少ないという意味だろうか)と悪口を言ったあと Scala への賞賛が続く。まぁ一番の理由は「Java の資産が使えること」っぽいけど。 Java 好きなんだか嫌いなんだか。

Newer, non-relational data stores like HBase and Redis are being used, but the bulk of their data is currently stored in a heavily partitioned MySQL architecture. Not replacing MySQL with HBase.

HBase や Redis といった NoSQL も使ってるけどオリジナルデータはパーティショニングした MySQL に入れてるし HBase で置き換える気はない。

Problem with MySQL and sharding for time series data is one shard is always really hot.

MySQL での(データの時刻をキーとした) sharding は特定の shard だけにアクセスが集中するのが問題。

MongoDB is not used even though it is popular in NY (their location). MySQL can scale just fine..

MongoDB は NY じゃ人気があるけども、使ってない(Tumblr は NY にあるらしい) MySQL はよくスケールするよ、と。

このあとまた Scala と Finagle の話。 Actor モデルを使ってたけど途中からやめたよとか書いてあるんだけど何言ってるかわからなくて悲しい。

あと内部用に Firehose があってね、という紹介。 Firehose って Twitter の限定された API のことかと思ってたけど、 Twitter 特有のものではなかったのね。こいつがリアルタイムなデータ配信のキモになっているらしいがこの次の Cell Design がこの記事のハイライトともいうべき一番面白い部分なので前座は省く。

Cell Design For Dashboard Inbox

まず前提として、現状の Dashboard は scatter-gather モデルで作られている。これは「データをばらまいて」から「かき集める」ということで、データつまり post は sharding されて保存され(ばらまく)、ユーザーの Dashboard を組み立てるために shard から都度取得される(かき集める)。このモデルは非常に限られた間しかうまく稼働しないと見ていて、もう長くないかもね、と言っている。

The solution is to move to an inbox model implemented using a Cell Based Architecture that is similar to Facebook Messages.

そこでどうするかというと、 inbox モデルへ移行するらしい。 inbox モデルとはどういうことか、という説明もこのあと出てくるのだけど、先に触れておくと、各ユーザーは自分の Dashborad にどの post が表示されるべきか、 post ID が記録された inbox を持っていて、だれかが何かを post するとその post を購読しているユーザー全員の inbox に post ID が書き込まれる、という仕組み。まぁ名前の通りメールの inbox なのだけど、 post そのものではなく post ID だけが記録されるのでストレージ容量を相当節約できるんだとか。これのいいところは、 Dashboard を組み立てるときにいちいち following/followers の関係を user ID から引っ張ってきて、それで得られたすべての user の post ID を集めて・・・という、検索処理が重い問題を解決できる点にある。で、それを Cell Based Architecture で実装していて、それは Facebook Messages のやり方に似てるんだそうで。

Solves the scatter gather problem because it’s an inbox. You just ask what is in the inbox so it’s less expensive then going to each user a user follows. This will scale for a very long time.

さらっとだけど、なぜ inbox がいいのかという説明をしてある。上のパラグラフに書いたような内容。このやり方は相当長くもつはずだ、と。

そして Cell とは何か、という核心に触れていく。ここはドキドキしながらページをめくるところですよ。まぁ原文は一ページなのでめくれないしおれは Kindle で読んだのでやっぱりめくった気はしないけど。

A cell is a self-contained installation that has all the data for a range of users. All the data necessary to render a user’s Dashboard is in the cell.

一つの Cell にはある範囲のユーザーの Dashboard を表示するのに必要な全てのデータが入っている。

Users are mapped into cells. Many cells exist per data center.

ユーザーは Cell のなかに分布していて、ひとつのデータセンターのなかに複数の Cell がある。ちなみにここよりずっと前のほうで Tumblr runs in one colocation site. Designs are keeping geographical distribution in mind for the future. とあり、いまのところ複数データセンターに分散してはいないらしい。 Cell は HBase とか Redis を擁していて、とかの話が少し続く。

Request flow: a user publishes a post, the post is written to the firehose, all of the cells consume the posts and write that post content to post database, the cells lookup to see if any of the followers of the post creator are in the cell, if so the follower inboxes are updated with the post ID.

で、動作の仕組みについて。ユーザーがなにか post すると、 post が firehose に書き込まれる。そして全ての Cell が post を受け取って自分自身の post 用データベースに内容を書き込む。 Cell はその post の投稿者の follower が Cell のなかにいるか調べて(ユーザー(の inbox)は Cell のなかに分布していて、 Cell ごとに格納されているユーザー(の inbox)が分かれている、という話を思い出すこと)、存在すれば該当する followers の inbox に post ID を書き込む。

The key idea that is easy to miss is: all posts are replicated to all cells.

重要なのは、「全ての post は全ての Cell に複製される」ということ。

Each cell stores a single copy of all posts. Each cell can completely satisfy a Dashboard rendering request. Applications don’t ask for all the post IDs and then ask for the posts for those IDs. It can return the dashboard content for the user. Every cell has all the data needed to fulfill a Dashboard request without doing any cross cell communication.

全ての Cell は post のデータを持っているので、自分自身が持っているデータだけで Dashboard を組み立てることができる。他のどの Cell とも相互にやり取りする必要がない(ここが sharding に対する優位点だということだろう)アプリケーションはあるユーザーの Dashboard に表示されるべき post ID を問い合わせる必要がない(inbox に書いてあるから)そして post を ID で引くだけでいい(ここは RDBMS なら primary key だし KVS なら単に key で引くだけなのでコストが低い)

Two HBase tables are used: one that stores a copy of each post. That data is small compared to the other table which stores every post ID for every user within that cell.

(Cell ごとに) HBase テーブルが二つあって、片方に post のコピーが入っている。これは、 Cell のなかにいるユーザー全員に対する全 post ID のデータサイズよりも小さい?ちょっと読みきれてないけど、要するに post の本文データは ID のリレーションデータよりもサイズが小さいということ。これは意外に思えるので、あとでまた取り上げられる。

それから inbox には post そのものじゃなくて post ID を入れてるのでデータサイズをおさえられて、なので各 Cell に post を全部突っ込んでも大丈夫なんだぜと。 Surprisingly posts are smaller than the inbox mappings. Post growth per day is 50GB per cell, inbox grows at 2.7TB a day. Users consume more than they produce. ということらしく、 post よりも inbox のサイズのほうが桁違いにサイズが大きくなる(この数字は per day なのでいかに巨大なデータサイズかわかる)「ユーザーは自分で作り出す以上に消費している」というのはちょっと皮肉っぽいけど、 Tumblr には reblog とかもあるのでそもそも大量消費させるようなデザインじゃん、と言いたくなる。

あとは followers がメチャ多いユーザーがいたりとか、 sharding だと特定の shard が落ちるとその shard にあるデータはサイト全体でみれなくなるので影響がでかいけど特定の Cell だけ死んでもサイト全体は死なないので可用性が高いとか、いろいろな話が続く。

Team Structure

ここはおおっと思った。 Tumblr チームを「どういう仕事をしてるか」で分けて定義しているのだけど、 DevOps よりさらに細かく分類していて、それらの守備範囲が明確なので、この分類を知ってる人同士だと「おれは Platform 的なことやっててさ」とか話が通じやすいかなと思った。あんまり細分化するのは是非があるだろうけど。

Platform: core app development, SQL sharding, services, web operations.

ちなみに Platform にだけ触れたのは、おれの専門とか興味関心がある部分はこの分類だとここかなぁ、と思ったからです。

Software Deployment

まぁ大規模サイトがどこもたどったようなデプロイにまつわるいろんな苦労話と工夫が書いてある。

All features run in dark mode before activation.

dark mode ってのをカンで解釈すると、これは Cookpad が採用してるのと同じ手法っぽい。そういえば Flickr も新機能のオンオフを司るフラグがたくさんあるとか書いてあったのをむかし読んだ。ある閾値を超えてでかくなるとこういうやり方に収束していくものなのかもしれない。どっちかというと、ソフトウェアのサイズというよりは開発チームのサイズによるのかなぁという気もする。ソフトウェアがでかくなりすぎて把握しきれなくなるというのもあるんだろうけど、関係者が多くなりすぎて全ての開発プロセスをマネージャ個人が把握しきれなくなるのでバッティング事故が防げなくなる、みたいな。そういうスタイルのシステム開発に関わったことはないので想像に過ぎないけど。

Development

Started with the philosophy that anyone could use any tool that they wanted, but as the team grew that didn’t work.

最初はみんな好きなツールを使って開発してたけど破綻したと。まぁそうですよね・・・。

Every developer has a preconfigured development machine. It gets updates via Puppet.

全ての開発者には開発環境が設定済みの開発マシンが与えられ、その環境は Puppet で自動的にアップデートされる。開発マシンというのが Linux (CentOS と Scientific Linux を採用してるらしい)の VM とかなのか、 MacBook とかなのかはわからないけど、徹底しているなぁと思った。 Puppet とか書いてあるのでなんかかっこよさげだけど、大手企業の「Windows アップデートはシステム本部が検証後に社内 LAN を通じて自動配布するので自前では適用するな」みたいなのを彷彿とさせて、ちょっとベンチャーっぽくなくてやだなあと思った。

Developers use vim and Textmate.

ハァ??? Emacs は???おれ絶対 Tumblr では働かないわ・・・(そもそも無理です)

Hiring Process

Architecture についてのインタビュー記事だったはずなのに採用の話が出てきちゃったけど結構いい話だったのでよしとする。まぁ Emacs 使えないらしいけどね。

Interviews usually avoid math, puzzles, and brain teasers. Try to ask questions focused on work the candidate will actually do.

数学とかパズルとか知能クイズみたいな面接はしないよ、と。コンピュータサイエンスの素養に乏しい全世界のウェブ技術者の安堵の溜息が聞こえるようだ。

Focused on coding. They’ll ask for sample code. During phone interviews they will use Collabedit to write shared code.

Focused on coding. くぅーかっこいいーいつか自分が面接する側になって「御社の採用はどのような方針に基づいているのですか?」とか記者に質問されてドヤ顔で言ってみたいわー。というのは冗談だが、電話面接中も画面共有ソフトか何かを使って候補者が書いたコードを見るという姿勢は立派だなと思った。

Candidates get to use all their tools, like Google, during the interview. The idea is developers are at their best when they have tools so that’s how they run the interviews.

候補者は面接中に自分の好きなツールを使えるし、グーグルで検索したりしてもかまわない。候補者が面接で最高のパフォーマンスを発揮するには普段使っているものを使えたほうがいいから、と。日本企業の人事担当者が聞いたらどんな顔するんだろう。個人的な意見だけど、面接でコードを書いてねと言われて「普段と違う開発環境だとうまくやれそうにないので、自分のマシンを持ち込ませて欲しい」と言ってくる候補者がいたらそれだけでけっこう期待していいんじゃないかなぁという気がしている。環境に無頓着なひとよりはこだわりがあるひとのほうがプログラミングとかに強い関心を持っているだろうし、そういう人のほうが独学で勉強したり良い習慣をみにつけている可能性が高いと思う。まぁ弘法筆を選ばずという言葉もあるので、こだわりと能力の高さは比例しないんだろうけど、意識の高さ(揶揄じゃなく)とは相関があると思う。

Lessons Learned

この段落はなんだろう、まとめ?

Read papers and blog posts. Key design ideas like the cell architecture and selective materialization were taken from elsewhere.

論文やブログを読もう。 Cell のような重要なデザイン上のアイデアはどこかよそのうまくやってるところからやってくるものだ。これは本当に徹底してるっぽくて、 inbox の話にかぎらず、最近でてきた新しいテクノロジーやミドルウェアをいろいろ採用しているけど、用途と自分たちのニーズを見極めて本当にフィットするものだけを選んでいる様子がうかがえた。 LinkedIn の Kafka という(Hadoop とか MongoDB とかオライリーから本が出てるような人気のあるプロダクトよりはマイナーそうな)分散メッセージングシステムを使ってる一方で、流行りの MongoDB は使ってない(かわりに Redis)とか、たぶん業界のいろんなプレイヤーの動向をよくチェックしているし、それに振り回されないのは常に自分たちのシステムが次に必要とするものは何か、について考えているからなんだろうなと思う。

このブログエントリのまとめ

High Scalability - High Scalability - Tumblr Architecture - 15 Billion Page Views a Month and Harder to Scale than Twitter を読んで、印象に残った箇所を引用し、多少の邦訳を添えて感想を書いた。とても面白かった。けっこう長いけど、触れなかった部分も多いし、技術者にとってはそこまで難解な内容でもないはずなので、時間を作って読んでみるといいと思う。 Emacser のひとは興奮のボルテージがあがりきったところで奈落の底に突き落とされてさめざめと泣けばいいと思う。

一番大事な感想を書き忘れてたんだけど、

se-mi おもしろいけどあまり参考にならない..

http://b.hatena.ne.jp/se-mi/20120219#bookmark-81495453

これホントにその通りで、 Tumblr のコピーを作るのでもない限りこの構成を真似る意味はないし、部分的に取り入れるのもそれはそれで難しそう。結局、あるラインを超えて大きくなったウェブサイトは、同じものが二つとない特別なシステムなので、たったひとつの冴えたやり方でスケールしたり成長したりするもんではないのだな、というごくごく当たり前の感想を抱いた。そこから学べるとしたら、「いいものは取り入れろ、ただし猿真似はするな」ということと、たとえ流行りの技術を取り入れてなかったとしても、最適だと考えるものを使うのに遠慮することはなくて、堂々としていればいいんだということなのかな、と思った。