Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What is going on with this article?
@ksato9700

Dockerコンテナとネイティブ実行の速度比較

More than 3 years have passed since last update.

はじめに

DockerはLinux上でのコンテナ型仮想化技術の一つである。ホストOSと同じLinuxカーネルしか動かすことできないという制約はあるが、従来のハイバーバイザー型の仮想化技術に比べて起動が速く性能的なペナルティが少ないと言われる。とは言え、何らかのオーバーヘッドがあるはずで、それをちょっと調べてみた。

テスト環境

本来であればLinuxマシンの上でホストとDocker上の比較をすべきと思うが、手元には古めのMac(MacBookAir4,2 13-inch Mid 2011)しかなく、それで確認をしてみた。DockerのランタイムはVersion 17.09.0-ce-mac35 (19611)。
ちなみに、MacOSの上でなぜDockerが動くのか?DockerはLinuxカーネルの上でしか動かないんじゃないのか? それはそうなんだけど、最近のMacOSにはHypervisor Frameworkというのが載っていてそこで別のOSを動かせる。Dockerはこの上にHyperkitというツールキットを載せ、その上でLinuxカーネルを動かしている。DockerのコンテナはそのLinux上で動くという構成だ。ここの記事に図入りで簡潔に説明されています。

比較実験

比較に使ったのはredisというキー・バリュー型のデータベース。これにredis-benchmarkという性能評価のツールが付属しているのでこれを使ってみる。
測ったのは次の3パターン。どれもバージョンは4.0.2。

  1. Native: MacOSの上で直接動かす (brew install redisでインストール)
  2. Docker: 一つのDockerコンテナ上で動かす
  3. Docker.Remote: redisとredis-benchmarkを別のDockerコンテナで動かす

そして1と2に関しては、tcpのport(デフォルトで6379)に接続する方法と、Unix domain socketで接続する方法(すなわちプロセス間通信)の2種類ができるのでそれを試している。便宜上、前者をtcp接続、後者をunix接続と呼ぶことにする

実験結果

一覧の表にしてみた。

Native(tcp) Native(unix) Docker(tcp) Docker(unix) Docker.remote
PING_INLINE 24384.3 77942.32 48899.75 81900.09 36469.73
PING_BULK 26068.82 88105.73 48638.13 85910.65 37133.31
SET 26567.48 88261.25 52002.08 90415.91 37792.89
GET 27300.03 83612.04 48100.05 82576.38 37411.15
INCR 27685.49 79554.5 51519.84 88028.16 38431.98
LPUSH 27329.87 86132.64 52029.14 97181.73 36968.58
RPUSH 20404.0 86355.79 54112.55 88652.48 39385.59
LPOP 22456.77 85034.02 52603.89 93632.96 39968.02
RPOP 24746.35 79681.27 52994.17 85543.2 36818.85
SADD 24324.98 94428.7 49504.95 91491.3 33156.5
HSET 23866.35 93545.37 53648.07 95057.03 36778.23
SPOP 24734.11 90497.73 47801.15 91996.32 32541.49
LPUSH(neededtobenchmarkLRANGE) 24336.82 94786.73 53734.55 90826.52 38417.21
LRANGE_100(first100elements) 9061.25 15581.18 28785.26 38328.86 22655.19
LRANGE_300(first300elements) 4830.68 6147.42 12247.4 14836.8 8915.04
LRANGE_500(first450elements) 3478.38 4192.34 9373.83 10488.78 7043.74
LRANGE_600(first600elements) 2917.66 3113.81 7452.68 7990.41 5470.76
MSET(10keys) 21294.72 51679.59 55928.41 98328.42 36036.04

でもこれだとちょっとわかりにくいので、pandasmatplotlibを使ってグラフにしてみた。

tcp接続とunix接続の比較

MacOS NativeでもDockerの上でもUnix接続のほうが断然早い。まあこれはTCPのオーバーヘッドを考えれば当然の結果。
fig0.png
fig3.png

MacOS NativeとDockerの比較

これが本題の比較なのだが、ちょっと意外な結果。

fig1.png
fig2.png

Unix Socket接続の方はドッコイドッコイだが(これも少し差が付くと思っていたので意外は意外)、TCP接続の方はなぜかDockerの方が早い。何回かやってみるとやる度にそれなりに値が振れるのだが、傾向としてDockerの方が早そうというのは変わらない。コレなんでだろうな...

Dockerのコンテナを別にした時との比較

通常Dockerでは「1サービス1コンテナ」というポリシーで運用するのでそれに従うとRedisを稼働させるコンテナとそれを使うロジックを実装するコンテナは別になる。その構成だとTCP接続しか出来ないのだが、それを1コンテナ構成で一緒にした時との比較をしてみるとこんな感じ。
fig4.png

この差が大きいか小さいかは用途次第だけど、確かに差はあることがわかる。

まとめ

予想外の結果が出ていてちょっと戸惑っているが、一つ目の結論は

  • Linuxマシンの上で比較してみたい。

ということ。

そして、例えばRedisを一つのクライアントからだけ使うなら

  • 同じコンテナに入れてUnix domainのソケット接続をする

のも性能を稼ぎたい場合はありなのかな。

そして今回の実験につかったソース他はこちら

11
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
caddi
製造業の受発注プラットフォーム「CADDi」を提供しています。 モノづくりに携わるすべての人が、本来持っている力を最大限に発揮できる社会を実現する。産業の常識を変える「新たな仕組み」をつくります。 「CADDi」は金属加工品のCAD・設計図の解析から複雑な物流を表現するUIまで幅広い開発をしており、常に開発環境に最新の技術をとり入れて、より良いプロダクトを作るように心がけております。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
11
Help us understand the problem. What is going on with this article?