読者です 読者をやめる 読者になる 読者になる

Mercari Engineering Blog

メルカリのエンジニアブログです。技術情報を日々発信していきます。

光遅い問題を克服してcomposerを10倍速くした話

はじめまして。サーバーサイドエンジニアの中野(@Hiraku)です。2015年12月からメルカリで働いています。

2016年1月27日(水)の第98回PHP勉強会@東京にて、composerを速くする取り組みについて発表をしてきました。

composerはPHPにおける実質スタンダードなパッケージマネージャです。 このcomposer、日本で実行すると非常に遅く感じます。この原因は普通ならこう表現すると思います。

  • githubやpackagistが日本から遠いから
  • composerの実装がよくないから

しかし発表ではあえて「光が遅いから」という主張をしました。

光遅い問題

一般常識として、光の速さ(真空中で秒速約30万km)はとてつもなく速いものという認識だと思います。しかし一方で、地球や宇宙の規模など極限的な状況に携わる仕事をしている人であれば「全然速くない、むしろ遅い」というのが普通の感覚です。

インターネットは多くの部分が光通信で作られているため、光の速度が通信速度に影響を及ぼします。

Webエンジニアであっても国内サービスであればそうそう光が遅いと実感はしないものです。一方でcomposerでは大陸間を越える通信であったり、往復を省略しない実装などの要因が重なり、珍しく光が遅いことを体感できる形になっていました。そのため「光遅い問題」という切り口で説明してみました。

ちなみに資料の数値部分は試行回数1回だったりとかなりいい加減です。ただ感覚的には分かって頂けるのではと思います。

composerプラグインによる高速化

上記のスライドの中で、prestissimoというcomposerプラグインを紹介しています。

github.com

インストールするとcomposer自体のダウンロード機構の直前に割り込み、cURLを使って6並列かつKeep-Aliveで一気にzipファイルをダウンロードすることで、composerコマンドを高速化します。

laravel-demo

このGIFアニメはキャッシュのない状態からLaravelを新規インストールしているところです。素のcomposerでは5分弱ぐらいかかっていたのですが、prestissimoを有効にすると26秒で完了しています。つまりプラグインを有効化するだけで10倍程度速くなるわけです。

この10倍もの高速化は、光が遅いことを前提にパケットの物理往復距離を節約し、待ち時間も並列化で有効活用することによって達成した数字です。 なおダウンロードの最適化は物理距離が遠いほど影響があるので、測定環境によって効果のほどは変わります。

なんかすごいことになった

prestissimoは2016年1月13日のPHPBLT#2で初めて紹介しました。

この時点ではバグも何個か残っていましたし、テストコードもほとんど無い状態でしたので、本家composerにマージを提案するにも安定してからだと思っていたのです。

その後突然、1月26日にRedditのPHP板で取り上げられたのをきっかけに、海外でも急速に使われるようになりました。

  1. リポジトリのstar数が1000を超えた
  2. Awesome-PHPに登録された
  3. composerの作者 (@seldaek) からメールが来て褒められた (めっちゃ嬉しい)

こんなにバズったのは初めてなので、非常に驚いています。

まだいくつかの環境で動かないというバグ報告が上がっていますので、まずは品質を上げるところに注力したいと思っています。

Be Professional Day

話は変わりますが、私がメルカリにちょうど入社した12月に、"Be Professional Day(BPD)"という取り組みが開始されました。 1ヶ月に1日、普段の業務を一旦ストップさせて普段手を付けていないことをやる日、というものです。

  • ずっと放置されているBTS奥底のチケットを片付ける
  • リファクタリングをやる
  • テストコードを充実させる
  • ドキュメントを書く
  • 前から気になっていた新サービス/新ツールを使ってみる

こういった、「今すぐやらなくてもいい」「でもやらないと後できっと後悔する」ような活動は、日々の業務に追われていると後回しにしがちです。意識的に時間を取って活動しなければなりません。

全社的に「この日はBPDだ!」と号令が出ていると日々の業務に言い訳ができますので、大変活動しやすいと感じました。

かくいう私は12月のBPDで「"composer update"で依存ライブラリのバージョンが変わるとき、どう変わったのがgithub上で読みにくい。これじゃコードレビューが面倒だ。改善できないか。」という課題に取り組みました。(細かすぎて伝わりにくい!)

できあがったのはcomposer updateコマンドを実行した時に、パッケージバージョンのdiffを表示し、今入っているpackageの一覧をテキストに出力するcomposerプラグインです。

mercari/composer-diff-pluginという名前でMITライセンスにて公開してあります。

packagist.org

ただこれ、正直なところイマイチな出来で、ダウングレードを抑えるような強制力はないし、結局のところはCI的にbotが検知してくれる方が効果があるので、アプローチを変えて作りなおしているところです。

思わぬ副産物

BPDの成果自体はともかく、ちょうどこの機会にcomposer自体のソースコードやプラグインに関する知見が溜まり、「プラグインで並列化できそうな気がしてきた」のきっかけになりました。 その後、正月休み中に大体のコードを書き上げてPHPBLTで発表したのが、このprestissimoです。

BPDで取り組む課題は、結果として失敗でも咎められることはありません。要するに「好きなことをやっていいよ」という日なのです。 (ちなみにこの記事は1月のBPDで書いています。)

副産物として面白い成果が出せて感激しています。メルカリ社内でもcomposerはあちこちで使われていますので、CIやビルドの高速化のために活用し、実績を積んでいきたいと思っています。