0%

虚拟机在线迁移的性能统计

前言

OpenStack中共享存储和非共享存储的虚拟机迁移环境都已经搭建完成,接下来可以进行实验了。对于不同的宿主机、不同的实例、不同的负载,虚拟机迁移的性能也会有所不同。那么,虚拟机迁移的性能指标有哪些?又该怎样统计呢?本文就来研究一下。

性能指标

参考论文《Virt-LM: a benchmark for live migration of virtual machine》,可以得知,虚拟机迁移过程中的主要性能指标有四个:

  • 整体迁移时间:从迁移开始到迁移结束的时间。
  • 虚拟机停机时间:迁移过程中虚拟机停机(停止服务)的时间。
  • 迁移数据量:在虚拟机迁移期间传输的数据总量。
  • 应用程序的性能:迁移过程中对虚拟机中应用程序产生的影响。

测量方法

监控

既然是实验,那么肯定要收集实验过程中的数据。郝同学给这个四个节点的OpenStack集群安装了ganglia,用来监控各种指标。但是,ganglia更适合监控实时数据和观察变化,不适合进行统计。

迁移时间

整体迁移时间怎么测出来?通过观察图表?不靠谱。叶可江老师提供了思路,整体迁移时间的话,可以通过日志来获取:
tail -n 40 /var/lib/docker/volumes/kolla_logs/_data/nova/nova-compute.log

通过查看迁出宿主机的日志,然后对比ganglia图表,可以找到两个关键节点:

1
2
3
2018-11-22 09:59:42.442 5 INFO nova.virt.libvirt.migration [req-d9849256-eaa8-4446-9cec-9545b74df126 202e7852a6074540a70638eed185538e eb83bf3b057f45e1b386cbc8c0702ae1 - default default] [instance: eebe068a-ba85-4905-a39b-f003a7480b14] Increasing downtime to 50 ms after 0 sec elapsed time
......
2018-11-22 10:00:02.984 5 INFO nova.compute.manager [req-4b409237-6c82-4b56-ae4c-9f905a4f932e b2edc935f89d4d2684ec4039c02a21cc ab7e3eb8c00d4299afd8572e1ec437bf - default default] [instance: eebe068a-ba85-4905-a39b-f003a7480b14] VM Stopped (Lifecycle Event)

但是,依然需要手动来计算迁移时间,很麻烦,那就写一个脚本来搞定吧!参考linux shell 时间运算以及时间差计算方法

1
2
3
4
5
6
#!/bin/bash
time1=`grep nova.virt.libvirt.migration /var/lib/docker/volumes/kolla_logs/_data/nova/nova-compute.log | tail -n 1 |awk '{print $2}'`;
time2=`grep 'VM Stopped' /var/lib/docker/volumes/kolla_logs/_data/nova/nova-compute.log | tail -n 1 | awk '{print $2}'`;
# 计算时间差
time=$(($(date +%s -d $time2) - $(date +%s -d $time1)));
echo "$time s";

以上脚本,保存为time.sh,并添加执行权限。

另外,还可以通过nova migration-list > list.log查看到迁移的开始时间和结束时间。然后通过脚本计算迁移时间:

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";

不过,这种方法测出的迁移时间,比我们从nova-compute.log日志中测出的迁移时间,要多出7秒左右。这种方法应该更准确一些,毕竟是OpenStack自己记录的。

停机时间

参考How to measure Migration time and Down time,使用ping命令来测量停机时间。

我们的虚拟机有两个IP,一个是内网IP,一个是浮动IP。外部机器可以直连的,一般是浮动IP,所以在迁移过程中,建议ping浮动IP,比如sudo ping 10.0.2.159 -i 0.01 >> ping.log。ping.log中的信息为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PING 10.0.2.159 (10.0.2.159) 56(84) bytes of data.
64 bytes from 10.0.2.159: icmp_seq=1 ttl=63 time=3.40 ms
64 bytes from 10.0.2.159: icmp_seq=2 ttl=63 time=1.15 ms
64 bytes from 10.0.2.159: icmp_seq=3 ttl=63 time=1.17 ms
64 bytes from 10.0.2.159: icmp_seq=4 ttl=63 time=1.33 ms
......
64 bytes from 10.0.2.159: icmp_seq=4139 ttl=63 time=1.17 ms
64 bytes from 10.0.2.159: icmp_seq=4140 ttl=63 time=1.05 ms
64 bytes from 10.0.2.159: icmp_seq=4141 ttl=63 time=1.12 ms
64 bytes from 10.0.2.159: icmp_seq=4142 ttl=63 time=1.06 ms

--- 10.0.2.159 ping statistics ---
4142 packets transmitted, 3668 received, 11% packet loss, time 44127ms
rtt min/avg/max/mdev = 0.580/1.412/36.648/1.407 ms, pipe 3

由统计信息可以求出停机时间:

1
2
3
4
# 方法一:(缺失的icmp_seq总数)*(时间间隔)
(4142-3668)*0.01=4.74s
# 方法二:(总时间)*(icmp_seq缺失百分比)
(44127/1000)*0.11 = 4.85s

