【问题标题】:What does "cpu_time" represent exactly in libvirt?“cpu_time”在 libvirt 中究竟代表什么?
【发布时间】:2017-03-20 23:38:15
【问题描述】:

我可以从 libvirt 中提取以下 CPU 值:

virsh domstats vm1 --cpu-total
Domain: 'vm1'
  cpu.time=6173016809079111
  cpu.user=26714880000000
  cpu.system=248540680000000

virsh cpu-stats vm1 --total
Total:
    cpu_time       6173017.263233824 seconds
    user_time        26714.890000000 seconds
    system_time     248540.700000000 seconds

此处的 cpu_time 数字究竟代表什么?

我希望使用此数据以百分比形式计算 CPU 利用率。

谢谢

【问题讨论】:

    标签: virtualization kvm libvirt


    【解决方案1】:

    这是一个非常难以回答的问题!在仔细研究了内核代码一段时间后,我弄清楚了这里发生了什么,并且很高兴了解发生了什么。

    通常对于 Linux 上的进程,总体 CPU 使用率只是用户空间所用时间和内核空间所用时间的总和。天真地认为user_time + system_time 等于cpu_time。我发现,Linux 跟踪 vCPU 线程执行客户代码所花费的时间,与用户空间或内核空间时间分开。

    因此cpu_time == user_time + system_time + guest_time

    因此您可以将system_time + user_time 视为在主机端提供 QEMU / KVM 的开销。 cpu_time - (user_time + system_time) 给出了客户操作系统运行其 CPU 的实际时间。

    要计算 CPU 使用率,您可能只想每 N 秒记录一次cpu_time 并计算两个样本之间的增量。例如usage % = 100 * (cpu_time 2 - cpu_time 1) / N

    【讨论】:

    • 我认为这个答案太棒了!
    • 如果有人在这里查看 libvirt 中 virNodeGetCPUStats 函数给出的 CPU 时间,请确保除以纳秒,因为时间以纳秒为单位。 :)
    【解决方案2】:

    根据 master 从 https://github.com/libvirt/libvirt/ 提取的 2018-07-10 以及就 QEMU/KVM 而言,它归结为:

    • cpu.time = cpuacct.usage cgroup 指标
    • cpu.{user,system} = cpuacct.stat cgroup 指标

    可能遇到的问题是guest load = time load - system load - user load 有时会导致负值 (?!?),例如使用 Debian 9 库存内核 (4.9) 运行 QEMU/KVM 来宾(值是秒):

    time                   system    user     total
    2018-07-10T13:19:20Z 62308.67 9278.59 107968.33
    2018-07-10T13:20:20Z 62316.08 9279.73 107970.73
                   delta     7.41    1.14      2.40 (2.40 < 7.41+1.14 ?!?)
    

    内核错误? (至少有一个人在做类似的实验:https://lkml.org/lkml/2017/11/1/101
    有一件事是肯定的:cpuacct.usagecpuacct.stat 确实使用不同的逻辑来收集他们的指标;这可能解释了差异(?)。

    【讨论】:

      【解决方案3】:

      很遗憾,上述答案在 KVM 来宾的 CPUACCT 控制器中不正确:

      cpu_time == user_time + system_time + guest_time (<-- wrong)
      

      如果您在 VM 中运行 CPU 密集型基准测试与 I/O 或网络密集型基准测试相比,您会发现公式中的“访客时间”不匹配。

      来宾时间(根据 /proc//stat)仅表示 VCPU 用于运行来宾虚拟机的时间(而不是退出或处理 I/O)。

      每个 KVM/libvirt 来宾的 CPUACCT 控制器的顶级父目录包括在“emulator”和“vcpuX”子目录上花费的时间全部,包括在 QEMU 主进程中运行的 vhost 内核线程和非 VCPU pthread,而不仅仅是客户时间或用户/系统时间。

      这使得上面的公式是错误的。正确的公式是:

      guest_time = sum(vcpuX)=>cpu.time - sum(vcpuX)=>(for each child: cpuacct.stat=>user + cpuacct.stat=>system)
      

      您不能简单地使用顶级父文件来计算访客时间。这在任何 I/O 绑定的工作负载下都是完全不准确的。

      【讨论】:

        猜你喜欢
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多