実態に近い機能(DBアクセス→キャッシュ処理→Markdownパース→テンプレートレンダリング)の実装が終わったのでベンチを改めて取りました。おそらく、今後機能拡張していってもここから劇的に(例えばひと桁とか)パフォーマンスが落ちることはないと思います。
ベンチ結果(wrk)
$ wrk -t12 -c400 -d30s http://localhost:9001/post/test Running 30s test @ http://localhost:9001/post/test 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev Latency 6.64ms 0.96ms 26.09ms 89.81% Req/Sec 5.00k 568.71 37.94k 99.25% 1790835 requests in 30.10s, 1.89GB read Requests/sec: 59499.40 Transfer/sec: 64.29MB
ベンチ結果(apache bench)
$ ab -n 1000000 -c 18 http://localhost:9001/post/test Server Software: Server Hostname: localhost Server Port: 9001 Document Path: /post/test Document Length: 1006 bytes Concurrency Level: 18 Time taken for tests: 45.188 seconds Complete requests: 1000000 Failed requests: 0 Total transferred: 1128000000 bytes HTML transferred: 1006000000 bytes Requests per second: 22129.83 [#/sec] (mean) Time per request: 0.813 [ms] (mean) Time per request: 0.045 [ms] (mean, across all concurrent requests) Transfer rate: 24377.39 [Kbytes/sec] received
考察
abとwrkでかなり結果が違いますね。wrkの方が後発で、より並列処理に適した負荷のかけかたをしてる?みたいなので、wrkの方が正しい値と言えるでしょう。
両者で並行処理数のパラメータが異なっていますが、これはabではある程度同時実行数を上げてやらないとパフォーマンスが出なかったからです。
すると、Sashimiのパフォーマンスは約60k reqs/sということになります。同マシンで実行したwordpressは35 reqs/sでしたから、約1700倍ですか。
WordPressでここまでのパフォーマンスを出すとなるとフロントエンドでキャッシュさせるしかありませんが、これはプラグインが正常に動かなくなるなどの問題が多発します。当ブログでも一時期はそのようにしていましたが、あまりにも問題が発生するのでキャッシュを外した経緯があります。
フロントエンドでキャッシュする以外のキャッシュプラグインはそもそも効果の点でいまひとつで、非キャッシュ時の数倍程度の性能にとどまります。
image from Benchmarking the Fastest WordPress Cache Plugins
これはIO以外の処理時間もIOに匹敵する程度の大きさであることを示しています。PHPのパフォーマンス改善については全く知見が無いので分かりませんが、実行時コンパイルされたコードをHHVMで実行させても大したパフォーマンス向上にならなかった(実体験やベンチスコアをググった結果)ことを考えると、もうちょっとパフォーマンスが出せる言語を使って作り直すしか無いんじゃないかなという気がします。
フルキャッシュ状態でのベンチ結果(wrk)
以下はテンプレートを適用した結果(レンダリング結果)をキャッシュした場合です。つまりHTTP Responseのbodyに相当する情報をキャッシュします。
$ wrk -t12 -c400 -d30s http://localhost:9001/post/test Running 30s test @ http://localhost:9001/post/test 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev Latency 1.49ms 4.71ms 208.89ms 99.21% Req/Sec 27.21k 3.85k 75.03k 94.66% 9734596 requests in 30.10s, 10.27GB read Requests/sec: 323406.16 Transfer/sec: 349.44MB
すると、323k reqs/sとまた一桁性能が向上します。秒間32万リクエスト。Yahooの地震速報で秒間数万アクセスくらいらしいです。ここまで来ると実用上は多分ネットワークがボトルネックになるはずなので、アプリが提供するパフォーマンスとしては十分なレベルで、ボトルネックになることは無いと思われます。
ちなみに、この結果はnginxでfastcgi cacheするよりも早いはずです。あれの実装はキャッシュデータをディスクに書くようになっています(はず)が、SashimiのキャッシュはCaffeine(オンメモリキャッシュ)なので。
Sashimiの機能としてはキャッシュのレベル(どの段階でキャッシュするか)とキャッシュの生存時間、トリガによるキャッシュの消去などの設定をサポートする予定ですが、デフォルトではすべてのキャッシュは有効になっているようにしたいと思います。
以前の記事で「ブログは動的な要素が意外に多いからキャッシュは解決策にならない」と書いたのですが、Sashimiでは動的に変更される部分は基本的にAjaxで更新されるものとして、記事本文までを高速に表示させることを重視する設計としたいです。
そもそもブログ(CMS)で動的に更新される部分は
- SNSのシェア数
- コメント
- 広告
などでどれもすぐに表示されなくて良いものばかりです。そもそもSNSのシェア数(とアイコン)や広告は元々外部のAPIをajaxで叩くのが普通です。
コメントはCMSのシステムに包含されているケースが多いと思いますが、Sashimiではコメントもajaxによって制御するようなプラグインとして提供する設計にしたいと思います。というか、私がコメント機能は要らないと思ってるので開発する意欲がそもそもあんまり無かったりするのですが…。