两种方法相差0.1s,方法一更精确一些。如果想要更加精确,还可以把ping命令的时间间隔调整为1ms。

方法一写成脚本为:

1
2
3
4
5
6
7
#!/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"
downtime=$(echo "scale=3; $lost / 1000" | bc)
echo "downtime is $downtime s"

方法二写成脚本为:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
time_str=`grep 'packets transmitted' ping.log | tail -n 1 | awk '{print $10}'`
loss_str=`grep 'packets transmitted' ping.log | tail -n 1 | awk '{print $6}'`
time_num=`echo ${time_str%ms}`
loss_percent=`echo ${loss_str%\%}`

# downtime = (time_num)*(loss_percent/100)/1000
num=`expr $time_num \* $loss_percent`
downtime=$(echo "scale=3; $num / 100000" | bc)
echo "downtime is $downtime s"

以上方法求出的停机时间,是总的停机时间,无论迁移过程中有几次停机,该方法都是适用的。我们会好奇,实际迁移过程中,停机是否只有一次?我们写一个脚本来寻求答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
# 去掉头部和尾部,保留第五列
cat ping.log | sed '1d' | tac | sed '1,4d' | tac | awk '{print $5}' > seq.log &&
# 得到最后一行的序列号
max=`tail -n 1 seq.log | awk -F '=' '{print $2}'`
# 所有序列号赋值给数组
array_str=`cat seq.log | awk -F '=' '{print $2}'`
IPS=' '
array=($array_str)

# 打印没有响应的序列号
COUNTER=0
while [ $COUNTER -lt $max ]
do
COUNTER=`expr $COUNTER + 1`
if [[ "${array[@]}" =~ $COUNTER ]]
then
continue
else
echo $COUNTER >> result.log
fi
done &&

# 对比seq数量
start=`head -n 1 result.log`
end=`tail -n 1 result.log`
num=`expr $end - $start + 1`
echo "if continuous, num should be $num"

result_str=`cat result.log`
IPS='\n'
result=($result_str)
echo "real num is ${#result[@]}"

脚本输出两个474,说明实例没有响应的序列号是连续的,证明了停机只有一次。比如result.log中为{3,4,5,6,7},那么7-3+1=5,集合中元素个数也为5,证明连续。比如result.log中为{3,4,5,10,11},那么11-3+1=9,集合中元素个数为5,证明不连续。

带宽

测量出的downtime为4.74s,很不合理,因为虚拟机迁移理论上的停机时间是毫秒级的!是因为带宽太低导致停机时间过长吗?可以用如下方法进行测试:
1、compute1和compute2上都安装iperf
sudo apt install iperf

2、compute1上启动iperf服务
iperf -s

3、compute2上启动iperf客户端
iperf -c 192.168.56.112 -i 1

迁移数据量

对于迁移数据量,可以使用iptables对端口进行监控,参考Linux下对端口流量进行统计Linux 使用iptables进行shadowsocks流量统计。但是,计算节点网络非常复杂,郝同学不想对其进行修改,所以采用另外一种方案,iptraf,参考使用iptraf查看TCP/UDP某个特定端口的带宽与流量

1、两个计算节点安装iptraf
sudo apt install iptraf

需要注意的是,iptraf只支持名为ethX的网卡。想要显示enoX、enp0sX网卡,要么网卡重命名,要么安装使用iptraf-ng。
sudo apt install iptraf-ng

2、启动iptraf
sudo iptraf
启动后,进入到一个字符界面。

3、设置
Configure… -> Additional ports…-> 22 -> Exit Configuration -> Statistical breakdowns… -> By TCP/UDP port -> eth0 -> statistic view

参考Configure live migrations,可以得知:

By default, libvirt uses the TCP port range from 49152 to 49261 for copying memory and disk contents. Compute hosts must accept connections in this range.

所以在实际使用的时候,端口设置为49152 to 49261。重新进入统计页面,之前的统计数据会清零。

应用性能

Web应用的性能,主要包括执行时间、传输速度、吞吐量、资源占用率。

基准测试(benchmarking)是一种测量和评估软件性能指标的活动。你可以在某个时候通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定那些变化对性能的影响。这是基准测试最常见的用途。其他用途包括测定某种负载水平下的性能极限、管理系统或环境的变化、发现可能导致性能问题的条件,等等。详情参考什么是基准测试?

对于性能的监控,最简单的思路是Apache Benchmark。使用ab来监控Web服务的性能,检查迁移过程中会发生哪些变化。但是,ab什么时候运行?什么时候停止?请求多少次?怎么计算迁移过程中的平均性能?这些都不能确定。
如果使用cAdvisor+prometheus呢?参考linux工匠之docker和kubernetes的监控(cadvisor+prometheus)。不行,因为这种方法监控的是docker容器,收集的是CPU、内存等数据,而不是Web性能数据。
使用SPEC?也不好,收费,安装使用复杂。

很绝望,前辈们都是怎么进行测试的?不管了,先不考虑应用性能指标。

书签