BC-Linux系统调优-虚拟化实时性提升

背景

电信云NFV应用场景下,对系统提出“实时性”需求,准确来说,在虚拟化场景下虚机也需要满足低时延或者实时应用需求。本文主要针对该需求提供部署方案以及相应调优手段,达到减少虚机时延的目的。

宿主机BIOS配置

关键的步骤如下:

禁用电源管理功能,包括CPU处理器深度休眠状态;

关闭超线程以及逻辑CPU处理器的相关选项;

配置完成后,可以通过hwlatdetect命令测试效果:

*# hwlatdetect

*hwlatdetect: test duration 120 seconds

*detector: tracer

*parameters:

*Latency threshold: 10us

*Sample window: 1000000us

*Sample width: 500000us

*Non-sampling period: 500000us

*Output File: None

*

*Starting test

*test finished

*Max Latency: Below threshold

*Samples recorded: 0

*Samples exceeding threshold: 0

宿主机系统配置

安装系统

建议安装下载安装BC-Linux 7.3系统:

配置yum源

添加repo开启BC-Linux的RT源以及VIRT源:

*# cat /etc/yum.repos.d/BC-Linux-RT.repo

*...

*[rt]

*name=BC-Linux-$releasever - RT

*baseurl=http://mirrors.BC-Linux.org/BC-Linux/kernel/rt/el7.3/$basearch/

*gpgcheck=0

*gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-BC-Linux-7

*...

*

*# cat /etc/yum.repos.d/BC-Linux-virt.repo

*...

*[virt]

*name=BC-Linux-$releasever - virt

*baseurl=http://mirrors.BC-Linux.org/BC-Linux/product/virt/el7.3/$basearch/

*gpgcheck=0

*gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-BC-Linux-7

*...

安装依赖

通过yum安装实时内核,虚拟化组件以及tuned调优配置:

*# yum install kernel-rt kernel-rt-kvm

*# yum install libvirt qemu-kvm-rhev

*# yum install tuned tuned-profiles-nfv

tuned配置

首先查看NUMA拓扑信息,我们需要隔离部分CPU核以保留给虚机使用:

*# lscpu | grep ^NUMA

*NUMA node(s): 2

*NUMA node0 CPU(s): 0-7

*NUMA node1 CPU(s): 8-15

为了测试效果,这边预留4(4-7)个CPU,配置如下:

*# cat /etc/tuned/realtime-virtual-host-variables.conf

*isolated_cores=4-7

执行tuned-adm命令使其生效:

*# tuned-adm profile realtime-virtual-host

*# tuned-adm active

*Current active profile: realtime-virtual-host

该profile配置生效时,会在内核引导项中添加如下启动参数:

isolcpus: 指定配置在realtime-variables.conf 文件里的隔离CPU列表。

nohz:在CPU处于ide状态时,停止周期时钟。默认值是off。

nohz_full:如果只有一个任务运行在某CPU上,停止周期时钟(需要将nohz设置为on)。

intel_pstate=disable:防止intel idel驱动程序管理电源及CPU频率。

nosoftlockup:防止内核检测用户态线程中的softlockup。

rcunocbs:使用rcunocbs来指定cpu进行卸载RCU callback processing。

配置大页

在grub配置/etc/grub2.cfg对应实时内核linux16行添加如下设定:

default_hugepagesz=1G hugepagesz=1G

default_hugepagesz是默认HugeTLB页大小,hugepagesz是指定HugeTLB页的大小。HugeTLB特性则允许将某些页的尺寸增大到2MB或1GB,从而大大减小TLB的尺寸,提高缓冲区的命中率。

在/etc/sysctl.conf添加如下配置申请32个大页(本例中虚机内存大小32G)

*# cat /etc/sysctl.conf

*...

*vm.nr_hugepages=32

调优内核参数

在grub配置/etc/grub2.cfg对应实时内核linux16行添加如下设定:

idle

=

poll processor

.

max_cstate

=

1

iommu

=

pt intel_iommu

=

on mce

=

off pcie_asmp

=

off tsc

=

reliable

idel=poll:poll选项强制CPU轮询并执行空循环,这可以避免频繁唤醒空闲CPU并略微提高性能。

processor.max_cstate=1:强制指定CPU的最大C-state值,C0为正常状态。

iommu=pt和inteliommu=on:使用 igbuio 驱动时必须携带 iommu=pt 参数。 这使得主机可以直接通过DMA重映射查找。 另外,如果内核中没有设置 INTELIOMMUDEFAULTON 参数,那么也必须使用 inteliommu=on 参数。

mce=off:彻底禁用MCE(Machine Check Exception)。MCE是用来报告主机硬件相关问题的一种日志机制。

pcieasmp=off:使用 pcieaspm kernel 参数可以启用或者禁用ASPM,其中 pcie_aspm=off 会禁用ASPM。

tsc=reliable: 表示TSC时钟源是绝对稳定的,关闭启动时和运行时的稳定性检查。

重启宿主机验证配置

分别验证tuned配置,大页以及内核调优参数是否已经生效:

*# tuned-adm active

*Current active profile: realtime-virtual-host

*

*# cat /proc/meminfo | grep -i huge

*HugePages_Total: 32

*HugePages_Free: 0

*HugePages_Rsvd: 0

*HugePages_Surp: 0

*Hugepagesize: 1048576 kB

*

*# cat /proc/cmdline

