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

文章目录
  1. 1. 前言
  2. 2. 性能指标
  3. 3. 测量方法
    1. 3.1. 监控
    2. 3.2. 迁移时间
    3. 3.3. 停机时间
    4. 3.4. 迁移数据量
    5. 3.5. 应用性能
  4. 4. 书签

前言

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,并添加执行权限。

停机时间

参考How to measure Migration time and Down time

我们的虚拟机有两个IP,一个是内网IP:10.0.2.159,一个是浮动IP:10.0.2.159。
在迁移过程中,可以ping内网IP或者浮动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

由ping命令的统计信息可以求出停机时间:
(44127/1000)*0.11 = 4.85s

写成脚本为:

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

# downtime = (alltime/1000)*(losstime/100)
num=`expr $alltime \* $losstime`
downtime=$(echo "scale=2; $num / 100000" | bc)
echo "downtime is $downtime s"

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

github有一个pingtrack项目,也可以获取停机时间:
sudo ./pinger.py -s 10.0.2.159 -d 1 -u 0.01 -o 0.01
但是,每次迁移,都会出现多次停机时间。问题来了,是真的有很多次停机,还是pingtrack项目有问题?需要我们自己写一个脚本来验证一下:

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,说明实例没有响应的序列号是连续的,证明了停机只有一次,pingtrack项目有问题。同时,利用这个icmq_seq数量,也可以计算停机时间:
474*0.01 = 4.74s
综上,利用icmq_seq数量的算法(简称seq算法)和利用ping命令的统计信息的算法(简称statistics算法)相差0.1s。seq算法更精确,statistics算法更简单。

迁移数据量

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

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

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,比如SPECweb2009,收费,安装使用复杂。

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

书签

An analysis of the performance of live migration in Openstack

An analysis of the performance of block live migration in Openstack

Performance analysis of “post-copy” live migration in Openstack