我有一个简单的Ruby应用程序,基本上它通过HTTP端点获取一些数据,稍微处理它,对它进行分组并将其分批发送到某个远程HTTP端点.
当我在裸机上运行时 - 我将4个CPU饱和到100%然后得到3000reqs/s
(根据ab
;应用程序有点计算密集);
但是当我在Docker中运行时,我只得到了1700reqs/s
- CPU似乎达到了55-65%的峰值.相同的应用程序,相同的设置.
我尝试增加ab的并发性.应用程序本身托管在Passenger中,我尝试在20个进程中运行它,在40个进程中运行(Passenger运行应用程序).在Docker里面它似乎并不想要更高.
我通过docker-compose
主机运行它Ubuntu 14.04
$ docker -v
Docker version 1.10.0, build 590d5108
$ docker-compose -v
docker-compose version 1.5.2, build 7240ff3
Run Code Online (Sandbox Code Playgroud)
两种情况下的负载平均值都很高(大约20),但它不受盘限制.
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- ---system--- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
22 0 0 8630704 71160 257040 0 0 29 6 177 614 3 1 94 1 0
7 0 0 8623252 71160 257084 0 0 0 16 9982 83401 46 12 43 0 0
43 0 0 8618844 71160 257088 0 0 0 0 9951 74056 52 10 38 0 0
17 0 0 8612796 71160 257088 0 0 0 0 10143 70098 52 14 34 0 0
17 0 0 8606756 71160 257092 0 0 0 0 11324 70113 48 15 37 0 0
31 0 0 8603748 71168 257104 0 0 0 32 9907 85295 44 12 41 3 0
21 0 0 8598708 71168 257104 0 0 0 0 9895 69090 52 11 36 0 0
22 0 0 8594316 71168 257108 0 0 0 0 9885 68336 53 12 35 0 0
31 0 0 8589564 71168 257124 0 0 0 0 10355 82218 44 13 43 0 0
Run Code Online (Sandbox Code Playgroud)
它也不受网络限制.即使我禁止向远程主机发送数据并且所有通信都在机器内 - 我仍然看到55-65%.
docker和compose的设置是默认的,没有任何调整.
当它在Docker中运行时,为什么我不能让CPU饱和?Docker中有一些隐藏的限制吗?我如何发现这个限制?
cpuset_cpus:0,1,2,3,4,5,6,7
和/或cpu_shares: 102400
(默认值的100倍)似乎没有改变这种情况.
关于限制也没有什么有趣的 /var/log/*
它也不是码头bridge
网络.当我net: host
在Docker Compose中使用时,效果是一样的
如果我使用相同的代码运行第二个容器,并且暴露了不同的端口 - 我可以将CPU负载提高到77%,但仍然不像裸机那样100%.请注意,每个容器运行20-40个进程,内部与Passenger负载均衡.
好吧,它似乎与Ubuntu有关.在CoreOS上运行相同的容器 - 我能够使所有核心饱和.
但我仍然不明白这个限制.
为了完全公平,我在法兰克福数据中心的DigitalOcean上采用了2个相同的16GB 8CPU实例.我在最近的Ubuntu和最新的CoreOS alpha上安装了应用程序.
CoreOS 949.0.0: Docker version 1.10.0, build e21da33
Ubuntu 14.04.3: Docker version 1.10.0, build 590d5108
Run Code Online (Sandbox Code Playgroud)
我不确定如何获得完全相同的构建 - 似乎CoreOS内置和只读FS和Ubuntu - 我不知道如何构建完全e21da33.但一般版本是一样的1.10.0
我ab
也在法兰克福数据中心的DigitalOcean上从外部机器运行,以确保ab
不是变化.在这两种情况下我都打了外部IP.参数ab
是相同的(ab -n 40000 -c 1000 -k
),代码是相同的.
结果:
Ubuntu: 58-60% CPU 1162.22 [#/sec] (mean)
CoreOS: 100% CPU 4440.45 [#/sec] (mean)
Run Code Online (Sandbox Code Playgroud)
为了给Ubuntu一些机会,我也尝试添加:
security_opt:
- apparmor:unconfined
Run Code Online (Sandbox Code Playgroud)
但这并没有太大变化.
Ubuntu 14.04.3 NOT OK (50-60% CPU)
Ubuntu 15.10 NOT OK (50-60% CPU)
Debian 8.3 NOT OK (50-60% CPU)
CentOS 7.2.1511 OK (100% CPU)
CoreOS 949.0.0 OK (100% CPU)
Run Code Online (Sandbox Code Playgroud)
仍然不知道限制是什么.似乎与Debian有关.
请不要激动(或火焰我) -这是没有的答案-我只是需要更多的空间比评论将允许!我不是Linux或Docker专家,但我真的很喜欢这种问题,并在周末做了一些研究,并有一些探索的途径可能有所帮助.我没有测试台,所以陷入了僵局.
到目前为止的理论"对于Debian和Ubuntu ......":
Docker将容器和子进程放入一个以某种方式受到限制的cgroup.
操作系统的调度程序和Docker容器中的调度程序(systemd?)在某种程度上与CPU"争斗"并且不断相互替换.
操作系统调度程序将(a)Docker容器和(b)应用程序内部视为单独的竞争资源请求,因此每个约50%
在我看来,Linux的RedHat风格在某种程度上"集成"了docker(阅读"看看它做了什么,并调整了他们的操作系统设置或Docker设置是兼容的").他们做了什么改变呢? - 这可能是有所作为的.
强烈要求在RHEL 6下不使用Docker,而是使用RHEL 7+ - 它们在这些版本之间的RH中发生了什么变化.CPU调度使他们如此热衷于使用7+?
我接下来会看到什么:
研究:https :
//goldmann.pl/blog/2014/09/11/resource-management-in-docker/
http://www.janoszen.com/2013/02/06/limiting-linux-processes-cgroups-解释/
https://github.com/docker/docker/issues/6791
https://github.com/ibuildthecloud/systemd-docker/issues/15
https://unix.stackexchange.com/questions/151883/limiting-进程到不超过10的cpu使用率
http://linux.die.net/man/5/limits.conf
https://marketplace.automic.com/details/centos-官方-泊坞窗图像
https://www.datadoghq.com/blog/how-to-monitor-docker-resource-metrics/
https://libraries.io/go/github.com%2Fintelsdi-x%2Fsnap-plugin集电极-泊坞窗%2Fdocker
https://serverfault.com/questions/356962/where-are-the-default-ulimit-values-set-linux-centos
https://www.centos.org/forums/viewtopic.php ΔT= 8956
https://docs.mongodb.org/manual/reference/ulimit/
http://www.unixarena.com/2013/12/how-to-increase-ulimit-values-in-redhat.html
如果这一切都没有帮助我道歉!
归档时间: |
|
查看次数: |
1783 次 |
最近记录: |