サーバーサイドのアプリケーションで分散処理をさせる必要は本当にあるのか?

植山類氏:「では、大きな問題って何?」という話で、いくつか例を挙げてみたいと思います。これは必ずしもそうするべきという話ではなくて、エンジニアリングはトレードオフなので、すべての選択肢に良いところもあれば悪いところもあります。

ただ、検討もしない、最初から考えてもみないというのは、それはそれで正しいエンジニアリングとは言えないので、気づきを与えるという意味で「こういうふうに考えてみることもできるんじゃないの」という話をいくつかしたいと思います。

このセッションを見ている方で、サーバーサイドのアプリケーションを書いている人は多いと思うんですよね。サーバーサイドのアプリケーションは普通は分散処理として書いて、いろいろなプロセスを立ち上げて、VMとかを立ち上げて、Kubernetesでマネジメントしてみたいなかたちなので、分散処理的な難しさが必然的にあるわけです。

しかし、分散処理はほとんどの場合、信頼性を除けば分散せざるを得ないから分散しているだけであって、本当は単一のプロセスで1台のマシンで全部できるほうが簡単なわけです。RPCや他のマシンに何かを頼むのではなくて、単に関数呼び出しのほうがはるかに簡単なわけです。

それなら同じメモリを見ているわけなので、例えば難しいデータベースに何かをしまうんじゃなくて、単なるハッシュテーブルルックアップで済むようなものはたくさんあるわけなんです。現在のサーバーは恐ろしく強力で、非常にたくさんメモリを積むことができて、適切に設計されたソフトウェアであれば、すごく大きなサービスでも動かすことは実際には可能です。

なので「本当に分散する必要があるんですか?」を考えてみるのはいいことだと思います。一例として、例えば「Netflix」の最新のサーバーは、800GbpsでTLSで暗号化されたビデオをストリームできるそうです。800Gbpsはすごい帯域幅で、例えば1人あたり10Mbpsで動画を見ているとしたら、8万ユーザーを1サーバーに収容できることになります。

そうすると、Netflixを100万人が同時に見ているとして、12台しかサーバーがないことになるんですよね。100万人に動画を届けるのに12台のサーバーで済むんだったら「自分のところのサービスは、果たしてこんなにマシンがいるのかな?」と思ったりすると思います。まぁ、いろいろな目的があるので、Netflixみたいにカリカリにチューニングするというのもアレですけどね。

ただ、現代のサーバーはそれぐらい本当に強力です。なので、ちょっと考えてみるとおもしろいと思います。

「Webに対して不満があるからWebブラウザそのものに手を加える」は大げさか?

また別の話として、Webアプリケーションを書いている人も多いと思います。僕もWebアプリケーションを書いたこともあるし、書くのも好きです。Webアプリケーションは当然ながらWebの機能に依存していて、時々自分のやりたいことが素直に実現できなくて、苛立たしく感じることがあると思います。

「本当はすごく簡単にできるはずなのに、ブラウザ上ではなかなか素直にできない」みたいなもので、ワークアラウンドを実装してなんとかがんばる。例えば、1回サーバーに何かを送って返してもらってとか。いろいろなワークアラウンドを実装した上でも、やはりなお理想の使い勝手やUXやレスポンスタイムからは程遠いものになることは、よくあると思うんですよ。

それはしょうがないことだと捉えていると思うのですが、「本当にしょうがないんですか?」と考えてみてもいいと思うんですよね。

というのも、今の主要なブラウザはすべてオープンソースで、自分で変更を加えるのは無理というわけではないんですよね。「Webに対して不満があるからWebブラウザそのものに手を加える」というのは大げさすぎると思うかもしれないですが、そういうことをやっている人たちは、実際には何千人とか何万人いるわけです。なので、自分がやったことがないだけで、本当は別にそんなに大げさじゃないのかもしれないと思うんですよね。

あとは、存在していない状態から何かを足そうと思うと、すごく大げさに感じるかもしれないですが、振り返ってみれば当然あるべきだったと感じるような機能はたくさんあると思います。

例えば「YouTube」みたいな動画サイトは2005年ぐらいに一斉に立ち上がりました。なぜ2005年ぐらいに一斉に立ち上がったかというと、その頃にMacromedia Flashを普通にみんながインストールするようになって、ブラウザ上での埋め込み、今見ているようなかたちでビデオ再生がスムーズにできるようになったのが、そこらへんだったんですよね。

それ以前にもインターネット上でのビデオストリーミングはあったし、それを再生できるようなマシンパワーもないわけではなかった。帯域もないわけではなかった。けど、今みたいな使い勝手を実現するには2005年ぐらいまで待つ必要があったわけです。それを解決したのがマクロメディアなわけなんです。

今から振り返ってみれば当然のように感じるかもしれないですが、当時だったらどうかというと、それをやったのがマクロメディアぐらいしかなかったというわけなんですよね。なので、未来を先取りしてみると別にそんなにおかしなアイデアではないということは今でもたくさんあるわけで、それを考えると、ブラウザに手を入れるのもそんなに突拍子もないわけではないと思います。

Chromeブラウザも“大きな問題”の解決のために作られた

考えてみれば、Chromeブラウザみたいなブラウザ自体も、大きな問題を解決するために作られたソフトウェアなわけですよね。「Google Chrome」は2008年に発表されているのですが、2007年にGoogle社内でChromeブラウザを作っているという話を聞いた時に、正直けっこうビックリしました。

