Dockerコンテナのパフォーマンス劣化とチューニング

2015年5月26日(火)
佐藤 司森元 敏雄

テスト5:Apacheのチューニングを実施する

これまでにDockerコンテナの実行環境や構成に対して様々な対策を施し、レスポンスの改善や問題点を確認してきたが、新たなアプローチとしてコンテナ内のアプリケーションの設定によるチューニングによる性能改善を検証する。ここでは、Redmineを稼働させる為に使用しているApacheおよびRuby on RailsアプリケーションをApacheと連携させるPhusion Passengerのチューニングに着目してみる。

コンテナ自体はテスト1と共通である。チューニングはRedmineコンテナに接続し、コマンドラインから直接設定を変更した。変更点は、プロセスの並行処理可能数の向上を目的として、Apacheの最大子プロセス数の上限とPassengerの最大プロセス数の上限の増加である。

設定項目変更前変更後
MaxSpareServers(mpm_prefork_module)1025
MaxClients(mpm_prefork_module)150200
PassengerMaxPoolSize615

この状態で再度負荷テストを行う。結果を表9に示した。

表9:テスト5の結果

作業1分間のオペレーション平均(ミリ秒)中央値(ミリ秒)90%Line(ミリ秒)最小値(ミリ秒)最大値(ミリ秒)Error%スループットKB/sec
アクセス2000137222791029450.0028.6133.9
ログイン実行20003272356105832090.0028.6175.8
Projectへ遷移2000200394311742220.0028.3156.5
チケット作成2000138423101937130.0028.4149.5
平均2000200.584.5407.5263522.250.028.48153.93
テスト5で取得できたiostatの最大値
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          23.42    0.00    3.17   13.57    0.00   59.83

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     3.33    0.33   86.00    16.00  3096.33    72.10     1.37   15.92   14.00   15.93  11.32  97.77
dm-1              0.00     0.00    0.33   75.67    16.00  3095.83    81.89     1.39   18.25   14.00   18.26  12.86  97.77
dm-2              0.00     0.00    0.67   94.33     2.67  3076.00    64.81     3.95   41.39    7.00   41.63   9.11  86.57
dm-4              0.00     0.00    0.00   19.33     0.00  1021.33   105.66     1.20   62.28    0.00   62.28   9.83  19.00
dm-5              0.00     0.00    0.67   74.33     2.67  2430.67    64.89     3.08   40.85    7.00   41.16  13.13  98.47

エラー割合は0%となり、「90%Line」の値も大幅に改善されている。Docker環境自体が変更出来ない場合でもプロダクト側の設定をチューニングすることで、パフォーマンスの改善が図れることがわかった。

ただしプロセスを増やした場合、必然的にこれまでテストを実施してきたコンテナと比べてホスト側のCPUやメモリリソース等をより多く消費してしまうこととなる。リソース量に上限を設けたければ、docker runコマンドの「-c」や「-m」オプションが有効だ。

まとめ

テスト中に得られた値と比較するため、Dockerコンテナのディスクイメージ格納用の領域として使用したハードディスクそのものの性能を測定してみた。

[root@host_server~]# dd if=/dev/zero of=/dev/sda bs=1MB count=1024
1024+0 records in
1024+0 records out
1024000000 bytes (1.0 GB) copied, 3.90083 s, 263 MB/s

ddコマンドによる単純なシーケンシャルwriteだが、1GBのファイルを一つ作成するにあたって263MB/secの書き込み速度が出ている。実際にテスト1中に取得したiostatの結果と比べて見よう。

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          43.82    0.00    5.27    7.56    0.00   43.35

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.33     1.67    3.00  140.67   102.67  3229.83    46.39     1.04    7.22   10.33    7.15   5.77  82.97
dm-1              0.00     0.00    3.33  110.67   102.67  3229.50    58.46     1.05    9.25   13.10    9.13   7.27  82.87
dm-2              0.00     0.00    1.67  276.33    26.67  3328.00    24.13     1.12    4.03   19.40    3.93   2.81  78.23
dm-3              0.00     0.00    1.33  264.33     5.33  3340.00    25.18     1.25    4.70    9.25    4.67   3.16  83.83

取得した値を見るとディスクの使用率(%util)は非常に高いが、一方で書き込みデータ量(wkB/s)はディスク自体の性能から見ると少ないことがわかる。つまり、ハードディスクの物理的な性能不足ではなく、データ量に比べてI/Oリクエストの処理件数が非常に多いことにより、処理性能の劣化が発生していると推察される。

これまでの性能対策の結果のまとめとして、Redmineに対する処理性能の評価を行った「90%Line」「Error%」「KB/sec」を各テストの平均値を比較したい。

 90%Line(ミリ秒)Error%KB/sec
