59
composerの遅さを まじめに考える 98PHP勉強会 @Hiraku

composerの遅さをまじめに考える #phpstudy

Embed Size (px)

Citation preview

composerの遅さを まじめに考える第98回PHP勉強会

@Hiraku

自己紹介

• 中野 拓 (@Hiraku)

• 口癖「composerが遅い」packagistのミラー作った http://packagist.jp

• 2015/12からメルカリで働いています。

今日は composerの話を しに来ました

composerは遅いのか

composer遅いと言う人々

• 中国、フィリピン、日本、ブラジルあたりに多いらしい

• issueに文句を書いてる人は大体アジア人

• 北米ではcomposerは速い

composerを速くする活動やってます• ミラーサイト http://packagist.jp

• 並列化プラグイン hirak/prestissimo

• https://packagist.org/packages/hirak/prestissimo

packagistのミラーサイト

hirak/prestissimo (並列化プラグイン)

インストールするだけで10倍ぐらい速くなります

どちらもコマンド1行で使える

# (ミラーサイトの有効化)$ composer config -g repositories.packagist composer http://packagist.jp

# (並列化プラグインのインストール)$ composer global require hirak/prestissimo

# フィードバック募集中!!

なぜこれで速くなるのかを解説します

composerが遅い理由

日本で

サーバーが遠い…で終わるんだが

あえて別の言い方をしたい

光が遅いから。

なぜ”光”の話になるのか

サーバーの場所

• packagist.org ← たぶんフランスにある

• github.com ← たぶんサンフランシスコにある

• 日本からの通信で必ず通るもの=海底ケーブル

=光ファイバー

約8000km

光は結構遅い

• 真空で約30万km/s

• 光ファイバー中で約20万km/s

• 8000kmで片道最低40msかかる

• (実際は他にも遅延原因があるからもっと遅い)

「40msって速くね?」

• 物理限界が40msであって、実際は(ry

• これにgithub.comの事情が加わる

• https://api.github.com からhttps://codeload.github.com へ毎回リダイレクトしている

HTTPSの往復

• ゼロからHTTPS通信すると、パケットの往復が4回発生する

• TCPのハンドシェイクで1往復

• TLSのハンドシェイクで2往復

• HTTP本体で1往復

• 1回リダイレクトすると更に倍

約8000km を8往復

128,000km

地球3.2周分

https://flic.kr/p/7icRw2

composerはこれを全zipに対して行っている

それぞれが 地球3.2周分

さすがの光でも

• 片道40msで8回往復すると640ms

• しかも実際は

• 海底ケーブルは最短距離を通ってないし

• 途中には様々なルーターやら何やらを通るからそこでも遅延がある

実際の遅延時間

curlで雑に測ってみる

# (githubから適当なzipをダウンロードする)$ curl --head \ --location \ --output prestissimo.zip \ https://github.com/hirak/prestissimo/archive/0.1.4.zip \ --write-out " time_namelookup: %{time_namelookup}\n time_connect: %{time_connect}\n time_appconnect: %{time_appconnect}\n time_redirect: %{time_redirect}\n time_total: %{time_total}"

...time_namelookup: 0.013time_connect: 0.201time_appconnect: 0.884time_redirect: 1.270time_total: 2.400

(試行1回と雑なので、 目安だと思ってください)

項目の意味

time_namelookup(0.013) 開始からDNS解決まで(秒)

time_connect(0.201) 開始からTCPハンドシェイク完了まで(秒)

time_appconnect(0.884) 開始からTLSハンドシェイク完了まで(秒)

time_redirect(1.270) リダイレクトで費やした時間(秒)

time_total(2.400) かかった時間全て(秒)

フェーズ毎の値に修正

名前解決 0.013

TCPハンドシェイク 0.201 - 0.013 = 0.188

TLSハンドシェイク 0.884 - 0.201 = 0.683

リダイレクト一回分 1.270

HTTPの本体 2.400 - 1.270 - 0.884 = 0.246

2.400秒中の

0.640秒 が

たぶん光のせい

距離と遅延

• 物理的に通信してるのだから、物理的に距離が遠いとその分遅れる

• アジアや南米でcomposerが遅いのは、サーバーから物理的に遠いから

composerを速くする方法

解決方法

1. packagistやgithubが近くにあればいい

2. 往復を減らせばいい

3. 並列化して待ち時間を活用すればいい

4. 光がもっと速くなればいい←難しそう

1. 距離を縮める

• 近くにミラーサイトを建てる

• CDNが導入されてれば同じ効果がある(packagist本家が導入してくれれば…)

• githubのミラーはちょっと大変…

packagistに関しては packagist.jpミラーで

実装済み

2. 往復を減らす(1)

• zipあたり8往復するのは無駄

• api.github.com→codeload.github.comリダイレクトをやめる最初からcodeloadに取りに行く

• これでzipあたり4往復減らせる

さっきの例で、1zipダウンロード時間の内訳

download 0.240

redirect 1.270

tls 0.683

tcp 0.188

dns 0.013

リダイレクトを削る

download 0.240

redirect 1.270

tls 0.683

tcp 0.188

dns 0.013

2. 往復を減らす(2)

• 同じコネクションを使いまわして次のzipをダウンロードする(Keep-Alive)

• 初回は省略できないが、2回目以降TLSハンドシェイクまで省略できる(3往復)

Keep-Aliveで2回目以降省略

download 0.240

redirect 1.270

tls 0.683

tcp 0.188

dns 0.013

zip50個の場合50 * 4 + 49 * 3 = 347往復の削減効果

地球69.4周分 節約

https://flic.kr/p/7icRw2

PHPでKeep-Aliveなリクエスト

<?php$ch = curl_init();curl_setopt($ch, CURLOPT_URL, 'http://example.com/1.txt');curl_exec($ch);

// 同じ$chを使い回して2回目

curl_setopt($ch, CURLOPT_URL, 'http://example.com/2.txt');curl_exec($ch);

curl_close($ch);

3. 並列化

• 待ち時間に別のダウンロードを行う

• 通信路の暇をなくせる

• 帯域を100%使いきったら、並列化の効果は薄い (prestissimoは6並列にした)

• PHPの場合、curl_multiを使えばできる

リダイレクト削減とKeep-Aliveと並列化は

hirak/prestissimoで実装済み

解決方法の現状packagistが近くにあれば packagist.jpで実装した

リダイレクトを減らす hirak/prestissimoで実装した

Keep-Aliveを使う hirak/prestissimoで実装した

並列化する hirak/prestissimoで実装した

光が速くなれば 未解決

インパクトのある部分は結構つぶせた

まとめ

本当は

• composerじゃなくて光がクソ遅いのが全て悪い!と

言いたかったが…

• 光の伝搬時間は全体の一部でしかない。まだ我々には改善できることがある

我々が知るべきこと

• 地球規模だと光の遅さが体感できる

• 物理限界を意識して実装しよう

• composerの実装・file_get_contents()はHTTP/1.0で、連続ダウンロードに向いていない (curl使おうぜ)

もっと詳しく知りたい人は←この本にだいたい書いてあります

光の遅さに文句が言えるエンジニアになろう

ご静聴ありがとうございました

We are hiring!