我想全面了解Docker容器的运行时性能成本。我发现关于网络的传闻要慢100µs。
我还发现运行时成本“可以忽略不计”和“接近于零”,但我想更确切地知道这些成本是什么。理想情况下,我想知道Docker以性能代价抽象了什么,以及没有性能代价抽象了什么。网络、CPU、内存等。
此外,如果存在抽象成本,是否存在绕过抽象成本的方法?例如,也许我可以直接挂载磁盘,而不是在Docker中虚拟挂载磁盘。
我想全面了解Docker容器的运行时性能成本。我发现关于网络的传闻要慢100µs。
我还发现运行时成本“可以忽略不计”和“接近于零”,但我想更确切地知道这些成本是什么。理想情况下,我想知道Docker以性能代价抽象了什么,以及没有性能代价抽象了什么。网络、CPU、内存等。
此外,如果存在抽象成本,是否存在绕过抽象成本的方法?例如,也许我可以直接挂载磁盘,而不是在Docker中虚拟挂载磁盘。
当前回答
Docker本身并不是虚拟化的——相反,它是内核对不同进程名称空间、设备名称空间等的支持之上的抽象;一个名称空间本身并不比另一个更昂贵或更低效,因此Docker对性能的影响实际上取决于这些名称空间中实际包含的内容。
Docker在如何为容器配置名称空间方面的选择是有成本的,但这些成本都与收益直接相关——你可以放弃它们,但这样做也放弃了相关的收益:
Layered filesystems are expensive -- exactly what the costs are vary with each one (and Docker supports multiple backends), and with your usage patterns (merging multiple large directories, or merging a very deep set of filesystems will be particularly expensive), but they're not free. On the other hand, a great deal of Docker's functionality -- being able to build guests off other guests in a copy-on-write manner, and getting the storage advantages implicit in same -- ride on paying this cost. DNAT gets expensive at scale -- but gives you the benefit of being able to configure your guest's networking independently of your host's and have a convenient interface for forwarding only the ports you want between them. You can replace this with a bridge to a physical interface, but again, lose the benefit. Being able to run each software stack with its dependencies installed in the most convenient manner -- independent of the host's distro, libc, and other library versions -- is a great benefit, but needing to load shared libraries more than once (when their versions differ) has the cost you'd expect.
等等。这些成本对环境(网络访问模式、内存限制等)的实际影响有多大,这是一个很难给出通用答案的问题。
其他回答
下面是更多基于Docker的memcached服务器和主机原生memcached服务器的基准测试,使用twempf基准测试工具https://github.com/twitter/twemperf,连接5000个,连接率20k
基于docker的memcached连接时间开销似乎与上述白皮书一致,大约是本机速度的两倍。
twempf Docker Memcached
Connection rate: 9817.9 conn/s
Connection time [ms]: avg 341.1 min 73.7 max 396.2 stddev 52.11
Connect time [ms]: avg 55.0 min 1.1 max 103.1 stddev 28.14
Request rate: 83942.7 req/s (0.0 ms/req)
Request size [B]: avg 129.0 min 129.0 max 129.0 stddev 0.00
Response rate: 83942.7 rsp/s (0.0 ms/rsp)
Response size [B]: avg 8.0 min 8.0 max 8.0 stddev 0.00
Response time [ms]: avg 28.6 min 1.2 max 65.0 stddev 0.01
Response time [ms]: p25 24.0 p50 27.0 p75 29.0
Response time [ms]: p95 58.0 p99 62.0 p999 65.0
twempf Centmin Mod Memcached
Connection rate: 11419.3 conn/s
Connection time [ms]: avg 200.5 min 0.6 max 263.2 stddev 73.85
Connect time [ms]: avg 26.2 min 0.0 max 53.5 stddev 14.59
Request rate: 114192.6 req/s (0.0 ms/req)
Request size [B]: avg 129.0 min 129.0 max 129.0 stddev 0.00
Response rate: 114192.6 rsp/s (0.0 ms/rsp)
Response size [B]: avg 8.0 min 8.0 max 8.0 stddev 0.00
Response time [ms]: avg 17.4 min 0.0 max 28.8 stddev 0.01
Response time [ms]: p25 12.0 p50 20.0 p75 23.0
Response time [ms]: p95 28.0 p99 28.0 p999 29.0
下面是使用memtier基准测试工具进行的基准测试
memtier_benchmark docker Memcached
4 Threads
50 Connections per thread
10000 Requests per thread
Type Ops/sec Hits/sec Misses/sec Latency KB/sec
------------------------------------------------------------------------
Sets 16821.99 --- --- 1.12600 2271.79
Gets 168035.07 159636.00 8399.07 1.12000 23884.00
Totals 184857.06 159636.00 8399.07 1.12100 26155.79
memtier_benchmark Centmin Mod cached
4 Threads
50 Connections per thread
10000 Requests per thread
Type Ops/sec Hits/sec Misses/sec Latency KB/sec
------------------------------------------------------------------------
Sets 28468.13 --- --- 0.62300 3844.59
Gets 284368.51 266547.14 17821.36 0.62200 39964.31
Totals 312836.64 266547.14 17821.36 0.62200 43808.90
运行时库比较
我将讨论容器在运行时库方面的运行时性能成本问题。
速度:musl与glibc
在Apline Linux容器中,运行时库是由Musl提供的,而不是glibc,根据下面的链接,两者之间可能存在性能差异:
https://www.etalabs.net/compare_libcs.html
我读过关于这个话题的各种观点,Musl既小又明显更现代,在某种程度上也比glibc更安全。然而,还没有找到任何数据来支持这些观点。
兼容性
即使Musl更快更安全,它也会出现兼容性问题,因为Musl与glibc在本质上是不同的。我发现如果我用apk创建一个docker映像来拉入我的包,当然没有能力问题。
结论
如果性能很重要,可以将一个使用Musl的Alpine Linux和另一个使用glibc的发行版的容器切割(2)并对它们进行基准测试。当然,也可以在!!!!的评论中发表你的结果
2014年,由Felter等人撰写的一篇优秀的IBM研究论文“虚拟机和Linux容器的最新性能比较”提供了裸金属、KVM和Docker容器之间的比较。总的结果是:Docker几乎与本机性能相同,并且在每个类别中都比KVM快。
例外的是Docker的NAT——如果你使用端口映射(例如,Docker run -p 8080:8080),那么你可以预期延迟会有一个小的打击,如下所示。然而,你现在可以在启动docker容器时使用主机网络堆栈(例如,docker run——net=host),它将与Native列执行相同的操作(如Redis延迟结果中所示)。
他们还对一些特定的服务(如Redis)进行了延迟测试。你可以看到超过20个客户端线程,最高的延迟开销是Docker NAT,然后是KVM,然后是Docker主机/本机之间的粗略连接。
因为这是一篇非常有用的论文,这里有一些其他的数据。请下载以获得完整访问权限。
看一下磁盘I/O:
现在看看CPU开销:
下面是一些关于记忆的例子(阅读论文了解细节,记忆是非常棘手的):
Docker本身并不是虚拟化的——相反,它是内核对不同进程名称空间、设备名称空间等的支持之上的抽象;一个名称空间本身并不比另一个更昂贵或更低效,因此Docker对性能的影响实际上取决于这些名称空间中实际包含的内容。
Docker在如何为容器配置名称空间方面的选择是有成本的,但这些成本都与收益直接相关——你可以放弃它们,但这样做也放弃了相关的收益:
Layered filesystems are expensive -- exactly what the costs are vary with each one (and Docker supports multiple backends), and with your usage patterns (merging multiple large directories, or merging a very deep set of filesystems will be particularly expensive), but they're not free. On the other hand, a great deal of Docker's functionality -- being able to build guests off other guests in a copy-on-write manner, and getting the storage advantages implicit in same -- ride on paying this cost. DNAT gets expensive at scale -- but gives you the benefit of being able to configure your guest's networking independently of your host's and have a convenient interface for forwarding only the ports you want between them. You can replace this with a bridge to a physical interface, but again, lose the benefit. Being able to run each software stack with its dependencies installed in the most convenient manner -- independent of the host's distro, libc, and other library versions -- is a great benefit, but needing to load shared libraries more than once (when their versions differ) has the cost you'd expect.
等等。这些成本对环境(网络访问模式、内存限制等)的实际影响有多大,这是一个很难给出通用答案的问题。