というのも、Googleはその時は今ほどには大きな会社じゃなかったし、クライアントサイドで動くアプリケーションはほとんど手がけていませんでした。基本的にはサーバーサイドで動くWebアプリケーションや、検索の会社というイメージだったので、ブラウザみたいな巨大なプログラムをいきなり作るのは野心的すぎるんじゃないのかと感じたのを覚えています。

それだけではなくて、正直な話、ちょっと迷惑なんじゃないのかなとすら思いました。というのも、「Internet Explorer」と「Firefox」の違いでWebアプリケーションを作るのがすでに面倒くさくなっているのに、そこに第三勢力をぶち上げて、よりカオスが広がるだけなんじゃないかなと思ったんです。が、やはり僕が間違っていたんですよね。

というのも、Chromeが解こうとしていた問題は、本当に解かれるべき問題だったわけなんです。2007年、2008年がどういう状態だったかというと、Microsoftがブラウザ戦争で勝ってNetscapeを叩き潰し、Firefoxのシェアがどんどん下がっていって……。Firefoxはそこまで下がっていなかったですが、IEが勝っている状態でMicrosoftはあぐらをかいていて、バグが多いし、機能は足りていないしと、ブラウザの進歩は停滞していたわけです。

Googleは、ビジネスモデル的にブラウザでできること自体が自分の会社でできることということで制限されているので、ブラウザを良くする必要があったんですよね。

その周辺で、例えばブラウザ以外の小さなプログラムを作るとかでなんとかがんばることも、できなかったわけじゃないとは思います。でもそうじゃなくて、「ブラウザがダメなんだったらブラウザを作ればいいじゃないのか」という、そういう大きな発想で大きな問題を解いて、挑戦してみて、その挑戦の結果はみなさんが今知っているとおりになっているわけです。なのですごいですよね。

クレイジーなアイデアでもやってみないとわからない

また別の例として、僕は次のプロジェクトとしてどれぐらいの規模のことを考えているのかを話したいと思います。現段階では考えているだけで本当に作るかどうかは決めていないですが、ただ、「こういうことを考えてもいい」「こういうことを検討してもいいんだ」という話として聞いてください。

僕は、lldとかmoldを作ることによって、リンクが遅いという問題は解決したわけです。しかし、プログラムのビルド時間が長いという問題は存在しているんですよね。なぜかというと、コンパイルが遅いからです。特にテンプレートをたくさん使ったC++プログラムとかだと、1ファイルのコンパイルに何十秒とかかかったり、ひどい場合には何分もかかったりすることがあります。

確としたことは言えないけれど、僕の心の中のどこかでは「これは何か本質的におかしい」という感覚があります。僕はGoogleのC++コンパイラチームで働いていたし、コンパイラを作ったことがあるし、コミュニティにも属しているので、コンパイラがどうして遅くなっちゃうのかはそれなりにはわかっているつもりです。

なぜ遅いかというと、コンパイラエンジニアにとっては、コンパイル時間を速くすること自体が一番のゴールではないんですね。どちらかというとコンパイルされたコードのクオリティを上げる、コンパイルされたコード自体を速くするのが大切で、コンパイラそのものの速度はみんなあまり重視していないんです。

コンパイルが遅いのは当然問題だとみんな薄々は思っていて、速くしたいとは思うのですが、それに対してすごく努力がなされているというわけではないんですね。正直、コンパイラの速度がどうなっているのかを誰も継続的に計測すらしていない状態です。そういう状態でみんなが改良を加えていくと、だんだんコンパイラが遅くなっていっちゃうわけなんです。というのも、誰もそこの点のクオリティを保とうとしていないので、遅くなっちゃって。しかも、1つのボトルネックがあって遅いとかではなくて、満遍なく遅くなっちゃうんですよね。

一度満遍なくすべての箇所で遅くなってしまったプログラム、本質的なデータ構造のレベルから遅くなっちゃったプログラムを速くするのは非常に困難で、実質的には不可能なレベルになります。なので、これはいわゆる体制的な問題なわけなんです。

逆に考えてみると、コンパイラの速度自体を一番のゴールに設定して、C++コンパイラを書き直せば、何十倍も速いレベルのものも狙えるんじゃないかと思うんですよね。数字自体に根拠があるわけではないですが、こんなに遅いのはさすがに何かおかしいと思うんですよ。

C++コンパイラをイチから書くのはクレイジーなアイデアみたいに聞こえると思います。僕もそう思わないでもないですが、本当のところはやればできると思うんですよ。やればできるかどうかは、やってみないとわからないです。

「やってみた人います?」という話になって、いろいろな人が「C++コンパイラをイチから書いてやるぜ」と言って、みんながダメとなったら「これはイチから書くのはかなり難しいね」となると思うんですが、挑戦したことがある人は世界的にはほとんどいなくて、数人……。「ここ10年で何人いるの?」という話だと思うんですよね。

最初から無謀だと思ってみんなやっていないだけで、本当に難しいかどうかはみんな知らなくて、意外と簡単かもしれません。簡単ということはないだろうけど、できないわけじゃないかもしれない。だから、おそらく一番足りていないのは、クレイジーな挑戦者だと思うんですよね。

(次回に続く)