一个计算机技术爱好者与学习者

0%

好好学OpenStack:虚拟机在线迁移实验V2——下

1. 前言

毕业论文送审的日期是3月22日,cloud2019的deadline也是3月22日。大概从2月27日开始写毕业论文,早八点半晚十点,周末不休,3月22日终于写完送审了,算是完成了一件大事。之后,还有两件大事:一个是实现阅卷系统,一个是发表小论文。

本来打算3月20日抽出一天时间做实验写小论文,没想到实验环境崩了!无奈只能放弃cloud。论文送审后一直在忙着修复实验环境,2月24日晚上十点左右,终于修复成功!是时候完成小论文了!

2. 前情回顾

《虚拟机在线迁移实验V2——上》一文中,实验遇到瓶颈,所以不得不重新设计实验。经过思考,打算把web服务换成mysql服务,在实例中进行测试。但是,实验表明,如果在迁移过程中对mysql试压,那么会出现和web服务同样的问题,迁移无法成功。所以,本文中去掉了服务降级这个指标,只测量停机时间、迁移时间和迁移数据量。

3. 实例准备

1、在horizon控制台,项目,计算,镜像。使用xenial-server-cloudimg-amd64-disk1.img镜像创建ubuntu16的镜像模板。

2、创建实例类型m1.tiny2,CPU个数为1,内存为512M,磁盘为5GB。

3、使用ubuntu16的镜像模板创建实例ubuntu0、ubuntu1、ubuntu2、ubuntu3、ubuntu4,实例类型分别选择m1.tiny2、m1.small、m1.medium、m1.large、m1.xlarge。之所以不使用默认的m1.tiny,是因为m1.tiny的磁盘太小,只有1G,无法安装ubuntu16。

4、创建成功后,分别分配浮动IP。

PS:在进行迁移实验时,关闭其他实例,防止资源占用产生干扰。

4. 脚本和软件准备

4.1. 总迁移时间

在控制节点,新建mtime.sh脚本:

1
2
3
4
5
#!/bin/bash
time1=`grep 'live-migration' list.log | head -n 1 | awk '{print $24}'`
time2=`grep 'live-migration' list.log | head -n 1 | awk '{print $26}'`
time=$(($(date +%s -d $time2) - $(date +%s -d $time1)));
echo "$time s";

