Node.js の Heroku 環境におけるパフォーマンス
Heroku で Node.js を動かしても絶対的なパフォーマンスは得られないのだけれど、最近仕事で Node.js on Heroku をやっているので、実際にどれくらいのパフォーマンスがでるのか測ってみました。
今回調べたのは、主に3点。
-
2X Dyno (
CPUとメモリが2倍のDyno。ただし、コア数は4のまま)を使うと速くなるのか? Cluster に効果はあるのか?
Dyno 数はどれくらいが良いのか?
ベンチマークは Node.js v0.10.9 を対象とし、全て siege のベンチマーク機能の結果です。ベンチマーク対象のコードは、Node.js 本家トップページに載っている例のHTTP サーバで、AWS の us-east-1 リージョンの EC2 m1.large インスタンスで実行した結果です。
$ siege -b 60S -c 100 http://server
結果
1X Dyno
まずはノーマル。これが基準ですね。
Transactions: 155084 hits Availability: 99.99 % Elapsed time: 59.87 secs Data transferred: 1.77 MB Response time: 0.04 secs Transaction rate: 2590.35 trans/sec Throughput: 0.03 MB/sec Concurrency: 99.63 Successful transactions: 155084 Failed transactions: 17 Longest transaction: 5.07 Shortest transaction: 0.00
2X Dyno
2X Dyno を使うと、なぜかパフォーマンスが下がりました。 何回か測りなおしたのですが、結果は同じでした。
Transactions: 127151 hits Availability: 99.99 % Elapsed time: 59.16 secs Data transferred: 1.46 MB Response time: 0.05 secs Transaction rate: 2149.27 trans/sec Throughput: 0.02 MB/sec Concurrency: 99.32 Successful transactions: 127151 Failed transactions: 7 Longest transaction: 4.18 Shortest transaction: 0.00
1X Dyno + Cluster
Cluster でもパフォーマンスは低下します。 Failed transactions が減っているのがせめてもの救いでしょうか。
Transactions: 122164 hits Availability: 100.00 % Elapsed time: 59.52 secs Data transferred: 1.40 MB Response time: 0.05 secs Transaction rate: 2052.49 trans/sec Throughput: 0.02 MB/sec Concurrency: 99.73 Successful transactions: 122164 Failed transactions: 4 Longest transaction: 5.27 Shortest transaction: 0.00
2X Dyno + Cluster
予想はつきましたが、これが最低のパフォーマンスになりました。 2X Dyno はまだ Heroku の Router がうまく捌けていないのか、と思うくらいパフォーマンスが落ちますね。
Transactions: 116440 hits Availability: 100.00 % Elapsed time: 59.48 secs Data transferred: 1.33 MB Response time: 0.05 secs Transaction rate: 1957.63 trans/sec Throughput: 0.02 MB/sec Concurrency: 99.80 Successful transactions: 116440 Failed transactions: 3 Longest transaction: 5.09 Shortest transaction: 0.00
1X Dyno 2台
2台にしても、パフォーマンスが落ちます。 振り分けのコストがそれなりにでかいわけですね。 Logest transaction が大きく下がっているので、引っ掛かりみたいなものを減らせていると思います。
Transactions: 80351 hits Availability: 100.00 % Elapsed time: 59.94 secs Data transferred: 0.92 MB Response time: 0.07 secs Transaction rate: 1340.52 trans/sec Throughput: 0.02 MB/sec Concurrency: 99.79 Successful transactions: 80351 Failed transactions: 4 Longest transaction: 1.70 Shortest transaction: 0.00
1X Dyno 3台
3台でやっと1台の時と同じくらいの Transaction rate が出るようになります。 Logest transaction がさらに下がっているのがわかります。
Transactions: 143521 hits Availability: 100.00 % Elapsed time: 59.72 secs Data transferred: 1.64 MB Response time: 0.04 secs Transaction rate: 2403.23 trans/sec Throughput: 0.03 MB/sec Concurrency: 99.67 Successful transactions: 143521 Failed transactions: 5 Longest transaction: 0.85 Shortest transaction: 0.00
1X Dyno 4台
4台だとまた下がってしまいました。
Transactions: 97675 hits Availability: 99.99 % Elapsed time: 59.05 secs Data transferred: 1.12 MB Response time: 0.06 secs Transaction rate: 1654.11 trans/sec Throughput: 0.02 MB/sec Concurrency: 98.85 Successful transactions: 97675 Failed transactions: 6 Longest transaction: 1.93 Shortest transaction: 0.00
まとめ
今回の結果だけをまとめると
- Heroku で Node.js を使う場合、2X Dyno も Cluster も使わない方が良い。
- Dyno 数は処理能力的には 1 で十分だが、可用性とかを考慮して 3 に設定すると良い。
となります。実際には処理の内容によって結果に差異はでると思うので、実際に測ってみると良いと思います。 自分は効果あると思って Cluster 使ってましたが、今回の結果をみて、使うのをやめました。
2X Dyno は ImageMagick などで画像処理を行うなど、CPU負荷の高い処理を書く場合は意味あるかもしれないが、それは Node.js で書くべきプログラムでもないし、倍の値段払うほどでもないかなと思います。
2X Dyno は Rails または、JVM 系の言語 (Scala / Java)のための Dyno であり、Node.js にはあまり意味がないかと。前述した公式Blog にもそう書いてありますしね。
補足
2X Dyno はまだ Public Beta (でも、明日から本サービス開始)なので、もしかしたら Router の調整とかがうまくいっていない可能性はあります。なので、1か月後くらいにまた測る予定。
追伸
Quipper という会社に転職しました。