テスト0:ベアメタル環境740.00%94.75
テスト1:Redmineコンテナ立ち上げてテストを行う267049.31%73.1
テスト2:DockerのData Spaceを別の物理ディスクに置き換え、テストを行う180525.66%96.43
テスト3: コンテナで利用する一部のファイルをホストOSへ切り出してテストを行う1560.00%58.08
テスト4:コンテナをRedmineとMySQLの2つに分離してテストを行う3379320.87%54.18
テスト5:Apacheのチューニングを実施し、テストを行う4070.00%153.93

まず、レスポンスタイムの平均値である90%Lineの数値を確認する。

テスト4のコンテナをRedmineとMySQLの2つに分離してテストを行ったケースが一番低いスコアとなっている。今回のケースではDiskの性能が十分に出ていないところにコンテナを分割で配置し、コンテナ間通信のネットワーク負荷も発生させたことで、さらにレスポンスが悪化した形になっている。

テスト2のDockerのファイルシステムに物理デバイスを割り当てる方式だが、Dockerが標準で利用するLoopbackデバイスにdevicemapperとしてファイルシステムをマウントする方式に比べて、30%以上の改善が見られる。ファイルによる仮想ディスクと比較して、大幅に性能が改善されていると考えられる。

テスト3では、比較的IOの高いファイルをホストOS側へ配置することによって、Dockerのファイルシステム(devicemapper)の影響を受けていない。iostatの結果からもわかるように、他のテスト結果に比べて秒間Write回数が多いのにも関わらず、Diskビジーの割合が低くベアメタル環境に近いレスポンスタイムとなっている。

次にリクエストがエラーとなったError%を確認する。

コンテナを分離したテスト4のケースが、一番高いエラー率を示した。レスポンスタイムの悪化からタイムアウトなどのエラーが多発したことが原因だと考えられる。テストケース2は、90%Lineからもレスポンスタイムの改善が見受けられ、その改善によりエラー発生率が約半減している。テスト3、テスト5は、ともにベアメタルと比較するとレスポンスタイムの若干の劣化はあるものの、エラー発生率は0%となっており、Docker環境においても環境やプロダクトのチューニングにより、ベアメタルと同等の性能を確保できることがわかる。

今回の検証を終えて得られた筆者の結論は、以下のようになる。

『Dockerコンテナは、設定やチューニング次第で十分処理性能を確保できる』

Dockerコンテナのパフォーマンスを引き出す上でボトルネックとなるのは、予測していたDiskIO速度の低下であった。さらにコンテナ間の通信速度も、性能劣化の一因となることも判明した。DiskIOに対しては『Dockerコンテナ用ファイルシステムを個別ストレージにする』方法や『DiskIOが多い領域を外部ファイルシステムに配置する』方式が有効である。

さらにDiskIOがボトルネックになる可能性があることを考慮し、コンテナ内のプロダクトのチューニングを行うのも非常に有効だ。コンテナ間通信のネットワーク負荷による性能劣化に関しては、必要な機能を一つのコンテナにまとめることで解消が可能である。

ただ、いずれの方式もDockerの標準インストール状態からは乖離するため、利用できるハードウェア環境や実行するプロダクトに応じて、環境構築を行う必要がある。またこれ以外にも、Docker専用に開発され、性能対策が施されているRed Hat Enterprise Linux 7 Atomic Hostなどの製品の利用も一つの選択肢である。

現在盛んに利用されているサーバ仮想化環境やパブリッククラウドも、発表された当初はビジネスシーンで使うには性能が不足で、信頼性に対してリスクが高いと考えられていた。しかし昨今のクラウドの性能や信頼性の向上で、クラウドの利用は非常に盛んとなっており、全てのシステムをクラウドに移行した、又は移行を決定した企業も多く出てきている。

そしてDockerも、これらの技術と同様の進化が起きるだろう。現状では様々な課題があるDockerだが、今後は利用が拡大し、性能や信頼性のさらなる向上が期待される。今後もDockerと周辺技術の利用を続け、より良い利用方法や安定稼働させる環境づくりなど様々な形でトライして行きたい。

株式会社アーベルソフト

インフラ基盤の設計・構築・運用までの全ての工程を担当。最近は、OSS製品を活用したインフラ基盤の提供を行っている。利用するOSS製品の調査・研究も行っており、現在は、DockerとTerraformに注目している。
>株式会社アーベルソフト

TIS株式会社

R&D部門である戦略技術センター所属。
金融系の大規模システム開発やプライベートクラウド開発環境の構築・運用の経験を生かし、OSS製品を中心としたの技術調査・検証を担当。
> TIS株式会社

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています