• KVM虚拟机cpu资源限制和vcpu亲缘性绑定


    前言

    KVM中添加的实例存在资源分布不均的情况,这样如果有消耗资源的实例会影响到其他实例的服务正常运行,所以给kvm做资源限制是很有必要的,下面记录一下在centos7中KVM环境下使用cgroup限制vm实例资源的过程。

    安装cgroup

    [root@yufu ~]# yum install libcgroup libcgroup-devel libcgroup-tools-y
    

    启动cgroup服务

    [root@yufu ~]# systemctl start cgconfig
    
    [root@yufu ~]# systemctl enable cgconfig
    

    默认安装后目录文件并没有在/cgroup 目录下,而是在/sys/fs/cgoup 目录下。可以说使用find / -type d -name cgroup查找目录。

    限制cpu资源

    查看当前宿主机上有哪些实例并查看实例的进行号。
    使用ps -ef 指令可以看到每个vm实例的进程号,一个示列在宿主机中就是一个进程。【通过进程名称查看进程号:pidof qemu-kvm

    下面使用进程为 2106 的这个vm实例进测试:

    进程号 2106 对应的实例是vm5,内存4G,cpu为2核心

    在实例vm4中写一个消耗cpu的脚本测试,在宿主机中查看该进程消耗的cpu资源

    #! /bin/bash
    
    x=0
    while [ True ];do
        x=$x+1
    done;
    

    宿主机执行 top -p 2106查看进程状态

    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  4.2 us,  0.0 sy,  0.0 ni, 95.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 98821584 total, 95922736 free,  2029444 used,   869412 buff/cache
    KiB Swap:  8388604 total,  8388604 free,        0 used. 96262080 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
     2106 qemu      20   0 4549900 566812   9336 S 100.0  0.6  11:47.26 qemu-kvm  
    

    可以看到cpu已经使用了100%

    下面用cgroup控制这个进程的cpu资源

    要对vm实例做资源限制,在cgroup目录下创建一个资源组vm5,然后在这个资源组中定义资源分配(可以一个vm定义一个资源组,容易管理,也可以给所有vm定义一个资源组)

    • 创建资源组
    [root@yufu ~]# mkdir /sys/fs/cgroup/cpu/vm5
    
    #资源组创建以后会有很多控制文件
    [root@yufu ~]# ls /sys/fs/cgroup/cpu/vm5
    cgroup.clone_children  cpuacct.stat          cpu.cfs_period_us  cpu.rt_runtime_us  notify_on_release
    cgroup.event_control   cpuacct.usage         cpu.cfs_quota_us   cpu.shares         tasks
    cgroup.procs           cpuacct.usage_percpu  cpu.rt_period_us   cpu.stat
    
    

    查看当前进程

    [root@yufu ~]# pidof qemu-kvm
    2106 1642
    
    • 添加控制进程

    将要限制的进程号加入到/sys/fs/cgroup/cpu/vm5/cgroup.procs

    [root@yufu ~]# echo 2106 > /sys/fs/cgroup/cpu/vm5/cgroup.procs
    
    • 限制cpu资源使用

    cpu.cfs_period_us和cpu.cfs_quota_us来限制该组中的所有进程在单位时间里可以使用的cpu时间。这里的cfs是完全公平调度器的缩写。cpu.cfs_period_us就是时间周期(微秒),默认为100000,即百毫秒。cpu.cfs_quota_us就是在这期间内可使用的cpu时间(微秒),默认-1,即无限制。

    • 查看默认值
    [root@yufu ~]# cat  /sys/fs/cgroup/cpu/vm5/cpu.cfs_period_us 
    100000
    [root@yufu ~]# cat  /sys/fs/cgroup/cpu/vm5/cpu.cfs_quota_us 
    -1
    
    • 对上面的两个值做调整
    [root@yufu ~]# echo 80000 > /sys/fs/cgroup/cpu/vm5/cpu.cfs_period_us 
    [root@yufu ~]# echo 40000 > /sys/fs/cgroup/cpu/vm5/cpu.cfs_quota_us
    
    • 再执行脚本测试
      在vm5上执行测试脚本,宿主机查看top
    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  2.1 us,  0.0 sy,  0.0 ni, 97.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 98821584 total, 95904496 free,  2047560 used,   869528 buff/cache
    KiB Swap:  8388604 total,  8388604 free,        0 used. 96243984 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
     2106 qemu      20   0 4549900 567324   9336 S  50.0  0.6  12:02.15 qemu-kvm                                              
    

    对比发现:长时间高负载下,限制了cpu资源的vm实例负载比没有做限制的实例负载要小。

    同样,其他虚拟机实例按照上面同样的方式也可以对cpu资源进行限制

    撤销资源限制

    要撤销某个资源的限制,将该资源组中的tasks中的pid写到根 cgroup 的 tasks 文件即可,因为每个进程都属于且只属于一个 cgroup,加入到新的 cgroup 后,原有关系也就解除了。要删除一个 cgroup,可以用 rmdir 删除相应目录。不过在删除前,必须先让其中的进程全部退出,对应子系统的资源都已经释放,否则是无法删除的。

    • 撤销资源
    [root@yufu vm5]# echo 2106 > /sys/fs/cgroup/cpu/tasks 
    [root@yufu vm5]# echo 2111 > /sys/fs/cgroup/cpu/tasks 
    [root@yufu vm5]# echo 2112 > /sys/fs/cgroup/cpu/tasks
    
    • 查看原来vm5实例中的pid已经被清空了
    [root@yufu vm5]# cat tasks 
    
    

    再执行脚本测试,cpu又是100%

    Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  4.1 us,  0.0 sy,  0.0 ni, 95.9 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 98821584 total, 95905520 free,  2046364 used,   869704 buff/cache
    KiB Swap:  8388604 total,  8388604 free,        0 used. 96245000 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                               
     2106 qemu      20   0 4549900 567324   9336 S 100.0  0.6  14:29.49 qemu-kvm 
    

    KVM中虚拟机的cpu亲缘性绑定

    默认情况下,kvm虚拟机实例并没有对vcpu做任何限制,当一个实例负载过高时,vcpu会在宿主机的cpu上来回切换,频繁的切换容易造成资源浪费,将vcpu与宿主机cpu对应绑定,能够有效提升cpu工作效率。

    也可以将一个进程绑定在一个cpu上,使用taskset指令

    cpu绑定方式

    上面提到过,一个vm实例在宿主机中其实就是一个进程,绑定方式有两种:

    taskset指令绑定进程cpu

    使用taskset绑定是以vm实例上的所有vcpu为单位,与宿主机上的cpu进行绑定。比如:将vm4实例绑定在第4号cpu上,那么vm4实例中有4个vcpu,这4个vcpu都工作在了宿主机的第4号cpu上了。这种绑定方式粒度比较大

    vcpupin子命令绑定

    virsh vcpupin 子命令是KVM自带的指令工具,它可以把vm实例的每个vcpu与宿主机的cpu对应绑定,这种绑定方式粒度更小。

    下面以vm4实例为例,查看其cpu运行情况和对其进程绑定

    • 查看vm4当前cpu绑定情况:
    [root@yufu ~]# virsh vcpupin vm4
    VCPU: CPU Affinity
    ----------------------------------
       0: 0-23      
       1: 0-23
     #默认2个vcpu没有进行绑定,可以在0-24号cpu上切换
    
    • 查看vcpu使用的时间
    [root@yufu ~]# virsh vcpuinfo vm4
    VCPU:           0
    CPU:            10   #运行在10号cpu上
    State:          running
    CPU time:       14.2s
    CPU Affinity:   yyyyyyyyyyyyyyyyyyyyyyyy
    
    VCPU:           1
    CPU:            8      #运行在8号cpu上
    State:          running
    CPU time:       6.8s
    CPU Affinity:   yyyyyyyyyyyyyyyyyyyyyyyy
    
    
    • 将vm4的两个vcpu绑定在宿主机的第4号和第6号cpu上

    cpu编号从0开始计数

    [root@yufu ~]# virsh vcpupin vm4 0 3
    
    [root@yufu ~]# virsh vcpupin vm4 1 5
    
    • 再看vcpu状态
    [root@yufu ~]# virsh vcpuinfo vm4
    VCPU:           0
    CPU:            3
    State:          running
    CPU time:       14.5s
    CPU Affinity:   ---y--------------------
    
    VCPU:           1
    CPU:            5
    State:          running
    CPU time:       7.3s
    CPU Affinity:   -----y------------------
    
    [root@yufu ~]# virsh vcpupin vm4
    VCPU: CPU Affinity
    ----------------------------------
       0: 3
       1: 5
    

    可以看到cpu已经绑定了,此时在vm4上做压力测试并在宿主机上看看cpu运行情况
    上面使用指令绑定的方式只在当前系统环境有效,实例重启后就会失效,要永久生效需要在xml配置文件中定义

    接着再把vm4的cpu使用资源做cgroup限制就就可以了:

    • 执行ps -ef获得vm4的pid为1636

    • 创建cgroup资源组vm4

    [root@yufu ~]# mkdir /sys/fs/cgroup/cpu/vm4
    
    • 将vm4的pid写进cgroup.procs文件
    [root@yufu ~]# cd /sys/fs/cgroup/cpu/vm4/
    
    [root@yufu vm4]# echo 1636 > cgroup.procs
    #当把进程pid加到 cgroup.procs后,系统会自动将该进程和进程下的线程加入到tasks文件中
    
    [root@yufu vm4]# echo 80000 > cpu.cfs_period_us 
    [root@yufu vm4]# echo 40000 > cpu.cfs_quota_us
    
    • 运行vm4消耗cpu脚本,查看宿主机进程状态和cpu

    可以看到htop中,两个线程的cpu使用率一直在50%左右,且负载一直在第4个第6号cpu运行(这里就不上图了)

    将cpu绑定信息写到xml配置文件

    上面提到过,在命令行做的设置后,vm实例重启后,绑定信息就会失效,要想永久生效,需要将cpu的绑定信息写到该实例的xml配置文件中。

    • 在配置xml配置文件中添加绑定信息

    停止vm4实例,编辑其xml文件

    <domain type='kvm'>
      <name>vm4</name>
      <uuid>a140824a-800b-42bf-ae26-60e9ec6aa50f</uuid>
      <memory unit='KiB'>4097152</memory>
      <currentMemory unit='KiB'>4097152</currentMemory>
      <vcpu placement='static'>2</vcpu>
      #以下为添加内容
      <cputune>    
      <vcpupin vcpu='0' cpuset='3'/>
      <vcpupin vcpu='1' cpuset='5'/>
      </cputune>
    
    • 修改配置文件后要重载xml文件
    [root@yufu qemu]# virsh define /etc/libvirt/qemu/vm4.xml 
    

    再启动实例查看vcpu绑定信息

    [root@yufu qemu]# virsh vcpuinfo vm4
    VCPU:           0
    CPU:            3
    State:          running
    CPU time:       14.2s
    CPU Affinity:   ---y--------------------
    
    VCPU:           1
    CPU:            5
    State:          running
    CPU time:       4.3s
    CPU Affinity:   -----y------------------
    
    [root@yufu qemu]# virsh vcpupin vm4
    VCPU: CPU Affinity
    ----------------------------------
       0: 3
       1: 5
    
    

    关于kvm虚拟机的cpu优化和资源限制暂时记录到这里,后面有时间再对内存和io进行总结

  • 相关阅读:
    ES之2:海量数据处理之倒排索引
    架构-伸缩性
    ES之3:elasticsearch优化收集
    架构-扩展性
    关于静态方法与非静态方法的执行效率
    架构师
    拖库 洗库 撞库
    SOA架构设计经验分享—架构、职责、数据一致性
    mysql索引之五:多列索引
    mysql索引之四:复合索引之最左前缀原理,索引选择性,索引优化策略之前缀索引
  • 原文地址:https://www.cnblogs.com/anay/p/11121708.html
Copyright © 2020-2023  润新知