关于elasticsearch:ps-vs-topCPU占用率统计的两种不同方式

118次阅读

共计 2875 个字符,预计需要花费 8 分钟才能阅读完成。

如何计算 CPU 占用率?

简略来说,过程的 CPU 占用率指的是 CPU 有多少工夫破费在了运行过程上。在 Linux 零碎里,过程运行的工夫是以 jiffies[1] 统计的,通过计算jiffies * HZ,就能够失去过程耗费的 CPU 工夫,再除以 CPU 的总工夫,就能够失去过程的 CPU 占用率:jiffies * HZ / total_time

ps 和 top 的不同之处

pstop 是最罕用的两种查看 CPU 占用的形式,都能够用来疾速找到以后 CPU 占用率高的过程。但实际上这两个工具的统计形式是齐全不同的。

咱们用上面这个简略的 Go 程序来测试这两个工具的差异:

package main

import (
    "bytes"
    "fmt"
    "strconv"
    "sync"
    "time"
)

var testData = []byte(`testdata`)

func testBuffer(idx int) {m := map[string]*bytes.Buffer{}
  for i := 0; i < 100; i += 1 {buf, ok := m[strconv.Itoa(i)]
    if !ok {buf = new(bytes.Buffer)
    }
    for j := 0; j < 1024; j += 1 {buf.Write(testData)
    }
    m[strconv.Itoa(i)] = buf
  }
  fmt.Println("done,", idx)
  wg.Done()}

var wg sync.WaitGroup

func main() {
    for i := 0; i < 10; i += 1 {wg.Add(1)
        j := i
        go testBuffer(j)
    }
    wg.Wait()
    fmt.Println("sleeping")
    time.Sleep(time.Hour)
}

而后咱们运行这个程序,通过 topps aux别离查看过程的 CPU 占用状况。

top -n 1:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
39753 infini    20   0 14.663g 0.014t   1200 S 611.1 22.2   0:23.53 test-cpu

ps aux:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
infini   39881  767 39.1 26505284 25791892 pts/16 Sl+ 07:04   0:38 ./test-cpu

能够看到,pstop 统计的 CPU 占用率是近似的(因为工夫点并不齐全吻合,统计值也会有轻微差异)。两个工具的差别体现在 testBuffer 完结后,top统计的 CPU 占用率曾经靠近于 0,然而 ps 仍然统计到很高的 CPU 占用率:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
infini   39881 82.3 42.4 28638148 27953532 pts/16 Sl+ 07:04   0:40 ./test-cpu

为什么 ps 和 top 的统计值会有差别?

这两个工具的差别来自于各自运行形式的不同:top 只能继续运行一段时间,而 ps 是立即返回的。这个差别体现在运行 top -n 1ps aux时,top是提早后返回的,而 ps 是立即返回的。这两种不同的运行形式就会反映在两个工具的统计算法上。

文章结尾咱们提到,Linux 的 CPU 工夫是依照 jiffies 统计的,思考到效率问题,Linux 只会统计总值,不会记录历史数据。对于 ps 来说,因为只能统计到瞬时值,这个瞬时值的统计算法就必然拿不到实时的 CPU 占用率,因为实时的占用率须要通过 (current_cpu_time - last_cpu_time) / time_duration来失去,ps 只能统计一次,所以 time_duration0,也就无奈计算这个占用率。实际上,ps 统计的是整个过程运行周期内的 CPU 占用率[2]:

(total_cpu_time / total_process_uptime)

对于测试程序这种短时间的占用率回升,刚开始的时候 ps 可能统计到近似精确的均匀 CPU 占用率,然而 cpu 占用复原后,ps 的统计值并不会立即降落,而是会随着过程运行工夫 total_process_uptime 的减少迟缓降落。

top 命令不同,top 是通过继续运行来更新 CPU 占用率统计的。-n 1这个参数指定 top 运行一个迭代后退出,top命令就能够通过这个提早来能够实现一个迭代内的 CPU 占用率统计:

(current_cpu_time - last_cpu_time) / iteration_duration

如何继续监控 CPU 占用率?

通常来说,监控零碎分为采集和统计两个不同的组件,采集组件只会采集指标数值,统计性能通过数据库 /Dashboard 来实现。要监控 CPU 占用率,ps是一个十分合乎采集组件行为的统计形式,每次采集都能够拿到“以后”的 CPU 占用率。然而受限于算法自身的统计形式,咱们理论采集到的是均匀 CPU 占用率,无奈反映过程的实时状态。

以 INFINI Console 为例,咱们运行一个短时间的数据迁徙工作负载,而后查看对应 INFINI 网关实例的 CPU 占用监控(payload.instance.system.cpu,通过 ps 形式统计以后 CPU 占用率)。能够看到,CPU 占用率会以一个曲线回升,在工作完结后会迟缓降落:

如果想继续监控实时 CPU 占用率,咱们就须要借鉴 top 的统计形式,采集原始的过程 CPU 工夫,进而通过聚合数据来计算 CPU 占用率。

在 Linux 零碎下,pstop 命令都会通过 /proc/[PID]/stat 提供的信息来计算 CPU 占用率[2]:

##  Name      Description
14  utime     CPU time spent in user code, measured in jiffies
15  stime     CPU time spent in kernel code, measured in jiffies
16  cutime    CPU time spent in user code, including time from children
17  cstime    CPU time spent in kernel code, including time from children

获取到每个采样工夫的过程信息后,咱们就能够通过这个公式来计算采样周期内的 CPU 占用率:

delta(cpu_time) / delta(timestamp)

在 INFINI Console,咱们能够通过 deriative 函数来计算 payload.instance.system.user_in_mspayload.instance.system.sys_in_ms绝对于 timestamp 的占比,进而失去精确的 CPU 占用率统计。

这样,咱们就能够统计到网关在运行工作负载前后的实时 CPU 占用率:

总结

尽管 topps都能够统计 CPU 占用率,但统计算法却齐全不同。理解这两种算法的底层原理之后,咱们就能够设计出适宜监控零碎的数据采集和数据统计形式,采集到精确的 CPU 占用率。

参考

  1. Jiffies
  2. Top and ps not showing the same cpu result

    本文由博客一文多发平台 OpenWrite 公布!

正文完
 0