前言
NFV(网络功能虚拟化)由运营商联盟提出,为了加速部署新的网络服务,运营商倾向于放弃笨重昂贵的专用网络设备,转而使用标准的IT虚拟化技术来拆分网络功能模块。在传统CT网络中对于服务质量保证的要求是非常高的,简而言之就是高带宽,高可靠,低时延。这些要求对于虚拟化技术而言本身就具有非常大的挑战。
在虚拟化场景下,Hypervisor对vcpu本身要进行调度,而在Guest中vcpu对正在运行的程序也需要调度。这种二层调度使得低时延在虚拟化场景下是一个很难解决的问题。而解决低时延很大程度上需要使用实时操作系统
实时性优化思路
实时性就是指能够在规定的时间内已足够快的速度予以处理,这要求操作系统能够及时的响应各种中断事件。并且在调度算法上要求中断处理进程能够得到及时的调度。以此来保证事件的处理。
在虚拟化场景中涉及操作系统有两个。Hypervisor操作系统和Guest操作系统。Hyperviosr操作系统中主要跑vcpu的进程,硬件中断处理程序,以及管理程序等等。为了提高实时性需要修改Hyperviosr调度算法,进程锁,中断屏蔽等机制。
在Guest操作系统中也需要使用实时操作系统来进行优化。同时,为了保证Guest的vcpu在Hypervisor上得到及时的调度,需要在Hyperviosr对vcpu进行隔离,物理cpu和vcpu进行绑定,减少vcpu调度到其他cpu上,保证cache命中率。
实时KVM优化
Hyperviosr侧的优化
首先要将linux修改成实时系统。
PREEMPT_RT
PREEMPT_RT是针对kernel进行修改,使得kernel成为实时操作系统的patch。它主要优化了spinlocks,interrrupts等,减少了不能够相应中断的操作。
相应可以在这里找到
然后调整内核参数,以满足实时性的要求。
cpu隔离/cpu绑定
在kernel启动时候通过isolcups进行cpu隔离,使得Hyperviso上的控制程序跑在其他cpu中,隔离出来的cpu主要给Guest使用。然后在创建虚拟机的时候同时使用cpu绑定技术,将Guest的cpu绑定到被隔离的cpu上。
减少cpu中断
nohzfull提供一种动态的无时钟设置,在内核”CONFIGNOHZFULL=y”的前提下,指定哪些CPU核心可以进入完全无滴答状态。配置了CONFIGNOHZFULL=y后,当cpu上只有一个任务在跑的时候,不发送调度时钟中断到此cpu也就是减少调度时钟中断,不中断空闲CPU,从而可以减少耗电量和减少系统抖动。默认情况下所有的cpu都不会进入这种模式,需要通过nohzfull参数指定那些cpu进入这种模式。
rcunocbs当cpu有RCUcallbacksping的时候,nohzfull设置可能不会生效,使用rcu_nocbs来指定cpu进行卸载RCUcallbackprocessing
mce=off彻底禁用MCE(MachineCheckException)。MCE是用来报告主机硬件相关问题的一种日志机制.
强制cpu进入高性能状态
idle=poll从根本上禁用休眠功能(也就是禁止进入C-states状态)
intelpstate=disable禁用IntelCPU的P-state驱动(CONFIGX86INTELPSTATE),也就是IntelCPU专用的频率调节器驱动P-state表明处理器处于省电模式但仍旧在执行一些工作。
_cstate无视ACPI表报告的值,强制指定CPU的最大C-state值(必须是一个有效值):C0为正常状态,其他则为不同的省电模式(数字越大表示CPU休眠的程度越深/越省电)。
tsc=reliable表示TSC时钟源是绝对稳定的,关闭启动时和运行时的稳定性检查。具体参数见如下设置:
isolcpus=1-4nohzfull=1-4rcunocbs=1-4mce=offidle=pollintel_pstate==1pcieasmp=offtsc=reliable
关闭Hypervisor侧影响性能的程序
关闭内存交换
swapoff-a
关闭ksm
echo0/sys/kernel/mm/ksm/mergeacrossnodes
echo0/sys/kernel/mm/ksm/run
关闭看门狗
echo0/proc/sys/kernel/watchdog
echo0/proc/sys/kernel/nmi_watchdog
调整隔离cpu上的ksoftirqd和rcuc的优先级
禁止带宽限制
echo-1/proc/sys/kernel/schedrtperiodus
echo-1/proc/sys/kernel/schedrtruntimeus
设置中断亲和性将中断都设置到0号cpu上。
forirqin/proc/irq/*;do
echo0${irq}/smpaffinitylist
done
虚拟机的启动设置
将vcpu绑定都内核隔离出来的物理cpu中
cputune
vcpupinvcpu="0"cpuset="1"/
/cputune
禁用kvmclock使用tsc
clockoffset='utc'
timername='kvmclock'present='no'/
/clock
虚拟机内部优化
启动项优化
isolcpus=3nohz_full=3rcu_nocbs=3mce=offidle=poll
虚拟机内部其他优化
swapoff-aecho0/sys/kernel/mm/ksm/merge_across_nodesecho0/sys/kernel/mm/ksm/runecho0/proc/sys/kernel/watchdogecho0/proc/sys/kernel/nmi_watchdogecho-1/proc/sys/kernel/sched_rt_period_usecho-1/proc/sys/kernel/sched_rt_runtime_us
禁止时钟迁移
echo0/proc/sys/kernel/timer_migration
实时性测试
对于实时性的测试,采用的是cyclictest。在10分钟内测试下cpu的实时性。具体命令如下
cyclictest-m-n-p95-h60-i200-D10m
测试结果优化前
/dev/cpu_dma_latencysetto0uspolicy:fifo:loadavg:0.000.010.031/1292407
T:0(2404)P:95I:200C:2999375Min:5Act:22Avg:16Max:1475
优化后
/dev/cpu_dma_latencysetto0uspolicy:fifo:loadavg:0.000.010.011/1522441
T:0(2440)P:95I:200C:2999967Min:6Act:7Avg:7Max:12{%highlight%}
可以看到优化前在实时性方面原始的KVM还是会出现毛刺。在优化后基本上能达到很好的结果。
云技术社区介绍:云技术社区成立于2014年,国内最大的云技术交流平台,分享在云计算/虚拟化项目实施中的资讯、经验和技术,坚持干货。