LoginSignup
71
47

More than 5 years have passed since last update.

Docker for Mac のボリュームの遅さを cached オプションで解消

Last updated at Posted at 2017-04-13

ようやく Docker を使い始めたところ、Docker for Mac でホストのディレクトリをコンテナでマウントした時の遅さに驚きました。

バージョン

$ docker --version
Docker version 17.04.0-ce, build 4845c56

状況

とある Rails アプリについて、ホスト(macOS)にあるソースコードをホストで編集しつつ Docker コンテナで動かす事を考えます。

Dockerfile
FROM ruby:2.4.1

WORKDIR /app

ENV BUNDLE_PATH /bundle
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev
docker-compose.yml
version: '3'
services:
  ...
  job: &job
    image: ...
    build: .
    volumes:
      - ./:/app
      - gems:/bundle
      ...
    depends_on:
      - postgres
      - redis
      - fluentd
    command: bundle exec rails jobs:work
    environment:
      ...
  api:
    <<: *job
    command: bundle exec rails s -p 3333 -b 0.0.0.0
    ports:
      - "3333:3333"
volumes:
  gems:
  ...

macOS 上で動かしたときと比べ、とある単純な Web API の応答時間が10倍くらいになりました(25ms/req → 250ms/req)。

対策

最近追加されたマウントオプション(consistency オプション)を利用することで、ボリュームのI/O性能(?)を向上させられる様です。

デフォルトは consistent で、一貫性のために性能が犠牲になっている、ということでしょうか。それなりの性能を求めつつ、ホスト側の変更をコンテナに反映したい場合は cached オプションを使えば良さそうです。

The consistency requirements for the mount; one of

  • default: Equivalent to consistent.
  • consistent: Full consistency. The container runtime and the host maintain an identical view of the mount at all times.
  • cached: The host's view of the mount is authoritative. There may be delays before updates made on the host are visible within a container.
  • delegated: The container runtime's view of the mount is authoritative. There may be delays before updates made in a container are are visible on the host.

docker/service_create.md at master · docker/docker

docker-compose.yml
version: '3'
services:
  ...
  job: &job
    image: ...
    build: .
    volumes:
      - ./:/app:cached
      - gems:/bundle
      ...
    depends_on:
      - postgres
      - redis
      - fluentd
    command: bundle exec rails jobs:work
    environment:
      ...
  api:
    <<: *job
    command: bundle exec rails s -p 3333 -b 0.0.0.0
    ports:
      - "3333:3333"
volumes:
  gems:
  ...

雑に比較した(ab -n100)限り、 consistent で平均 250 ms/req 程度だった応答時間が、 cached では平均 85 ms/req 程度に改善出来ました。
まだ使い始めたばかりなので、ホスト側での変更がコンテナに反映されるまでの遅延については、要観察です。

まとめ

だいぶましにはなりましたが、macOS で動かした時は平均 25ms 程度なので、まだ体感的にも遅さを感じています…。Docker 慣れしてなさすぎて、そもそもの考え方を間違えているかもしれません。

今回例示した様な構成(ユースケース)では、現時点では docker-sync を使っておくのが無難だったりするでしょうか。

追記: 2017/04/13

docker-sync

最低限の設定で unison を使った同期を試したところ、cached の半分以下の応答時間(計測環境が違うので正確ではない)で、macOS 上で development で動かした時と同程度でした。

71
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
47