新建allmtime.sh脚本,可以计算所有迁移时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash
time1=`grep 'live-migration' list.log | awk '{print $24}'`
time2=`grep 'live-migration' list.log | awk '{print $26}'`
IPS=' '
array1=($time1)
array2=($time2)
length=${#array1[@]}
COUNTER=0
while [ $COUNTER -lt $length ]
do
COUNTER=`expr $COUNTER + 1`
t1=${array1[COUNTER]}
t2=${array2[COUNTER]}
time=$(($(date +%s -d $t2) - $(date +%s -d $t1)));
echo "$time s";
done

4.2. 停机时间

在控制节点,新建downtime.sh脚本:

1
2
3
4
5
#!/bin/bash
transmitted=`grep 'packets transmitted' ping.log | tail -n 1 | awk '{print $1}'`
received=`grep 'packets transmitted' ping.log | tail -n 1 | awk '{print $4}'`
lost=`expr $transmitted - $received`
echo "downtime is $lost ms"

4.3. 迁移数据量

在两个计算节点,安装iptraf-ng。
apt install iptraf-ng

4.4. xshell

使用xshell,打开两个controller节点的shell,一个登录实例B后用来ping实例A;一个用来执行迁移命令,迁移之后执行mtime.sh脚本。打开一个compute1节点的shell,用来运行iptraf-ng。打开一个compute2节点的shell,用来运行iptraf-ng。

5. 实验流程

假设当前只启动了ubuntu0实例,nova show ubuntu0位于compute1节点。

1、在两个compute节点启动iptraf-ng,配置参考《虚拟机在线迁移的性能统计》

2、在实例中启动压力测试软件,或者在两个compute节点中启动网络故障模拟软件。(flavor实验中不需要)

3、在实例B中ping实例ubuntu0
sudo ping ubuntu0_internal_ip -i 0.001 >> ping.log

4、在controller中执行迁移
nova live-migration ubuntu0 compute2

5、观察compute节点的iptraf-ng,等到流量不再增加。关闭压力测试软件或者网络故障模拟软件,然后在实例B中Ctrl+C结束ping命令。

6、在controller节点记录迁移列表
nova migration-list > list.log

7、controller节点执行mtime.sh得到迁移时间,在实例B中执行downtime.sh得到停机时间,在两个计算节点观察iptraf-ng得到迁移数据量。

以上流程,适用于接下来的所有实验。

6. flavor实验

按照实验流程,分别使用五个flavor,进行五次迁移实验,记录实验结果。

1
2
3
4
5
6
#Flavor    迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
tiny 24 297 275 277
small 26 14 329 332
medium 27 69 373 375
large 30 50 846 852
xlarge 31 57 923 929

由实验结果可以看出,随着CPU和内存的增加,迁移时间也会随之增加。tiny模板的停机时间最大,其他模板的停机时间在10ms到70ms之间。源主机的迁出数据量和目标主机的迁入数据量也会随之增加,而且迁入数据量要比迁出数据量多2到6MB。

6.1. 系统压力实验

6.2. CPU实验

接下来的实验,都使用small类型的flavor。
1、先给实例安装stress-ng
sudo apt install stress-ng

2、在实例中创建一个CPU进程,CPU占用率10%
stress-ng -c 1 -l 10

3、创建CPU进程,CPU占用率20%-100%,记录实验结果。

1
2
3
4
5
6
7
8
9
10
11
12
# CPU占用率%   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
Idle 26 14 329 332
10% 27 15 330 333
20% 26 18 331 333
30% 24 403 330 333
40% 25 3332 330 334
50% 25 3175 330 332
60% 24 505 327 329
70% 26 10372 328 331
80% 25 292 329 331
90% 26 124 330 333
100% 26 573 328 330

由实验结果可以看出,随着CPU占用率的提高,迁移时间没有太大变化。停机时间在CPU使用率大于30%之后,停机时间普遍大于100ms,偶尔会出现停机时间大于3s,没有明显的规律。迁移数据量并没有太大变化,迁入数据一直比迁出数据多2到4MB。

在迁移时,偶尔会出现OpenStack显示实例迁移成功,但是实例停机时间特别长(大于600s)的情况。本文中认为这种情况属于异常,会重做实验,去除这些异常值。

6.3. 内存实验

1、在实例中创建一个200M的内存进程
stress-ng --vm 1 --vm-bytes 200M --vm-keep

2、创建内存进程,内存占用400M-1600M,记录实验结果。

1
2
3
4
5
6
7
8
9
10
# 内存占用MB   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
Idle 26 14 329 332
200 79 3090 6543 6585
400 199 144 21344 21481
600 308 440 33368 33585
800 422 560 47712 48019
1000 541 23560 61417 61814
1200 649 250080 74617 75103
1400 925 27230 107004 107702
1600 1049 3140 121600 122390

从实验结果中可以看出,随着内存使用量的增加,总迁移时间急剧增加。停机时间一般大于100ms,有时甚至超过20s。迁移数据量也急剧增加,数量级变为GB。当内存占用1600MB时,总迁移时间超过1000s,迁移数据大于120GB,传输到目标机器的数据与从源机器传输的数据之间的差异为700MB。

6.4. 磁盘实验

1、在实例中创建2个写入进程,每个进程写入大小为1M的文件。
stress-ng -d 2 --hdd-bytes 1M

2、在实例中创建4-20个写入进程,记录实验结果。

1
2
3
4
5
6
7
8
9
10
11
12
# 写入进程数   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
0 26 14 329 332
2 42 510 2178 2192
4 50 100 2954 2974
6 127 3350 12456 12537
8 137 490 13519 13608
10 172 4570 18179 18296
12 182 6340 18948 19072
14 172 6860 18034 18150
16 189 410 19569 19696
18 179 600 18790 18910
20 246 3160 26687 26859

从实验结果中可以看出,随着写入进程的增加,迁移时间也在不断增加。停机时间普遍大于400ms,频繁出现大于3s停机时间。迁移数据量呈现阶梯式变化,数量级变成GB。当写入进程数为20时,迁移时间约为250s,迁移数据约为27GB。

7. 网络故障实验

网络故障实验之前,需要重启测试实例,否则测出的迁移数据量会偏大一个数量级。

7.1. 网络延迟

1、在compute节点(迁出节点)添加网络延迟20ms
sudo tc qdisc add dev eth1 root netem delay 20ms
注:原本的延迟在0.2ms上下。

2、将网络延迟修改为40ms-200ms,记录实验结果。
sudo tc qdisc replace dev eth1 root netem delay 40ms

1
2
3
4
5
6
7
8
9
10
11
12
# 网络延迟ms   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
0 26 14 329 332
20 27 6720 354 356
40 29 320 354 356
60 32 3200 355 357
80 39 160 356 358
100 39 3370 360 362
120 43 320 357 358
140 45 310 358 360
160 51 580 356 357
180 51 5480 356 357
200 59 620 380 382

由实验结果可以看出,随着网络延迟时间的增加,迁移时间也会随之增加。停机时间普遍大于300ms,经常出现3s到7s的停机时间。迁出数据量和迁入数据量没有明显的变化,差值也保持在稳定的范围。

此外,在网络延迟实验中,实例死机(停机时间大于600s)的频率要高于CPU、内存和磁盘实验。

3、取消模拟:
sudo tc qdisc del dev eth1 root

7.2. 丢包

1、两个计算节点,都模拟丢包率1%
sudo tc qdisc add dev eth1 root netem loss 1%

2、将模拟丢包率修改为1%-10%,记录实验结果。
sudo tc qdisc change dev eth1 root netem loss 2%

1
2
3
4
5
6
7
8
9
10
11
12
# 丢包率   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
0% 26 14 329 332
1% 24 1460 354 356
2% 26 4190 355 356
3% 30 3990 358 359
4% 38 2640 357 357
5% 43 7610 359 360
6% 67 5960 361 361
7% 131 43890 363 363
8% 170 20850 368 368
9% 283 11430 371 371
10% 392 67520 365 365

从实验结果中可以看出,随着丢包率的增大,迁移时间也会明显增加。丢包率大于7%之后,停机时间普遍大于10s,甚至出现了68s的停机时间。迁移数据量变化不大,迁入迁出数据量的差值稳定在1MB以内。

3、取消模拟:
sudo tc qdisc del dev eth1 root

7.3. 包重复

1、两个计算节点,都模拟包重复率10%
sudo tc qdisc add dev eth1 root netem duplicate 10%
随机产生 10% 重复的包。

2、将模拟包重复率修改为20%-100%,记录实验结果
sudo tc qdisc change dev eth1 root netem duplicate 20%

1
2
3
4
5
6
7
8
9
10
11
12
# 包重复率   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
0% 26 14 329 332
10% 32 180 652 656
20% 28 180 712 717
30% 27 120 769 774
40% 28 300 840 845
50% 29 3060 887 893
60% 29 140 959 965
70% 28 540 1016 1023
80% 32 440 1073 1080
90% 35 3490 1135 1142
100% 32 90 1196 1204

从实验结果可以看出,随着包重复率的增加,总的迁移时间变化不大。停机时间普遍大于100ms,偶尔出现大于3s的情况,没有明显的变化趋势。迁移数据量随着包重复率的增加而增大,迁入数据量和迁出数据量的差值在4M到8M。

3、取消模拟:
sudo tc qdisc del dev eth1 root

7.4. 包损坏

1、两个计算节点,都模拟包损坏率1%
sudo tc qdisc add dev eth1 root netem corrupt 1%
随机产生 1% 损坏的报文(在报文的随机位置造成一个比特的错误)。

在ping的时候会报错:Warning: time of day goes back , taking countermeasures,不过没关系,不影响我们的停机时间统计结果。

2、将模拟包损坏率修改为2%-5%,记录实验结果。
sudo tc qdisc change dev eth1 root netem corrupt 2%

1
2
3
4
5
6
7
8
# 包损坏率   迁移时间s    停机时间ms    迁出数据量MB   迁入数据量MB
0% 26 14 329 332
1% 26 660 333 334
2% 27 1120 334 335
3% 35 4160 337 337
4% 149 2760 342 342
5% 254 15040 352 353
6% 1228 117760 356 356

从实验数据中可以看出,包损坏率大于3%之后,迁移时间会急剧增加。停机时间普遍大于1s,总体呈上升趋势。停机时间在包损坏率等于5%和6%时发生突变。迁移数据量没有明显变化。当包损坏率等于6%时,迁移时间超过20min,停机时间接近120s。

而且,在本文中的实验环境中,包损坏率大于等于7%时,迁移会失败。迁移进行了1600s还没有完成,OpenStack会自动撤销迁移。还有一个有趣的现象是,正常迁移中只要使用49152端口就可以了,在出现包损坏的情况下,会使用49153-49216端口来辅助传输数据。

3、取消模拟:
sudo tc qdisc del dev eth1 root

PS:如果迁移无法成功,那么就取消包损坏的模拟,或者撤销迁移。

1
2
3
nova migration-list
nova server-migration-show 29a58cf7-646a-43f2-b1d6-89ec421fc9d6 152
nova live-migration-abort 29a58cf7-646a-43f2-b1d6-89ec421fc9d6 152

8. 后记

从以上结果可以看出,在OpenStack中选择VM进行迁移的时候,为了提高迁移的效率,有以下几个结论:
(1)选择更小的flavor,能够减少迁移时间和迁移数据量。
(2)基本不用考虑CPU使用率,因为它对迁移影响很小。
(3)选择内存占用小的VM,能够减少迁移时间、停机时间和迁移数据量。
(4)选择磁盘写入进程较少的VM,能够减少迁移时间、停机时间和迁移数据量。
(5)包延迟会稍微增加迁移时间,对停机时间和迁移数据量的影响很小。
(6)丢包会急剧增加迁移时间,对停机时间和迁移数据量的影响很小。
(7)包重复会增加一些迁移数据量,但是对迁移时间和迁移停机时间的影响很小。
(8)包损坏率小于等于3%时,对迁移影响较少,可以忽略。包损坏率大于4%之后,迁移时间和停机时间会急剧上升。包损坏率大于7%时,已经无法迁移成功。

至此,实验完成,数据有了,就差论文了!加油加油!