Tumblr における Scala

最近のウェブ系スタートアップが採用しているプログラミング言語やフレームワークまとめ とちょうど同じくらいの時期に High Scalability に Tumblr Architecture - 15 Billion Page Views A Month And Harder To Scale Than Twitter という記事がでていた。 まとめだと Tumblr は PHP を使っていることになっているけど、いま現在の Tumblr は PHP ですべてを書くのを止めて、Scala も使っているらしい。

Scala と Finagle

Tumblr はもともと LAMP (Linux + Apache + MySQL + PHP) で出来ていた。スケールさせるために memcached や HAProxy でキャッシュしてみたり、MySQL を sharding してみたり、バックエンドのサーバーを C で書いたり、Redis をいれてみたりしていたのを記事では Old Tumblr としている。

対して New Tumblr は「採用と開発スピード」のために JVM 中心のアプローチをとっている。PHP は薄いアプリケーション部分に、裏側は Scala に、つなぎには Finagle が採用された。Scala と Finagle を採用した理由については以下のように説明される。

  • Internally they had a lot of people with Ruby and PHP experience, so Scala was appealing.
  • Finagle was a compelling factor in choosing Scala. It is a library from Twitter. It handles most of the distributed issues like distributed tracing, service discovery, and service registration. You don’t have to implement all this stuff. It just comes for free.
  • Once on the JVM Finagle provided all the primitives they needed (Thrift, ZooKeeper, etc).
  • Finagle is being used by Foursquare and Twitter. Scala is also being used by Meetup.
  • Like the Thrift application interface. It has really good performance.
  • Liked Netty, but wanted out of Java, so Scala was a good choice.
  • Picked Finagle because it was cool, knew some of the guys, it worked without a lot of networking code and did all the work needed in a distributed system.
  • 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. With Scala you can use all the Java code. There’s not a lot of knowledge of how to use it in a scalable way and they target 5ms response times, 4 9s HA, 40K requests per second and some at 400K requests per second. There’s a lot in the Java ecosystem they can leverage.
  • 社員はみんな Ruby や PHP の経験があったので、Scala は魅力的だった。
  • Finagle は Scala を選ぶ強い理由になった。 Twitter が開発したライブラリで、分散システムのほとんどの問題、分散トレーシングやサービスのディスカバリ、登録などをやってくれる。こういったことを自分で実装する必要がないし、無料で使える。
  • Finagle が必要なすべて (Thrift, ZooKeeper など) を提供してくれた。
  • Finagle は Foursqure と Twitter で、Scala は Meetup でも使われている。
  • Thrift のアプリケーションインターフェースは好きだ。パフォーマンスがとても良い。
  • Netty も好きだけど、Java は使いたくなかった。こういう場合に Scala は良い選択肢になった。
  • Finagle をえらんだ理由は、クールだったってのもあるし、開発者に知り合いも何人かいたし、ネットワークまわりのいろいろなしでも、分散システムに必要なことは全部やってくれるというのもある。
  • Node.js を選ばなかったのは、Scala + Finagle のほうが JVM の基礎があるチームには広めやすかったというのがある。Node.js はまだ開発が進んでいなくて、標準やベストプラクティス、よくテストされた沢山のコードというのがない。Scala なら、Java のコードが使える。Node.js にはどうやってスケーラブルに、5ms のレスポンスタイム、99.99%の可用性、毎秒4万から40万のリクエストを実現するか、ということについてあまり知見が無い。Java のエコシステムには Tumblr で使えるような、それらの知見があった。

他にも Redis, HBase の部分的な導入や、Internal Firehose といっている内部向けアクティビティストリーム、scatter-gather (表示時に SELECT してかき集める) から inbox (配る) アプローチへの転換、Cell といっている、ユーザーごとの MySQL sharding をアプリケーションでやるような考え方 (Alice は Cell A の memcached, MySQL, Redis を、Bob は Cell B の memcached, MySQL, Redis を使う、みたいに閉じたセットをつくる) など、おもしろいところはいろいろあるんだけど、今回は Scala の話をします。

Scala をどこで使うのか

Scala をつかっている Web サービスだと、他には Foursquare と Twitter がある。Foursquare は Lift をつかって上から下まで Scala のはずなので、Tumblr のアプローチは Twitter の「表は Ruby, 裏は Scala」というのに近いと思う。

これは単に歴史的な事情なんだろうか? Twitter の Nick Kallen さんは2011年3月の InfoQ のインタビュー で「どういった種類のアプリケーションやシステムが Scala に、どういったものが他の言語に向いていると思うか」と聞かれ、こう答えていた。

That’s a great question, but it’s very subjective. I’ll give you my personal opinion and I wouldn’t necessarily say it’s everyone’s opinion at Twitter. I think Scala’s sweet spot is network services. I think one way of describing how network services work is that they have a very strict or constrained interface, like usually an RPC layer is a very tight protocol with very few procedures or methods to invoke. But the implementation of those methods is very sophisticated. Often it will involve partitioning strategies or a sophisticated use of the file system or something like that. A system like that has an interesting property as a small surface area of the protocol, but sophisticated implementation. A rich type system or a rich statically typed language, in my judgment, is a real boon for those kinds of problems.

I’ll contrast that with building a website. When rendering web pages, often you have very many components interacting on a web page. You have buttons over here and little widgets over there and there are dozens of them on a webpage, as well as possibly dozens or hundreds of web pages on your website that are all dynamic. With a system with a really large surface area like that, using a statically typed language is actually quite inflexible. I would find it painful probably to program in Scala and render a web page with it, when I want to interactively push around buttons and what-not. If the whole system has to be coherent, like the whole system has to type check just to be able to move a button around, I think that can be really inflexible.

いい質問ですね。でも人によって答えは分かれそうです。個人的な意見をいいます。Twitter の皆の意見というわけじゃないですよ。私は Scala のスイートスポットはネットワークサービスだと思います。ネットワークサービスというのは、非常にかっちりとした、制限されたインターフェースをもっているものです。RPC レイヤ上のきっちりとしたプロトコルに、ごく少数の手続きとかメソッドが呼び出される、みたいにね。でもこれらのメソッドの実装はとても洗練されています。パーティショニングとか、ファイルシステムを洗練されたかたちで使うとか、そういったことですね。システムが、その特徴として、小さな表面としてのプロトコルと、洗練された実装を持っている。強力な型システムや、強力な静的型づけ言語は、この種のシステムにとって利があると思います。

これを Web サイトを作るのと比べてみましょう。ページをレンダリングするときは、沢山の種類の部品がページ上でやりとりします。ボタンがここらへんにあって、小さなウィジェットがあっちと、あそこにあって、そういうのが数十個もページ上にある。あなたのサイトのうち、たぶん数十や数百のページが動的なものです。こういう大きな表面部分があるようなシステムを、静的な型づけ言語でやるのは、すごく柔軟性を損なってしまいます。対話的にボタンを押して回るようなものを作るときに、Scala でやるとしたら、たぶん苦痛なことになるのではないかと思っています。システム全体がかっちりしていて、ボタンを動かすためにも型チェックがなんてことになったら、それは非常に柔軟性を欠くものになるでしょう。

私が英語を読めていないのかもしれないけど、個人的にはこの感覚はあまり共有できていない。表も Scala でもいいんじゃないかと思う。

もちろん Twitter の総意でない Nick Kallen さんの話は Scala の人々の総意でもなく、Scala の設計者 Martin Odersky 先生がチーフアーキテクトを勤める Typesafe では (CoffeScript や LESS まで使える) Web アプリケーションフレームワークの Play を推している。