跳转至

02-kvm性能优化

02-kvm性能优化

KVM虚拟化-性能优化

用户空间与内核空间

用户空间与内核空间,进程上下文与中断上下文[总结]

http://www.cnblogs.com/Anker/p/3269106.html

我们知道现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操心系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核,保证内核的安全,操心系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。空间分配如下图所示:

img

有了用户空间和内核空间,整个linux内部结构可以分为三部分,从最底层到最上层依次是:硬件→内核空间→用户空间。如下图所示

img

需要注意的细节问题:

(1) 内核空间中存放的是内核代码和数据,而进程的用户空间中存放的是用户程序的代码和数据。不管是内核空间还是用户空间,它们都处于虚拟空间中。

(2) Linux使用两级保护机制:0级供内核使用,3级供用户程序使用。

内核态与用户态:

(1)当一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态(内核态)。此时处理器处于特权级最高的(0级)内核代码中执行。当进程处于内核态时,执行的内核代码会使用当前进程的内核栈。每个进程都有自己的内核栈。

(2)当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。此时处理器在特权级最低的(3级)用户代码中运行。当正在执行用户程序而突然被中断程序中断时,此时用户程序也可以象征性地称为处于进程的内核态。因为中断处理程序将使用当前进程的内核栈。

我在看《linux内核设计与实现》这本书的第三章进程管理时候,看到进程上下文。书中说当一个程序执行了系统调用或者触发某个异常(软中断),此时就会陷入内核空间,内核此时代表进程执行,并处于进程上下文中。看后还是没有弄清楚,什么是进程上下文,如何上google上面狂搜一把,总结如下:

程序在执行过程中通常有用户态和内核态两种状态,CPU对处于内核态根据上下文环境进一步细分,因此有了下面三种状态:

(1)内核态,运行于进程上下文,内核代表进程运行于内核空间。

(2)内核态,运行于中断上下文,内核代表硬件运行于内核空间。

(3)用户态,运行于用户空间。

上下文context: 上下文简单说来就是一个环境。

用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递 很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存 器值、变量等。所谓的“进程上下文”,可以看作是用户进程传递给内核的这些参数以及内核要保存的那一整套的变量和寄存器值和当时的环境等。

相对于进程而言,就是进程执行时的环境。具体来说就是各个变量和数据,包括所有的寄存器变量、进程打开的文件、内存信息等。一个进程的上下文可以分为三个部分:用户级上下文、寄存器上下文以及系统级上下文。

(1)用户级上下文: 正文、数据、用户堆栈以及共享存储区;

(2)寄存器上下文: 通用寄存器、程序寄存器(IP)、处理器状态寄存器(EFLAGS)、栈指针(ESP);

(3)系统级上下文: 进程控制块task_struct、内存管理信息(mm_struct、vm_area_struct、pgd、pte)、内核栈。

当发生进程调度时,进行进程切换就是上下文切换(context switch).操作系统必须对上面提到的全部信息进行切换,新调度的进程才能运行。而系统调用进行的模式切换(mode switch)。模式切换与进程切换比较起来,容易很多,而且节省时间,因为模式切换最主要的任务只是切换进程寄存器上下文的切换。

硬件通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的 一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“ 中断上下文”,其实也可以看作就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)。中断时,内核不代表任何进程运行,它一般只访问系统空间,而不会访问进程空间,内核在中断上下文中执行时一般不会阻塞

cpu的优化

inter的cpu的运行级别,按权限级别高低Ring3->Ring2->Ring1->Ring0,(Ring2和Ring1暂时没什么卵用)Ring3为用户态(用户空间),Ring0为内核态(内核空间)。

img

一:系统进程分为用户态和内核态(上下文切换的问题,Inter已经解决)

[root@linux-node1 ~]# top

%Cpu(s):

0.0 us, #用户态

0.2 sy, #内核态

Ring3的用户态是没有权限管理硬件的,需要切换到内核态Ring0,这样的切换(系统调用)称之为上下文切换,物理机到虚拟机多次的上下文切换,势必会导致性能出现问题。对于全虚拟化,inter实现了技术VT-x,在cpu硬件上实现了加速转换,CentOS7默认是不需要开启的。

img

二:cpu的缓存绑定cpu的优化

[root@chuck ~]# lscpu|grep cache

L1d cache: 32K

L1i cache: 32K

L2 cache: 256K

L3 cache: 3072K

三:L1 L2 L3 三级缓存和CPU绑定

L1是静态缓存,造价高,L2,L3是动态缓存,通过脉冲的方式写入0和1,造价较低。cache解决了cpu处理快,内存处理慢的问题,类似于memcaced和数据库。如果cpu调度器把进程随便调度到其他cpu上,而不是当前L1,L2,L3的缓存cpu上,缓存就不生效了,就会产生miss,为了减少cache miss,需要把KVM进程绑定到固定的cpu上,可以使用taskset把某一个进程绑定(cpu亲和力绑定,可以提高20%的性能)在某一个cpu上,例如:taskset -cp 1 25718(1指的是cpu1,也可以绑定到多个cpu上,25718是指的pid).

cpu绑定的优点:提高性能,20%以上

cpu绑定的缺点:不方便迁移,灵活性差

可以把KVM的进程绑定到执行的CPU上,提高CPU的亲和力

[root@linux-node1 ~]# taskset -cp 0 6573

提示:此项操作,可以提高性能10%,但是灵活性就下降啦

四:KVMCPU优化总结:

1.通过net-VT技术提高CPU的上下文切换

2.使用tasket命令绑定KVM进程到固定的CPU,减少Cache Miss

参考博文:cpu亲和力总结taskset和setcpu及其他相关

http://blog.csdn.net/ttyttytty12/article/details/11726569

