目的
下記の結果を見て、制限されたCPU,Memoryの環境下において、本当にこんなスループットが出るか?
と思い、Docker for Macを利用し、Kubernetes環境下でどのような結果が出るかを検証してみました。
https://github.com/networknt/microservices-framework-benchmark/blob/master/README.md
今回は、同一のリソース制限を加えた状態での応答速度、スループットの相違を確認する事を目的としています。
各フレームワークにおけるCPU,Memoryのフットプリントの最適化は別途行う予定ですので今回の検証結果では考慮していません。
また、時間があれば、GKE環境でも調べてみようかと考えています。
今回この検証が再現が用意に行えるようにするため、コンテナ化した際のDockerfile、及びKubernetesのマニフェストファイルは全てGitHubリポジトリに格納しています。
事前条件
環境
- Mac Book Pro (OS: High Sierra 10.13.6)
- CPU:Intel Core i7 2.5GHz
- Memory:16GB
- Docker for Mac 18.06.1-ce
- Kubernetes v1.10.3
- CPU:3 core
- Memory: 6GiB
- Swap: 512MiB ※無効化したかったけど、できなかった。
検証方法
負荷を与えるコンテナ wrk
から対象となるサービスに対して負荷を与えます。
負荷は全て service経由で与える。serviceにて実際に負荷を与えるpodを切り替えます。
負荷を与えるツールは、wrk
を利用し、下記のように実施します
$ wrk -t4 -c64 -d60s http://microservice.default.svc.cluster.local:30000/ --latency
ウォームアップ部分のオーバーヘッドは無視するため、上記のコマンドを2回実行し、2回目の測定結果を有効な結果として扱っています。
また、測定対象のコンテナは、下記のresourceを与えた状態で、podを1つ起動した状態で測定します。
resources:
requests:
cpu: 200m
memory: 400Mi
limits:
cpu: 200m
memory: 400Mi
また、コンテナ化した際のDockerfile、及びKubernetesのマニフェストファイルは、全て
https://github.com/h-r-k-matsumoto/microservices-framework-benchmark
のリポジトリに保管しています。
Javaアプリケーションに関しては、 jibを利用し、コンテナ化しています。
そして、jdk10をベースにしています。これは下記のようにスレッド数などの最適化がjdk8では行われないためです。
https://qiita.com/h-r-k-matsumoto/items/17349e1154afd610c2e5
検証対象
個人的に気になった下記の6つを対象としています。
- go-Http
- iris
- spring-boot2-tomcat
- spring-boot2-undertow
- light4j
- helidon-se
検証結果
フレームワーク | スループット(req/min) | 平均(ms) | 90%LINE(ms) | 99%LINE(ms) |
---|---|---|---|---|
light-4j | 295,125 | 29.35ms | 72.17ms | 99.01ms |
go-http | 163,557 | 48.11ms | 119.78ms | 304.28ms |
iris | 143,173 | 66.62ms | 174.93ms | 571.83ms |
spring-boot2-undertow | 107,540 | 46.04ms | 94.61ms | 196.11ms |
spring-boot2-tomcat | 38,068 | 117.01ms | 290.70ms | 492.55ms |
helidon-se | 30,742 | 160.51ms | 299.11ms | 969.99ms |
※平均、90%LINE,99%LINEは応答速度です。
考察
light-4jは確かに爆速だった。
ただ、本家のサイトほどの速度差は出ませんでした。
実運用を考えると、JSONやgRPCでのAPIを考慮する必要があります。
この部分の検証も考慮しておく必要があります。
swap系も無効にするなどがDocker for Macで行えなかった事から、GKE環境でも検証を進めて見たいと思います。
light-4jにフレームワーク変更するのは色々難しいけど、せめて spring-boot2-undertowに変更したい・・・。
補足
実行方法は、
https://github.com/h-r-k-matsumoto/microservices-framework-benchmark/blob/fix/master/k8s_reproduce_benchmark/DockerForMac.md
を確認してください。
後、light-4j的にはkubernetesはパフォーマンス落ちるからやめろ的な感じなのかな。
https://gitter.im/networknt/light-4j?at=5bf5948a958fc53895c9dbe5