SashimiとWordPressの速度比較(見積)

Sashimiとして実装するWordpressフロントエンド(最終的にCMS)で速度がどれくらい出るのか見積もってみました。

WordPressのパフォーマンス

この構成のdockerコンテナでWordpress環境を構築しました。ハードはRyzen 1700 / MEM 8G / SSDです。データとしてこのブログのダンプを突っ込んでます。Wordpressプラグインは全部無効、テーマはデフォルトのものを指定しています。サーバもベンチマーク取るマシンも同一です。

$ wrk -t12 -c400 -d30s http://localhost:8080/2017/01/01/%E3%83%8E%E3%83%BC%E3%83%88e-power%E3%81%A8swift%E3%81%8C%E3%81%99%E3%81%94%E3%81%84/
Running 30s test @ http://localhost:8080/2017/01/01/%E3%83%8E%E3%83%BC%E3%83%88e-power%E3%81%A8swift%E3%81%8C%E3%81%99%E3%81%94%E3%81%84/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.13s   550.25ms   1.99s    56.90%
    Req/Sec     7.66      7.08    50.00     81.10%
  1054 requests in 30.10s, 48.47MB read
  Socket errors: connect 0, read 0, write 0, timeout 996
Requests/sec:     35.02
Transfer/sec:      1.61MB

35 reqs/s です。マジか…。もうちょっと早いと思ったんだけど。しかもタイムアウトも996回発生しており、こんなもんプロダクトで使うとか冷静に考えるとおかしい。

ちなみに、ブログをさくらのレンタルサーバーで運用していたときは秒間0.5アクセスしかさばけなかったです。現在このブログはさくらのVPSで運用しており、マシンリソースもレンタルサーバー運用のときとはずっと上がっているはずですが、おそらく素の状態で秒間10〜20アクセスが関の山というところではないでしょうか。それ以下の可能性も十分ありますが…。

その後、フロントエンドでキャッシュ(FastCGI)を有効にして秒間200アクセス程度まで高速化しましたが、キャッシュするのは色々なところで問題が発生した(いいねボタンや投票プラグインの動作不良)ので諦めました。

当時のパフォーマンスについては以下記事などにまとめてあります。

wordpressをサクっと高速化する

Sashimi

同じハードで今度はSashimiを動かしてみました。

といってもSashimiはまだ実装途中です。今回実装している処理は、

  • ルーティング
  • MySQLからの該当記事のデータ取り出し
  • クライアントに記事本文を返却

の3つです。この他に、本来であれば更にいくつかのデータ取得処理(ブログの名前、カテゴリなどの情報)とテンプレートを用いたページのレンダリング処理が入ります。また、フロントエンド(nginx)を挟んでいないのでそのオーバーヘッドもありません。つまり、今回の比較はSashimiが大幅に有利な条件となっています。ただ、最も時間がかかると思われる記事本文の取り出し(IO)は実装済みなので、完成した段階で今回の結果から何桁も遅くなるわけではないと思います。せいぜい遅くなったとして半分程度じゃないかと思っています。

結果は以下の通り。

$wrk -t12 -c400 -d30s http://localhost:9001/2017/01/01/%E3%83%8E%E3%83%BC%E3%83%88e-power%E3%81%A8swift%E3%81%8C%E3%81%99%E3%81%94%E3%81%84/
Running 30s test @ http://localhost:9001/2017/01/01/%E3%83%8E%E3%83%BC%E3%83%88e-power%E3%81%A8swift%E3%81%8C%E3%81%99%E3%81%94%E3%81%84/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    17.77ms   21.56ms 550.56ms   99.21%
    Req/Sec     2.02k   277.12     4.11k    91.58%
  711684 requests in 30.08s, 3.46GB read
Requests/sec:  23659.95
Transfer/sec:    117.94MB

23k reqs/s です。3桁違う。

ここから残りの機能を実装して1桁遅くなったとしても100倍くらいは差がつけられるということになります。

開発方針

sashimiは速度(秒間アクセス数とレイテンシ)を最優先して開発することとしています。今回はキャッシュを使っていませんが、今後は緩いキャッシュ機構も導入する予定なのでさらに秒間アクセス数を稼げるというプラスもあります。一方でレンダリング等々の未実装の処理を実装によるマイナスがあります。できれば一通りの機能を実現しても今と同じくらいの速度は保ちたいです。とりあえず、キャッシュなしIO毎回ありという状態でどこまでパフォーマンスの最高値がどの程度になるのかというのを知りたかったという主旨です。

ちなみにIOを介さず固定のテキストを送信した場合のパフォーマンスは40k reqs/s でした。さらに倍くらいにはなるということなので、上手くやればフル機能を実装しても23k reqs/sくらいの性能を出すことは出来るような気がします。

もし本当に3倍の差が出るのであれば、「Wordpressで大量のアクセスをさばいている」「キャッシュは導入できない」というユーザーには響くものになるんじゃないかなぁという気がします。

使っているフレームワークなど

HTTPサーバ部分はcolossusというAkkaを使用したマイクロサービス向けフレームワークを使用しています。

DBアクセス部分はquillを使用しています。quillはSQLを書かない系のライブラリです。コンパイル時にSQLを生成するので実行時のオーバーヘッドは無い(はず)ですが、高速化のためにはSQLを細かくチューニングする必要があるかもしれず、するとSQLを書く系のライブラリの方が良いと思われるのですが、とりあえず使ってみたかったのでこれを使ってます。速度面での問題が出れば他のフレームワークも使用します。

テンプレートエンジンは基本ユーザー任せにしようと思いますが、twirlをデフォルトかつ推奨としたいです。twirlはPlay Frameworkのデフォルトのテンプレートエンジンで、任意の引数を受け取ってHTMLなどを出力する関数としてコンパイルされます。速度的な問題は発生し無さそうなのと、構文が単純で覚えやすい(と思う)という二つの理由で採用しました。

WordPressの資産について

WordPressのテンプレートやプラグイン資産は基本捨てることになると思われます。将来的にコンバータ的なものが作れれば良いですが、まず無理です。言語が違うんで…。