いかにしてウィキペディアを編集する際の速度を二倍にしたか

[How we made editing Wikipedia twice as fast](http://blog.wikimedia.org/2014/12/29/how-we-made-editing-wikipedia-twice-as-fast/)という記事を翻訳しました。ライセンスは[Creative Commons Attribution 3.0 unported license](https://creativecommons.org/licenses/by/3.0/)です。画像も、注意点がない限り、同じか、画像のリンク先のライセンスを確認してください。間違いだらけだろうから、何かあったら、ぜひコメントください。

***


[![File:Definition of 'wiki' in Andrews' Hawaiian dictionary (1865).png](https://upload.wikimedia.org/wikipedia/commons/f/f5/Definition_of_%27wiki%27_in_Andrews%27_Hawaiian_dictionary_%281865%29.png "Lorrin Andrews, A Dictionary of the Hawaiian language, 英語-ハワイ語の語彙と、その定期的な時系列 Printed by Henry M. Whitney, Honolulu H.I., 1865. (Via [Google Books](https://books.google.com/books?id=jRRKAAAAcAAJ&pg=PA514#v=onepage&q&f=false))")](https://commons.wikimedia.org/wiki/File:Definition_of_%27wiki%27_in_Andrews%27_Hawaiian_dictionary_(1865).png)



"ウィキ"とは速いという意味だった...
----

[ウィキ](https://en.wikipedia.org/wiki/Wiki)を開発したWard Cunninghamは、素早く簡単に編集できるウェブページを作りたかった。Cunninghamは自身のソフトウェアにハワイ語の「速い」という言葉をつけた。それがウィキメディア財団がウィキペディアの編集のソフトが二倍になったことを広く知らせる理由だ。過去6ヶ月間、PHPのコードを使ったウィキペディアの裏方であるメディアウィキの速度をあげる新しい技術に取り組んでいた。HipHop Virtual Machine(HHVM)は、編集者がページの保存する際にかかる時間の中央値を7.5秒から2.5秒に、平均時間を6秒から3秒に減らした。以下では、メディアウィキ上のHHVMや、パフォーマンス向上のもたらす広範囲のメリットについて述べる。

[![Wikimedia HHVM deployment - Average Edit Save Time, in Milliseconds.png](https://upload.wikimedia.org/wikipedia/commons/d/df/Wikimedia_HHVM_deployment_-_Average_Edit_Save_Time%2C_in_Milliseconds.png "")](https://commons.wikimedia.org/wiki/File:Wikimedia_HHVM_deployment_-_Average_Edit_Save_Time,_in_Milliseconds.png)


ウィキペディアを素早くすることが、どういう風にウィキペディアの下落傾向を食い止めるか
----

ウィキペディア及び他のウィキメディアサイトには、毎月5億人近い人がアクセスする。しかし、ウィキメディア財団は、他のトップウェブサイトと比べて、予算もスタッフも少ししかない。そうなると、どうやって十分な速度を利用者に提供できるだろう? ウィキペディアの始め以降、その答えは、キャッシュメモリを使うことだった。利用者に近いデータセンターにあり、それぞれが1秒あたり数千人の閲覧者を処理できる百以上のサーバーにウィキペディアのページの静的コピーを置いたのである。

この戦略は、ウィキペディアに利用者の動きを1秒あたり数万ページビューまで拡大させた。(要確認)その一方、サーバーやデータセンターの費用を低下させた。最初の[Squid](https://en.wikipedia.org/wiki/Squid_(software))キャッシュサーバーは、2004年にボランティア開発者であるGabriel Wickeが設置した。現在ウィキメディア財団のPrincipal Software EngineerになっているGabrielは、Ulrich Wickertが[ドイツのゴールデンタイムのテレビでウィキペディアが最初に取り上げた](https://www.youtube.com/watch?v=Wm9zBciQjBM)時に、ページのリクエストが20/秒から1500/秒に上がってもSquidが難なくさばいたことを今でも思い出す。キャッシュはエレガントな解決法であるけど、すべての利用者の要望に応えることはできない。リクエストの2から4%は、キャッシュ経由では処理できず、(キャッシュされていない)アプリケーションサーバーで処理する必要のある利用者が必ずいた。これには、アカウントへログインする人が含まれ、そうした人たちにはウィキペディアのカスタマイズしたバージョンが表示されるため、利用者が編集する際に送られるリクエストと同様に、静的なキャッシュのコピーでは賄えなかった。

これは、ウィキペディアを編集する際の利用者の体験が、メディアウィキのアプリケーションサーバーのパフォーマンスと直接つながっていることを意味する。こうした利用者は、どんなウィキでもその原動力である。彼らは、読む際にほとんどログインしているだけでなく、コンテンツの投稿、編集する人たちである。サイトの、素早いキャッシュされたページを見る多くの訪問者と違って、私たちの重要な利用者、投稿者はウィキのパフォーマンスが落ちてきているのを少なからず感じてきた。

速度が意味するもの
----

メディアウィキは、オープンソースソフトウェアで動作している大規模ウェブサイトでアドバンテージのある、[型チェックの弱い](https://en.wikipedia.org/wiki/Loose_typing)動的言語であるPHPで書かれている。PHPは柔軟な言語で、素早いプロトタイピングに向いていて、入門の障壁が低く、新人の開発者が比較的簡単に参入できるようになっている。と同時に、PHPは、よく知られたパフォーマンスの問題など、幾つかのデメリットも抱えている。

サーバーだけを単純に追加していくだけでは、この問題は解決しない。[シングルスレッド](https://en.wikipedia.org/wiki/Thread_(computing))言語であるPHPは並行処理できない。つまり、ひとつの処理がCPUを占領してしまい、複数コアへ拡張してスピードアップすることができない。それに、シングルCPUのクロップスピードは過去10年大きな進化を見ていない。メディアウィキが新しい編集機能を備えて成長するにしたがって、ウィキペディアのコンテンツは相当複雑になり、編集の際のパフォーマンスは低下した。

ウェブサイトの応答時間が少しでも遅れる(0.5秒とか)ことは、利用者の継続性が[劇的に落ちる](http://glinden.blogspot.com/2006/11/marissa-mayer-at-web-20.html)[可能性](http://radar.oreilly.com/2009/06/bing-and-google-agree-slow-pag.html)を示していた。結果、GoogleやFacebookといった人気のウェブサイトは、人気を維持するために、率先してサイトのパフォーマンスに大きく投資することになる。Friendstarのような以前の人気のサイトは、この問題で[忘れられることになった](http://www.nytimes.com/2006/10/15/business/yourmoney/15friend.html?_r=0&pagewanted=all)。編集者コミュニティをフォローして、ミッションを貫徹するために、ウィキペディアやその姉妹プロジェクトが利便性に優れたものになることは、ウィキメディア財団の優先事項となっている。

ウィキメディア財団のパフォーマンスエンジニアとして、私(Ori Livneh)は、一度Ward Cunninghamに、「ウィキ」という語にある「速さ」という意味は、どのようにウィキというソフト自身の速度に関連し、goes beyond that to mean the speed with which someone can translate intent to action(未訳)と聞いたことがある。彼は、このように[答えた](http://code.fed.wiki.org/view/wiki-is-quick)。

> 「そうだ。私が感じている"速さ"には、自分を表現する際にすることすべてが含まれていた。私は、httpd(ウェブサーバー)で直接ホストする素のHTMLよりも、[vi](https://en.wikipedia.org/wiki/Vi) (高速で動くテキストエディタ)で記事を編集してきた。この単純さをもってしても、自分の考えの流れを断ち切ることなく、二つのページに自分の考えを分断することは苦痛だった」

Wardは、どのようにして、自分の発明で最初の15から20ページを作った後、[ウィキウィキウェブ](https://en.wikipedia.org/wiki/WikiWikiWeb)、要するにとても速いウェブというネーミングにたどり着いたかを説明してくれた。

[![File:Wikimedia HHVM deployment - Average Page Load Time in Milliseconds, Logged-in Users.png](https://upload.wikimedia.org/wikipedia/commons/7/73/Wikimedia_HHVM_deployment_-_Average_Page_Load_Time_in_Milliseconds%2C_Logged-in_Users.png "")](https://commons.wikimedia.org/wiki/File:Wikimedia_HHVM_deployment_-_Average_Page_Load_Time_in_Milliseconds,_Logged-in_Users.png)

HHVMはこの問題にどう取り組んだか
----

幸運なことに、ウィキペディアだけが、この古い問題に直面した、PHPで書かれたトップテンサイトではなかった。このうちの最大のものである[Facebook](https://www.facebook.com/)は、このPHPのパフォーマンスの問題に取り組んで、[HipHop Virtual Machine (HHVM)](https://en.wikipedia.org/wiki/HipHop_Virtual_Machine)と呼ばれる、標準の[Zendインタプリタ](https://en.wikipedia.org/wiki/Zend_Engine)を含む以前の解決策よりも格段に素早いPHPの別実装を作ることで解決した。

PHPは動的なインタプリタ言語であるため、C言語のようなコンパイル言語に比べた時、すべてのインタプリタ言語の持つ欠点を抱えている。HHVMは、[just-in-time (JIT) compiler](https://en.wikipedia.org/wiki/Just-in-time_compilation)を使ってプログラムが動作している間にコードのコンパイルを最適化することで、PHPから高いパフォーマンスを引き出すことができる。HHVMのJITは、PHPは動的な型付け言語であるけど、実際はPHPプログラムを通じて型の流れはあまり動的じゃないということに基づいている。HHVMは動作前に型を観測し、これらの型に応じた動作に最適化されたコードを出力する。


HHVMはまだPHPインタプリタの役割を果たし、事前のコンパイルコード無しに起動時に即座にリクエストを提供する。しかし、動作中は、HHVMは最適化の機会を探すためにコードを分析する。最初の数回は一部コードが実行され、HHVMは全く最適化しない。最もありふれた方法で動作させる。しかし、そうしている最中、様々なコードが実行を要求される回数をカウントし続け、プログラム中の「ホットな」(良く呼び出され、実行に負荷のかかる)コードのプロファイルを少しずつ作っていく。この方法で、どのコードを学習、最適化するかについて戦略を立てることができる。Facebookは、フリーソフトウェアライセンスを付してHHVMのコードを公開し、他のサイトでの利用を推奨している。メディアウィキは、利用可能なショーケースの最初の一つとなった。

HHVMに移行することで獲得したもの
----

下記の様々な準備をすることで、自分たちのアプリケーションサーバーは現在全てZendではなくHHVM上のメディアウィキで動作している。2014年の11月、12月に段階的な切り替えを行い、その際得たパフォーマンスの向上には、以下のものがある。

[![File:Wikimedia HHVM deployment - Percentage of CPU Utilization.png](https://upload.wikimedia.org/wikipedia/commons/5/5a/Wikimedia_HHVM_deployment_-_Percentage_of_CPU_Utilization.png)](https://commons.wikimedia.org/wiki/File:Wikimedia_HHVM_deployment_-_Percentage_of_CPU_Utilization.png)

* アプリケーションサーバーの__CPU負荷__は劇的に下がり、50%から10%になった。TechOpsチームメンバーのGiuseppe Lavagettoは、HHVMがないときに必要としていたものと比べ、新しいメディアウィキのアプリケーションサーバーの購入は大幅に削減できると報告している。
* __ページ保存時間の平均値__は、6秒から3秒へと減った(これは、利用者が「投稿」や「プレビュー」を押してから、利用者に対して編集作業を完了し、更新されたページを送信し始めるまでの時間である)。ウィキメディアプロジェクトは2014年に1億回の編集を経験したが、これは、現在から毎年10年分のレイテンシを節約できたことを意味する。(要確認)
* __ページ保存時間の中央値__は7.5秒から2.5秒に減った。
* ログインした利用者向けの__平均ロード時間__(例えば、閲覧用のウィキペディアの記事の生成にかかる時間)は、1.3秒から0.9秒に落ちた。

どうやって移行したか
----

メディアウィキ向けHHVMの理論上の利点は明確だった。2013年の5月、ウィキメディア財団の開発者たちは初めてFacebookのチームと会って、JITではなく完全な事前コンパイラとして実装された「Hiphop」と呼ばれる初期の具現品の利用可能性について議論した。すでに、サーバーの速度が3-5倍になるという見通しはあったが、幾つかの点で信頼性についての懸念(例えば、メディアウィキが移行後も同じアウトプットを出力できるかどうか)はあった。

HHVMの新しいバージョンが出た後の今年の初めに、移行の作業を再開した。信頼性の問題を解決するには、いくばくかの努力が必要とされたが、いい方向に進んだ。すでに数ヶ月以降に取り組んでいたが、その後、Facebookは、この作業を助けるべく何人かの開発者を提供すると申し出てくれた。Facebookの開発者Brett Simmersは一ヶ月間私たちのチームと一緒にフルタイムで働いてくれて、大いに助けてくれ、Facebook自身も私たちが遭遇した問題に対処してくれた。

最終的には、移行作業は6か月に及び、以下の三つの領域のうちひとつにほとんどの作業を費やすことになった。


* __信頼性__:結局、HHVMのPHPの互換性は、とても本当にいいものだったが、自分たちのように大きいコードベースでは、もちろんエッジケースがあった。これら小さな問題の修正は、相当な作業を要求された。
* 自分たちの__PHP拡張__の統合:メディアウィキはC言語で書かれた三つのPHP拡張を使っていた(メディアウィキ自体への拡張と混同しないこと)。Lua(テンプレートなどで、編集者が自動化の際に利用できるスクリプト言語)向けのサンドボックス、Wikidiff2(異なるバージョンのウィキページの差分を素早く表示する)、「高速文字列検索」(コードポイントのサポートが弱く、非ラテン言語のパフォーマンスが悪いPHPのデフォルトの実装を置き換える、高速な部分文字列マッチ用。これは、利用者が見ることのある、他の目的で利用される検索エンジンとは分離されている)の三つだ。これらは三つは、Zend PHPフレームワークと強く結びついており、HHVMの提供する元々の互換性レイヤーでは自由に走らせることはできなかった。この過程で、ウィキメディア財団のLead Platform ArchitectのTim Starlingは、HHVMの互換性レイヤーを一から書き直した。この2万行のコードはアップストリームに寄贈された。
* 移行作業以外では、古いPHP環境とセットになった、アップデートを必要とするPuppetスクリプトといった、複数の__サーバー設定__ツールのアップデートとコンバートがあった。これにより、たくさんのごみくずを整理し、Ubuntu PreciseからUbuntu Trustyにサーバーをアップデートすることになった。

一般に利用できるように変換したソフトウェアを公開する準備をしてから、最初にキャッシュのあるHHVMサーバーの一群を分離してから、サーバーをひとつひとつ移行し始めた。編集者に残りのバグをテストしてもらうために、しばらくはオプトインのベータ機能としてHHVMのサーバーへのアクセスを許可して、特別な[編集タグ](https://en.wikipedia.org/wiki/Special:Tags)でHHVM経由の編集をトラッキングした。ウィキペディアンたちは、相当数のレアケースでのバグを見つけ、メインの公開前に直すことができた。一つ一つサーバーを移行することでゆっくりと(キャッシュされていない)トラフィックの数を徐々に増やしていった。最後は、12月のはじめに、一気に、すべての利用者をHHMV経由での処理に変換することになった。

HHVMの他のメリット、今後の見通しについて
----

私達の目指すスピードアップは、まだ始まったばかりだ。HHVMへ転換した結果、多くの利益が得られた。例えば、

[![Flame graph スクリーンショット](https://wikimediablog.files.wordpress.com/2014/12/1024px-mediawiki_flame_graph_screenshot_2014-12-15_22.png "[Flame graph](https://performance.wikimedia.org/xenon/svgs/hourly/2014-12-15_22.svgz) スクリーンショット")](https://wikimediablog.files.wordpress.com/2014/12/1024px-mediawiki_flame_graph_screenshot_2014-12-15_22.png?w=855&h=548)

* HHVMから優れた__監視ツール__が提供されており、ボトルネックを見つけ、不要な動作をしている部分を簡単に特定できるようになる。これらのツールは、過去に行っていたよりもメディアウィキのパフォーマンスの最適化を可能とする。この「flame graph」は、最初のサンプルである。これは、最もCPU時間を消費しているコードの場所を視覚化するもので、それがどの部分から呼び出されているかを追跡する。グラフを生成するのに使われるデータはHHVM のXenonという拡張で提供される。これは、一定間隔でサーバーの動作のスナップショットを撮り、CPU上にあるコードを見せてくれる。Xenonの設計は、(1990年代のウェブの起源を反映するアーキテクチャを持つZendとは異なり)HHVMが巨大なコンピュータのクラスタにデプロイされた複雑なアプリケーションを利用するためにゼロから設計されたことを示すものだ。
* HHVMから(例えば、文字列、整数、浮動小数点といった変数をどういう風に利用しているかを最初から推定する)__静的なプログラム解析__が提供されている。これにより、コードをデプロイする前にかなり厳密な確認を行い、エラーを減らすことができ、今までの品質管理の仕組みを向上させることができる。
* PHPだけでなく、HHVMはFacebookが開発した言語である__[Hack](https://en.wikipedia.org/wiki/Hack_(programming_language))__で書かれたコードも実行できる。HackはPHPに文法的に似ているが、非同期処理といったPHPにはないパワフルな機能を備えている。製品ではHackをまだ使っていないが、非常に大きな興味を持って、言語の開発は追跡している。
* HHVMチームはすでにメディアウィキのパースの動作を__パフォーマンス劣化テスト__に含めている。つまり、HHVMの新版がリリースされ、私たちが開発に入る前に、メディアウィキのパフォーマンスに影響を与えるようなアップストリームが変更は検知可能だということだ。
* さらには、私たちは、再利用者としてニーズに対応する必要のあるFacebookの有力な__アップストリームパートナー__として信頼されており、今後数年にわたってHHVMのメンテナンスと改善にコミットできる。私たちは、すでにアップストリームに投稿するようになっている。ウィキメディアの開発者によってなされたもっとも重要な投稿は、上記で言及したZend互換レイヤーの書き直しである。これにより、Zend PHP拡張はHHVMで動作する。ウィキメディア財団のLead Platform ArchitectであるTim Starlingによるこうした改善は、[HHVM 3.1.0のリリースノート](http://hhvm.com/blog/5195/hhvm-3-1-0)で名前が挙げられている。
* HHVMを使って、以前にも増して、非常に多くの訪問者に動的なコンテンツを提供する余裕ができた。全体としては、このことで、__ウィキペディアの受け身な利用者と活発な利用者の間にある見えない相違__をもっと解消することができると想定され、好きな記事のリストや、受け身だった読み手の参加を促すための「マイクロ投稿ボタン」といったようなカスタマイズ機能の組み込みが可能になる。

Ori Livneh
Principal Software Engineer
Wikimedia Foundation