*BOOT_IMAGE=/vmlinuz-3.10.0-514.26.1.1.rt56.442.el7.BC-Linux.x86_64 root=/dev/mapper/bel00-root ro crashkernel=512M rd.lvm.lv=bel00/root rd.lvm.lv=bel00/swap LANG=en_US.UTF-8 idle=poll processor.max_cstate=1 default_hugepagesz=1G hugepagesz=1G iommu=pt intel_iommu=on mce=off pcie_asmp=off tsc=reliable rhgb quiet skew_tick=1 isolcpus=4-7 intel_pstate=disable nosoftlockup nohz=on nohz_full=4-7 rcu_nocbs=4-7

虚机启动配置

绑定物理CPU

将虚机vcpu绑定到宿主机隔离出来的物理cpu上,本例中将虚机的4个vcpu绑定到CPU 4-7中,其中vcpu 2-3的调度策略是fifo:

*

*

*

*

*

*

*

CPU模式

这边采用host-passthrough模式,直接将物理CPU暴露给虚拟机使用,在虚拟机上完全可以看到的就是物理CPU的型号:

*

*

开启大页

设置虚拟机使用大页:

*

*

*

*

*

*

配置时钟源

禁用kvmclock,默认使用宿主机的tsc时钟源:

*

*

移除所以可能影响延时的设备

建议移除所有的USB设备,virtio串口设备,qga通道设备以及声卡设备。

虚机系统配置

安装系统

同样下载安装BC-Linux7.3系统,并参考宿主机yum源配置开启RT源。

安装依赖

通过yum安装实时内核以及tuned调优配置:

*# yum install kernel-rt

*# yum install tuned tuned-profiles-nfv

tuned配置

配置tuned以隔离在libvirt配置中保留的2个实时CPU 2-3:

*# cat /etc/tuned/realtime-virtual-guest-variables.conf

*isolated_cores=2-3

执行tuned-adm命令使其生效:

*# tuned-adm profile realtime-virtual-guest

*# tuned-adm active

*Current active profile: realtime-virtual-guest

调优内核参数

在grub配置/etc/grub2.cfg对应实时内核linux16行添加如下设定:

default_hugepagesz

=

1G

hugepagesz

=

1G

hugepages

=

12

idle

=

pool mce

=

off tsc

=

reliable

重启虚机并检查配置

分别验证tuned配置,时钟源以及内核调优参数是否已经生效:

*# tuned-adm active

*Current active profile: realtime-virtual-guest

*

*# cat /sys/devices/system/clocksource/clocksource0/current_clocksource

*tsc

*

*# cat /proc/cmdline

*BOOT_IMAGE=/vmlinuz-3.10.0-514.26.1.1.rt56.442.el7.BC-Linux.x86_64 root=/dev/mapper/bel-root ro crashkernel=auto rd.lvm.lv=bel/root rd.lvm.lv=bel/swap mce=off default_hugepagesz=1G hugepagesz=1G hugepages=12 idle=pool tsc=reliable rhgb quiet LANG=en_US.UTF-8 skew_tick=1 isolcpus=2-3 intel_pstate=disable nosoftlockup nohz=on nohz_full=2-3 rcu_nocbs=2-3

实时性测试

首先在虚机内部CPU 2上通过stress命令模拟负载加压:

taskset

-

c

2

stress

--

cpu

4

对于实时性的测试,采用的是cyclictest,该测试工具原理比较简单,它会周期性的执行定时器线程并估算时延,关键流程如下:

首先线程进入while循环,通过clock_gettime获取当前时间T1;

然后执行clock_nanosleep进入睡眠,默认睡眠时间100微秒,本次测试是200微秒;

睡眠时间到期后,线程被唤醒(wakeup),同样通过clock_gettime获取当前时间T2,计算(T2-(T1+200us))就是估算的时延了。

在10分钟内测试下cpu的实时性。具体命令如下:

# taskset -c 2 cyclictest -m -n -q -p95 -D 10m -h60 -i 200 > cyclictest_rt_10min.out

优化前测试结果,平均时延17微秒,最高时延5954微秒:

*# Min Latencies: 00007

*# Avg Latencies: 00017

*# Max Latencies: 05954

*# Histogram Overflows: 02786

*# Histogram Overflow at cycle number:

*# Thread 0: 00036 00308 00525 00741 01007 01225 01524 01765 02003 02304 02548 02845 03088 03328 03626 03843 04140 04381 04679 04923 05164 05466 05708 05919 06159 06403 06705 06948 07246 07491 07790 08035 08279 08578 08821 08857 09119 09358 09602 09726 09830 10064 10069 10294 21226 21273 21315 21368 21416 21466 21511 21556 21599 21646 21701 21742 21793 21839 21928 21972 # 02726 others

*...

优化后,平均时延3微秒,最高时延6微秒:

*# Min Latencies: 00003

*# Avg Latencies: 00003

*# Max Latencies: 00006

*# Histogram Overflows: 00000

*# Histogram Overflow at cycle number:

*# Thread 0:

进一步对比测试12小时cyclictest结果,并利用gnuplot工具画图对比分析,结果如下:

其中红色部分是在调优之后的数据,绿色部分调优之前的数据,可以看出,实时性能调优后的时延最高不超过10微秒,而调优之前时延在10微秒至60微秒的次数远远超过调优之后的,所以优化后的时延性能数据相对比较稳定,满足NFV场景下系统“实时性”需求。

秋季

春种秋收

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180928B1FARL00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券