去年,我的燃7000出现了一些软硬件故障,便狠下心换了一个二手的15款MBP,从此告别了折腾linux的日子。然而,日常开发时却发现docker的响应速度远不如之前的linux。好在还有优化的空间。

Linux和MacOS上docker的区别

因为折腾过不少系统,自然而然知道,docker在linux上是直接跑在系统上的。而在Windows和MacOS上,docker需要通过一层虚拟化来运行,性能损失是必然的。

于是,我优先将docker的CPU和内存配额尽可能的调大了。然而,性能提升并不明显。

分析主要性能损失

我在做Laravel项目的开发,项目中用到了Laravel-Admin这个包,直观的感受就是打开一个页面需要等好久。

一个偶然的发现:在请求发起之后的文件改动生效了!这就意味着,从我发起了请求直到我修改这个文件的这段时间内,服务器都没有读取到这个被修改的文件,即文件读写的性能开销很大。

因为是开发环境,代码是通过Volume的方式挂载到容器内部的,因此性能损失很有可能是Volume造成的。

优化方法

volume挂载有多个参数可以设置,常见的只读ro和读写rw,还有cacheddelegatedconsistent。以下引用官方的说明:

  • consistent:perfect consistency (host and container have an identical view of the mount at all times)
  • cached:the host’s view is authoritative (permit delays before updates on the host appear in the container)
  • delegated:the container’s view is authoritative (permit delays before updates on the container appear in the host)

consistent从字面上理解是持久的,应该是保证容器内的数据跟volume挂载时宿主机的数据一致,不管容器内外文件有何变动,都不会同步。
cached是缓存的意思,更新策略是宿主机改动优先更新到容器内,允许容器内的改动延迟更新回宿主机。
delegated的机制则与cached相反。

由于开发环境主要是在宿主机上改动(写)代码,在容器内运行(读)代码,因此cached参数更合适。加上缓存后,原本需要10秒才能打开的页面,现在只要2秒就能打开了,性能提升明显。至少能接受了。

使用示例

docker run -v /Users/yallop/project:/project:cached alpine command
version: "3"
services:
  php-fpm:
    image: php:fpm-alpine
    volumes:
    - /Users/yallop/project:/var/www/html:cached

参考文章