内存的优化

内存寻址的过程

一般内存寻址的过程如下:

1.宿主机虚拟内存 -> 宿主机物理内存

2.虚拟机的虚拟内存 -> 虚拟机的物理内存

影子页表

以前VMM通过采用影子列表解决内存转换的问题,影子页表是一种比较成熟的纯软件的内存虚拟化方式,但影子页表固有的局限性,影响了VMM的性能,例如,客户机中有多个CPU,多个虚拟CPU之间同步页面数据将导致影子页表更新次数幅度增加,测试页表将带来异常严重的性能损失。如下图为影子页表的原理图

img

影子页表参考博文:http://tec.5lulu.com/detail/107m8n4e6aaaj8433.html

EPT技术

*在此之际,Inter在最新的Core I7系列处理器上集成了*****EPT技术********(对应AMD的为RVI技术)****,以硬件辅助的方式完成客户物理内存到机器物理内存的转换,完成内存虚拟化,并以有效的方式弥补了影子页表的缺陷,该技术默认是开启的,如下图为EPT技术的原理

img

img

KSM内存合并

宿主机上默认会开启ksmd进程,该进程作为内核中的守护进程存在,它定期执行页面扫描,识别副本页面并合并副本,释放这些页面以供它用,CentOS7默认是开启的

[root@chuck ~]# ps aux|grep ksmd|grep -v grep
root     286  0.0  0.0    0   0 ?     SN  12:32  0:00 [ksmd]

大页内存

大页内存,CentOS7默认开启的

[root@chuck ~]# cat /sys/kernel/mm/transparent_hugepage/enabled 
[always] madvise never      
#这个表示内存的合并,系统会定期扫描内存,并合并为2M的,减少内存碎片
[root@chuck ~]# ps aux |grep khugepage|grep -v grep
root        287  0.2  0.0      0     0 ?        SN   12:32   0:21 [khugepaged]

提示:Linux平台默认的内存页面大小都是4K,HugePage进程会将默认的的每个内存页面可以调整为2M。

内存优化总结

1.宿主机虚拟内存---宿主机物理内存

2.虚拟机的虚拟内存--虚拟机的物理内存

3.宿主机虚拟内存映射到宿主机物理内存

磁盘IO的优化

IO调度算法,也叫电梯算法,详情请看http://www.unixhot.com/article/4

① Noop Scheduler:简单的FIFO队列,最简单的调度算法,由于会产生读IO的阻塞,一般使用在SSD硬盘,此时不需要调度,IO效果非常好

② Anticipatory IO Scheduler(as scheduler)适合大数据顺序顺序存储的文件服务器,如ftp server和web server,不适合数据库环境,DB服务器不要使用这种算法。

③ Deadline Schedler(默认使用的算法):按照截止时间的调度算法,为了防止出现读取被饿死的现象,按照截止时间进行调整,默认的是读期限短于写期限,就不会产生饿死的状况,一般应用在数据库

④ Complete Fair Queueing Schedule(cfq):完全公平的排队的IO调度算法,保证每个进程相对特别公平的使用IO

1.查看本机Centos7默认所支持的调度算法

[root@chuck ~]# dmesg|grep -i "scheduler"
[   11.312549] io scheduler noop registered
[   11.312555] io scheduler deadline registered (default)
[   11.312606] io scheduler cfq registered

2.临时更改某个磁盘的IO调度算法,将deadling模式改为cfq模式

[root@chuck ~]# cat /sys/block/sda/queue/scheduler  #查看当前的IO调度算法
noop [deadline] cfq     #cfq表示完全公平的IO调度模式
[root@chuck ~]# echo cfq >/sys/block/sda/queue/scheduler             
[root@chuck ~]# cat /sys/block/sda/queue/scheduler       
noop deadline [cfq]

3.使更改的IO调度算法永久生效,需要更改内核参数

[root@chuck ~]# vim /boot/grub/menu.lst
kernel /boot/vmlinuz-3.10.0-229.el7 ro root=LABEL=/ elevator=deadline rhgb quiet

Cache的优化

关于write through和write back,默认write through即可

以下为用户写入数据的过程图:

img

Write-back

在这种策略下,当数据被写到raid卡的cache中,控制器就向IO调度器返回了写操作完成信号; 双刃剑,它虽然带来了IO性能的提升,但是随之而来的风险:因为cache是ROM,假设服务器突然断电,则cache中的数据可能丢失; 为了解决这个问题,raid卡加加装一块锂电池(BBU),即当服务器断电时,能把cache中的数据刷到磁盘上;同样的道理,BBU又成为一个风险点,因为锂电池需要保证始终有足够的电量来保证能将cache中的数据写到磁盘上,raid卡会加入一个BBU的管理策略,learn cycle(充放电周期,一般有30/90天,让电池充放电一次,持续约6小时),那么这6小时又称为一个风险点;所以raid卡又会增加一个策略:No WB when bad bbu,即当BBU坏掉,或者BBU正在充放电时,禁用write-back,此时Write policy就会变成:write-through。

img

Write through (默认方式)

只有当数据被写到物理磁盘中,控制器才向IO调度器返回了写操作完成信号; 这种策略以牺牲IO性能,来保证数据安全性,淘宝这边的策略:因为Write-Through的io性能无法满足业务的需求,所以我们这边会采用另一个模式:WB when bad bbu,即不管bbu状态是否正常,我们都会采用write-back,那数据安全怎么办?服务器异常断电的情况,在我们这边概率极低;即便很不幸的我们IDC局部断电了,我们也有主备模式来保证数据的相对安全;我们会监控BBU的状态,一旦发生了BBU failed,我们会将安排停机更换

img

提示:KVM默认使用Write through的方式,安全最高,但是性能最差