給大家分享一個(gè)事情。背景是這樣的,我們要測(cè)試某個(gè)第三方 SDK 運(yùn)行性能,這是個(gè) CPU 密集型的服務(wù)。我想評(píng)估一下它運(yùn)行一遍到底有多吃 CPU,以便評(píng)估上線后我們需要部署多少臺(tái)服務(wù)器。
我們是在一臺(tái) 16 物理核的機(jī)器上測(cè)試的,我們的想法是把它啟動(dòng)起來,然后執(zhí)行一遍。用耗時(shí)乘以 16 核那就是總的 CPU 耗時(shí)開銷。不過不巧的是我們發(fā)現(xiàn)這個(gè)貨在并發(fā)上做的并不是特別好,運(yùn)行的前半段里只能打滿一個(gè)核,而后半段可以把整臺(tái)機(jī)器上所有 16 核都打滿。這樣就沒法準(zhǔn)確估算它的 CPU 消耗了。
最先我想到的方案是將這個(gè) SDK 進(jìn)行 numa 綁定。但是 nuam 綁定只能將 cpu 限制在一個(gè) node 上,我的機(jī)器上 一個(gè) node 里有 8 個(gè)核。問題仍然存在,還是不能精確控制 cpu 的用量。
所以我接著又想到了 cgroup 。假如我能從始至終都限制這個(gè) SDK 只使用一個(gè)核,且把一個(gè)核全部打滿,這樣我就能準(zhǔn)確地評(píng)估它的 CPU 耗時(shí)。
說干就干。Cgroup 這玩意兒聽起來復(fù)雜,沒想到用起來那是超級(jí)的簡單。首先我找到了 cpu,cpuacct 這個(gè) group。在它下面創(chuàng)建一個(gè)子 group,一行 mkdir 就能搞定。
# cd /sys/fs/cgroup/cpu,cpuacct
# mkdir test
# cd test
這時(shí)候 cgroup 已經(jīng)在 test 這個(gè)目錄下幫我們創(chuàng)建好了一些文件,通過修改這些文件可以控制進(jìn)程的 CPU 消耗的。
# ls -l
total 0
-rw-r--r-- 1 root root 0 Sep 23 11:38 cgroup.procs
-rw-r--r-- 1 root root 0 Sep 23 11:37 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Sep 23 11:37 cpu.cfs_quota_us
......
為了簡便,我們只關(guān)注上面幾個(gè)文件。其中 cfs_period_us 用來配置時(shí)間周期長度,cfs_quota_us 用來配置當(dāng)前 cgroup 在設(shè)置的周期長度內(nèi)所能使用的 CPU 時(shí)間。這兩個(gè)文件配合起來就可以設(shè)置 CPU 的使用上限。
比如我想控制我的進(jìn)程最多只能使用 1 個(gè)核,那么就這樣。
# echo 500000 > cpu.cfs_quota_us // 500ms
# echo 500000 > cpu.cfs_period_us // 500ms
每 500ms 能使用 500ms的 CPU 時(shí)間,即將 cpu 使用限制在 1 個(gè)核以內(nèi)。(如果想要限制只用兩個(gè)核,那就把 cpu.cfs_quota_us 改成 1000000 即可)
這個(gè)時(shí)候,還缺關(guān)鍵的一步。把要限制的進(jìn)程加進(jìn)來。這個(gè)也簡單,修改 cgroup.procs 把要限制的進(jìn)程 pid 添加進(jìn)去就行了。
這里有個(gè)細(xì)節(jié),那就是加入一個(gè)進(jìn)程后,這個(gè)進(jìn)程創(chuàng)建的子進(jìn)程都將默認(rèn)加到這個(gè) cgroup 的限制中。雖然我們不知道我們將要啟動(dòng)的進(jìn)程的 pid 是多少,但是我們可以查到當(dāng)前 bash 進(jìn)程的 pid,只要把它加進(jìn)來就行了。這樣后面通過控制臺(tái)啟動(dòng)進(jìn)程的時(shí)候,都將自動(dòng)進(jìn)入 cgroup 限制中。
# echo $$
16403
sh -c "echo 16403 > cgroup.procs"
這個(gè)時(shí)候我們使用一個(gè)簡單的工具 ,stress。用它來模擬開篇 sdk 的 cpu 密集型工作。通過 -c 指定開啟幾個(gè)進(jìn)程,然后每個(gè)進(jìn)程都反復(fù)不停的計(jì)算隨機(jī)數(shù)的平方根,盡最大努力消耗 cpu。
# stress -c 4
另外啟動(dòng)一個(gè)控制臺(tái),觀察 cpu 消耗。發(fā)現(xiàn)總量確實(shí)是控制住了。stress 及其子進(jìn)程加起來都只使用了 1 核。
不過我發(fā)現(xiàn)了一個(gè)不滿意的地方。雖然 cpu 用量是控制住了,但是 cpu 消耗是分散在各個(gè) cpu 核上的,而且還是飄來飄去的。我想要的效果是限制它在某一個(gè)核上運(yùn)行。
回來查看了一下 cgroup 目錄下的文件。猛然看到了一個(gè)叫 cpuset 的 group。第六感告訴我,它一定可以!
# ll /sys/fs/cgroup/
total 0
drwxr-xr-x 2 root root 0 Sep 15 17:43 blkio
lrwxrwxrwx 1 root root 11 Sep 15 17:43 cpu -> cpu,cpuacct
lrwxrwxrwx 1 root root 11 Sep 15 17:43 cpuacct -> cpu,cpuacct
drwxr-xr-x 4 root root 0 Sep 15 17:43 cpu,cpuacct
drwxr-xr-x 3 root root 0 Sep 15 17:43 cpuset // 就是它!
......
于是乎,我先是廢棄了剛剛的 test 配置,直接刪除即可(rm -rf /sys/fs/cgroup/cpu,cpuacct)。再我搜了一下這個(gè) cpuset 怎么用,開始新的配置。
# cd /sys/fs/cgroup/cpuset
# mkdir test && cd test
# echo "0" > cpuset.cpus //限制在第 0 號(hào)核上
# echo 0 > cpuset.mems
# echo $$ > cgroup.procs
繼續(xù)開始施加 cpu 壓力。
# stress -c 4
在另外一個(gè)控制臺(tái)上查看效果。
完美!這次不但將 cpu 用量控制在了一個(gè)核,而且也將 CPU 消耗牢牢地釘在了 cpu0 上。這就是我想要的效果!
基于這個(gè)方法,我們就非常準(zhǔn)確地完成了對(duì)那個(gè)第三方 sdk 的 cpu 消耗用量的測(cè)試。也評(píng)估出來未來上線后需要幾臺(tái)服務(wù)器。
文章鏈接:
https://mp.weixin.qq.com/s/Y6qY8TKWu_dezeYs_KTqPA轉(zhuǎn)載自:嵌入式linux
文章來源:開發(fā)內(nèi)功修煉 ,作者張彥飛allen
文章鏈接:一次限制進(jìn)程的 CPU 用量的實(shí)操過程
版權(quán)申明:本文來源于網(wǎng)絡(luò),免費(fèi)傳達(dá)知識(shí),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請(qǐng)聯(lián)系我進(jìn)行刪除。