借用朋友石头的一句话,“一个公有云做的好不好,可以看看它的网络和存储。”
的确,不论你用KVM还是Xen,计算虚拟化都做的很好了,用户在不同公有云中关于计算性能的体验,主要源于资源配给。关于公有云超售的现状,大家可以参考清野大哥的博客,在前不久的云计算大会上,清野大哥就这个问题作了非常精彩的讲述。(http://www.qyjohn.net/?p=1948)而网络、存储方面的性能和用户体验,就比较考验研发团队的功力了。
尤其是网络,它对终端用户而言,始终behind the door,但却每时每刻都在影响着用户体验。大家肯定很感兴趣公有云里面的网络是怎么做的,很多人也会考虑,如果我自己做公有云,网络部分应该怎么设计。
在网络方面,由于运营模式和用户使用方式的不同,公有云和私有云考虑的问题有不少差别。较容易想到的有,不同tenant网络隔离,相同tenant内网互通,带宽限制,不同等级VM网络流量Qos,IP管理,内外网IP的NAT,外网IP的安全(防火墙),提供web server漏洞扫描服务,提供Load Balance服务,按流量计费等。
从了解的情况看,目前各公有云普遍采用的是iptables + ebtables + tc的方案,而用SDN的较少。第一个方案里都是很成熟的技术,大家很多都是这方面的专家。这个方案可以说技术上没什么新意,拼的是设计是否合理,考虑问题是否足够细致。但毕竟简单,实用,开发周期短。有利于早日上线,抢占客户。如果采用SDN方案,会更有意思些。
实践出真知,让我们从实验开始吧。云计算大会上获赠某知名公有云的体验券,做了些简单测试。因为我们在VM里面,作为黑盒测试受到很大限制,实验设计也很麻烦,一不能在host上抓包,二不能控制VM分布在哪些Host上。但管中窥豹,从数据还是能做出一些有意思的猜测。
【测试一】先从内网带宽这个最有意思的问题开始
虚机A、B属于同一个tenant,用iperf测试内网带宽。
- ### TCP 测试 ###
- ~# iperf -c 10.200.54.86 -i 30 -t 150
- ------------------------------------------------------------
- Client connecting to 10.200.54.86, TCP port 5001
- TCP window size: 16.0 KByte (default)
- ------------------------------------------------------------
- [ 3] local 10.241.24.103 port 58374 connected with 10.200.54.86 port 5001
- [ ID] Interval Transfer Bandwidth
- [ 3] 0.0-30.0 sec 3.17 GBytes 907 Mbits/sec
- [ 3] 30.0-60.0 sec 3.16 GBytes 905 Mbits/sec
- [ 3] 60.0-90.0 sec 3.18 GBytes 911 Mbits/sec
- [ 3] 90.0-120.0 sec 3.16 GBytes 904 Mbits/sec
- [ 3] 120.0-150.0 sec 3.12 GBytes 893 Mbits/sec
- [ 3] 0.0-150.0 sec 15.8 GBytes 904 Mbits/sec
- ### UDP测试 ###
- ~# iperf -c 10.200.54.86 -i 30 -t 150 -u -b 2G
- ------------------------------------------------------------
- Client connecting to 10.200.54.86, UDP port 5001
- Sending 1470 byte datagrams
- UDP buffer size: 124 KByte (default)
- ------------------------------------------------------------
- [ 3] local 10.241.24.103 port 43894 connected with 10.200.54.86 port 5001
- [ ID] Interval Transfer Bandwidth
- [ 3] 0.0-30.0 sec 3.30 GBytes 945 Mbits/sec
- [ 3] 30.0-60.0 sec 3.30 GBytes 946 Mbits/sec
- [ 3] 60.0-90.0 sec 3.30 GBytes 946 Mbits/sec
- [ 3] 90.0-120.0 sec 3.30 GBytes 945 Mbits/sec
- [ 3] 120.0-150.0 sec 3.30 GBytes 945 Mbits/sec
- [ 3] 0.0-150.0 sec 16.5 GBytes 945 Mbits/sec
- [ 3] Sent 12057641 datagrams
- [ 3] Server Report:
- [ 3] 0.0-150.0 sec 16.5 GBytes 944 Mbits/sec 0.080 ms 19512/12057640 (0.16%)
- [ 3] 0.0-150.0 sec 238017 datagrams received out-of-order
TCP、UDP均接近1Gb,这是一个让人兴奋的结果,也是一个让人担心的结果。计划买多台VM构建network intensive应用的用户肯定非常开心。该公有云如此设计,也许出于以下三种情况:
情况一,国内做公有云的公司都紧盯EC2,而EC2对内网带宽是非常慷慨的。作为一个卖点,国内公司会考虑效仿。下面是国外友人07年测的EC2带宽数据:
- 1 curl -> 75MB/s (cached, i.e., no I/O on the apache server)
- 2 curls -> 88MB/s (2x44MB/s) (cached)
- 3 curls -> 96MB/s (33+35+28 MB/s) (cached)
情况二,满足用户对network intensive应用的需求,同时有相应方案保证云里存在大量此类用户时,用户体验不会变差。EC2应该属于这种情况,发展了这么多年,人家敢给这么高的带宽,肯定有解决方案;
情况三,以“用户有高带宽需求”为理由,在设计中忽略内网带宽这个问题,内网不做限制。
如果是情况二,是非常令人佩服的。但如果是情况三,则是比较欠考虑的。不清楚该公有云的物理网络是如何设计的,不好妄下结论。但另一家知名公有云的服务器上,VM流量走的是单块1Gb网卡,内网不限速。如果用iperf测试的话,应该能得到类似结果。考虑到10Gb网卡昂贵的价格,我们所测试的公有云,也采用1Gb网卡的可能性较大,如果有区别,顶多用多块1Gb网卡做了bond,拓宽带宽的同时,引入failover。
公有云设计时,应尽可能保证公平,让支付相同费用的用户,尽可能获得接近的性能;同时要能保证调皮用户的一些恶意行为,不会严重影响别人的用户体验。如果该公有云的设计符合上述猜想的最坏情况,即单张1Gb网卡,内网不限速,且没有Qos,那多个network intensive应用被分配到同一个物理机时,就会出现抢带宽的现象。更进一步,如果有调皮的用户,拥有两台虚机,分布在不同物理机上,同一租户的VM通信不会被iptables禁掉,并且数据包会经过物理网络,然后他在VM之间疯狂地发UDP包,把物理网卡打满。那这两台物理机上的其他VM就悲催了。以上两种极端情况都会导致用户体验变差。OK,也许你说可以引入Qos,但同一级别的VM还是会受影响。
那应该怎么处理这一问题呢?两种情况:如果能像EC2那样,有合理的硬件、软件方案,保证大量network intensive应用不会导致用户体验变差,那提供1Gb带宽,绝对是有力的竞争资本;如果暂时做不到EC2那么牛,网络方案接近上面的猜测,个人觉得再仔细考虑一下内网带宽,是很有必要的。毕竟不是所有用户都要部署network intensive应用,另外,即使用户的web server、app server 、db server分离,如果该用户外网带宽购买的很小,那他对于内网带宽要求很高的可能性又有多大呢?没做过网站架构,呼唤专家拍砖、教育,呵呵。对于没有此类需求的用户,限制一点内网带宽,对现有方案就降低了一分风险。例如对disk intensive应用,用户对内网带宽也许不那么敏感,或者说对带宽的敏感性同时也取决于disk读写性能。该公有云中,在不同VM间做大文件传输时,即使1Gb带宽,瓶颈也是在磁盘IO性能。参见以下两组测试数据。
【测试二】本地文件读写性能
- ### 纯写速度 ###
- ~# time dd if=/dev/zero of=/tmp/testfile bs=8k count=128000
- 128000+0 records in
- 128000+0 records out
- 1048576000 bytes (1.0 GB) copied, 42.7901 s, 24.5 MB/s
- real 0m42.856s
- user 0m0.008s
- sys 0m0.784s
- ### 纯读速度 ###
- ~# time dd if=/tmp/testfile of=/dev/null bs=8k
- 128000+0 records in
- 128000+0 records out
- 1048576000 bytes (1.0 GB) copied, 15.8374 s, 66.2 MB/s
- real 0m15.900s
- user 0m0.016s
- sys 0m0.536s
- ### 读写速度 ###
- ~# time dd if=/tmp/testfile of=/tmp/testfile_new bs=8k
- 128000+0 records in
- 128000+0 records out
- 1048576000 bytes (1.0 GB) copied, 113.736 s, 9.2 MB/s
- real 1m53.748s
- user 0m0.024s
- sys 0m1.364s
可以更好地设计测试方法,使得测试数据更加精准,但简单测试的结果,已经很好地说明了在该公有云中做文件传输,瓶颈不在内网带宽,而是磁盘IO。
【测试三】VM间文件下载性能
虚机A、B属于同一个tenant。虚机A上跑nginx,虚机B从A下载文件。测试文件大小分别为5M、30M、100M、300M、500M、1G、5G,内网带宽接近1Gb。
testfile大小 |
下载时间 |
下载速度 |
5G |
7m 53s |
10.8 MB/s |
1G |
71s |
14.4 MB/s |
500M |
20s |
25.6 MB/s |
300M |
2.9s |
102 MB/s |
100M |
0.9s |
110MB/s |
30M |
0.3s |
105 MB/s |
5M |
0.08s |
66.3 MB/s |
表1 文件下载性能测试结果
测试是件很严肃的事情,可以因测试方法不好而有偏差,但不能篡改数据。为了防止大家怀疑数据的真实性,这里贴出1G文件的测试结果。篇幅原因,其余的就不一一贴了,感兴趣的可以联系俺索要数据,或者自己测一测。
- ### testfile大小为1G ###
- ~# wget 10.241.24.103/testfile
- --2012-06-06 00:56:39-- http://10.241.24.103/testfile
- Connecting to 10.241.24.103:80... connected.
- HTTP request sent, awaiting response... 200 OK
- Length: 1073741824 (1.0G) [text/plain]
- Saving to: testfile
- 100%[====================================>] 1,073,741,824 9.45M/s in 71s
- 2012-06-06 00:57:50 (14.4 MB/s) - testfile
从测试二、测试三的数据可以看出,在该公有云中,如果用户有传输大量大文件的需求,即使内网带宽为1Gb,磁盘IO的瓶颈作用,仍会使得用户根本享受不到那么多带宽。Hadoop就是一个典型例子,专门请教了做Hadoop的朋友,他们在自己的物理机上测的磁盘IO高于150MB/s,大量大文件回传时,如果用1Gb的网卡,弄不好网络反而成为瓶颈,因此他们对带宽的需求肯定很高。但在该公有云里,磁盘IO并不高,本地纯写只有24.5MB/s,1G的大文件平均下载速率14.4MB/s,因此相对来说,1G的带宽有点超配。用该公有云做Hadoop的同志们,可能要对磁盘IO带来的性能瓶颈有心理准备。这很可能是公有云当前普遍存在的问题,Amazon EMR不也被人诟病么。
回到网络话题,基于测试二、测试三可以看出,在网络方案不成熟的情况下,硬推1Gb内网带宽是有潜在问题的,有可能影响用户体验。而公有云卖的是服务,跟互联网公司一样,用户体验就是生命!因此,针对公有云里存在的几种用户(network intensive用户,非network intensive用户,或者受磁盘IO影响而不可能全面利用1Gb带宽的用户),也许应该重新考虑一下内网带宽的设计,然后设法引入Network Resource Pool和Networking DRS(实际上还有别的一些办法可想)。总之在网络方案能做的像EC2那么强大之前,从带宽做起毕竟能降低一些风险,从而在用户量大了之后仍能保证用户体验,而不是单纯追求“我和EC2提供一样的内网带宽”这样的口号。