溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Cgroup限制CPU、IO、內(nèi)存以及l(fā)inux系統(tǒng)中的調(diào)度方法

發(fā)布時(shí)間:2021-07-06 09:07:03 來(lái)源:億速云 閱讀:2030 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要講解了“Cgroup限制CPU、IO、內(nèi)存以及l(fā)inux系統(tǒng)中的調(diào)度方法”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Cgroup限制CPU、IO、內(nèi)存以及l(fā)inux系統(tǒng)中的調(diào)度方法”吧!

一、CPU
1、0核利用
思路: 0核是必須要保護(hù)的,否則各種系統(tǒng)命令、喂狗都可能出問(wèn)題;
       設(shè)想是把某個(gè)實(shí)例,比如SD,綁定到0核,并通過(guò)cgroup功能限制CPU負(fù)載,比如最多使用80%的0核CPU;
問(wèn)題: cgroup被裁掉了,需要安裝; 需要分析和測(cè)試cgroup是否會(huì)影響調(diào)度順序;

2、其它核
思路:其它實(shí)例,綁定到除0核和dpdk核之外的所有核,也就是允許在這些核上遷移,由操作系統(tǒng)調(diào)度;
問(wèn)題:按照以前的經(jīng)驗(yàn),操作系統(tǒng)調(diào)度進(jìn)行核遷移是不會(huì)很快的,在高負(fù)載的時(shí)候容易瞬間CPU沖頂導(dǎo)致呼損;
          
v4用法:
service cgconfig start     #開(kāi)啟cgroups服務(wù)
chkconfig cgconfig on    #開(kāi)啟啟動(dòng)

v5用法
systemctl start  cgconfig.service
systemctl enable cgconfig.service
systemctl is-enable cgconfig.service

v5系統(tǒng)安裝cgroup,安裝libcgroup-0.41-13.el7.x86_64.rpm //v5系統(tǒng)已經(jīng)安裝
                                        libcgroup-devel-0.41-13.el7.x86_64.rpm
                                        libcgroup-tools-0.41-13.el7.x86_64.rpm
                      
https://segmentfault.com/a/1190000008323952

cgroup.procs:只讀文件,顯示當(dāng)前cgroup下的所有進(jìn)程

CFS完全公平調(diào)度策略
cpu.cfs_period_us:用來(lái)配置時(shí)間周期長(zhǎng)度,單位是us,取值范圍1000~1000000:1ms ~ 1s
cpu.cfs_quota_us:用來(lái)配置當(dāng)前cgroup在設(shè)置的周期長(zhǎng)度內(nèi)所能使用的CPU時(shí)間數(shù),單位us,最小值為1000:1ms; t > 1000
tasks中所有任務(wù)總CPU占用率 = cpu.cfs_quota_us/cpu.cfs_period_us
只有這兩個(gè)文件同時(shí)有效,表示cfs限制開(kāi)啟,此時(shí)才能將cfs調(diào)度策略的進(jìn)程寫(xiě)進(jìn)tasks中,否則參數(shù)無(wú)效echo: write error: Invalid argument


RT實(shí)時(shí)調(diào)度策略
cpu.rt_period_us :統(tǒng)計(jì)CPU使用時(shí)間的周期,單位us,最小值為1 ,t > 1
cpu.rt_runtime_us:周期內(nèi)允許任務(wù)使用單個(gè)CPU核的時(shí)間,如果系統(tǒng)中有多個(gè)核,則可以使用核倍數(shù)的時(shí)間,單位us,最小值為0
tasks中所有任務(wù)總CPU占用率 = cpu.rt_runtime_us*CPU核數(shù) / cpu.rt_period_us
只有這兩個(gè)文件同時(shí)有效,表示rt限制開(kāi)啟,此時(shí)才能將rt調(diào)度策略的進(jìn)程寫(xiě)進(jìn)tasks中,

如果同時(shí)配置RT和CFS有效,A(RT類(lèi)型線(xiàn)程總和)、B(CFS類(lèi)型線(xiàn)程總和)兩者分別工作,
對(duì)tasks中的對(duì)應(yīng)的線(xiàn)程屬性進(jìn)行限制
假設(shè)RT和CFS均設(shè)置CPU占用率為80%,那么A、B均占用80%,
兩者加起來(lái)即160%,如果tasks中的線(xiàn)程共核,那么: A + B = 100%
至于A(yíng)、B的具體值,由于A(yíng)為RT調(diào)度優(yōu)先搶占CPU,通常是A=80%,B=20%

兩種調(diào)度策略均通過(guò)配置cgconfig.conf生效

cpu.shares
cpu.stat
notify_on_release
release_agent
tasks


-rw-r--r-- 1 root root 0 Aug 12 17:09 cpu.cfs_period_us
-rw-r--r-- 1 root root 0 Aug 12 17:09 cpu.cfs_quota_us
-rw-r--r-- 1 root root 0 Aug 12 17:09 cpu.rt_period_us
-rw-r--r-- 1 root root 0 Aug 12 17:09 cpu.rt_runtime_us

v4環(huán)境:
service sbcd restart ===不要存在/cgroup/cpu/路徑否則service cgconfig restart失敗導(dǎo)致單板重啟

v5環(huán)境:
當(dāng)系統(tǒng)


遺留問(wèn)題:
1、如何配置cgroup,v5系統(tǒng)設(shè)置開(kāi)機(jī)啟動(dòng),無(wú)法正常啟動(dòng)
答:已經(jīng)解決,修改cgconfig.conf需要重啟單板一次才能生效

2、實(shí)時(shí)調(diào)度的cpu.rt_period_us 、cpu.rt_runtime_us參數(shù)粒度選??;
   粒度太大,直觀(guān)感覺(jué)占用cpu過(guò)大,系統(tǒng)命令響應(yīng)變慢
答:寫(xiě)一個(gè)測(cè)試程序(兩種調(diào)度方式),
    a、觀(guān)察在不同粒度下執(zhí)行相同操作(1w、10w、100w次循環(huán))所需時(shí)間
    b、觀(guān)察程序的調(diào)度次數(shù)
     
4、調(diào)度方式發(fā)生改變
   背景:發(fā)現(xiàn)會(huì)修改SD下線(xiàn)程的調(diào)度方式 5號(hào)(mspe),9號(hào)(mpe)機(jī)均出現(xiàn)
         Q1:sbc中線(xiàn)程的調(diào)度策略,有什么決定
   原因:sd繼承shell進(jìn)程,將任務(wù)默認(rèn)寫(xiě)進(jìn)/sys/fs/cgroup/cpu/user.slice
              user.slice分組中rt=0,導(dǎo)致SD中設(shè)置線(xiàn)程調(diào)度屬性失敗(sched_setscheduler接口返回 -1)
   解決方法:1、裁剪或訂制user.slice、system.slice,經(jīng)試驗(yàn)user.slice.rt + system.slice.rt < 90%可行
                          進(jìn)一步論證:user.slice.rt + system.slice.rt +test.rt < 100
                     2、在代碼中實(shí)現(xiàn),先進(jìn)行寫(xiě)文件設(shè)置,后進(jìn)行調(diào)度屬性設(shè)置,實(shí)驗(yàn)可行

5、通過(guò)配置cgconfig.conf ,/cgconfig.d/test.conf,可以解決調(diào)度策略發(fā)生改變問(wèn)題
   Q1:systemctl restart cgconfig.service 命令失敗


測(cè)試問(wèn)題收尾:

1、實(shí)時(shí)調(diào)度的cpu.rt_period_us 、cpu.rt_runtime_us參數(shù)粒度選?。?br/>    粒度太大,直觀(guān)感覺(jué)占用cpu過(guò)大,系統(tǒng)命令響應(yīng)變慢
解決方案:寫(xiě)一個(gè)測(cè)試程序(cfs調(diào)度,系統(tǒng)命令也cfs調(diào)度方式)
         1、觀(guān)察程序的調(diào)度次數(shù)
sbc占用80%,linux_endless占用20%

粒度小cpu.rt_period_us=100000 cpu.rt_runtime_us=20000        
粒度大cpu.rt_period_us=1000000 cpu.rt_runtime_us=200000

相同時(shí)間:
粒度大sbc調(diào)用次數(shù) > 粒度小sbc調(diào)用次數(shù)
粒度大linux_endless調(diào)用次數(shù) < 粒度小linux_endless調(diào)用次數(shù)

因此,選擇粒度小的cpu參數(shù),要優(yōu)先保證操作系統(tǒng)調(diào)度
#總核數(shù) = 物理CPU個(gè)數(shù) * 每個(gè)物理CPU的核數(shù)
#總邏輯CPU數(shù) = 總核數(shù) * 超線(xiàn)程數(shù)

 #查看物理CPU個(gè)數(shù)
 cat /proc/cpuinfo | grep "physical id" |sort | uniq |wc -l
 
 #查看每個(gè)物理CPU中的core的個(gè)數(shù)
 cat /proc/cpuinfo | grep "cpu cores" | uniq
 
 #查看邏輯CPU個(gè)數(shù)
 cat /proc/cpuinfo | grep "processor" | wc -l
 
 #查看超線(xiàn)程是否打開(kāi)判斷
  cat /proc/cpuinfo | grep "sibling" | uniq ,cat /proc/cpuinfo | grep "cpu cores" | uniq
  如果"siblings"和"cpu cores"一致,則說(shuō)明不支持超線(xiàn)程,或者超線(xiàn)程未打開(kāi);
  如果"siblings"是"cpu cores"的兩倍,則說(shuō)明支持超線(xiàn)程,并且超線(xiàn)程已打開(kāi)

 #查看CPU是32還是64位運(yùn)行模式
  getconf LONG_BIT 
  執(zhí)行結(jié)果:64 
  注意:如果結(jié)果是32,代表是運(yùn)行在32位模式下,但不代表CPU不支持64bit。4.CPU是32還是64位運(yùn)行模式


注意:如果結(jié)果是32,代表是運(yùn)行在32位模式下,但不代表CPU不支持64bit。
 一般情況:邏輯CPU的個(gè)數(shù) = 物理CPU個(gè)數(shù) * 每個(gè)cpu的核數(shù)。如果不相等的話(huà),則表示服務(wù)器的CPU支持超線(xiàn)程技術(shù)

1、物理CPU:實(shí)際Server中插槽上的CPU個(gè)數(shù)
物理cpu數(shù)量,可以數(shù)不重復(fù)的 physical id 有幾個(gè):cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

2、cpu核數(shù):一塊CPU上面能處理數(shù)據(jù)的芯片組的數(shù)量、比如現(xiàn)在的i5 760,是雙核心四線(xiàn)程的CPU、而 i5 2250 是四核心四線(xiàn)程的CPU
   cpu核數(shù)查看方法:cat /proc/cpuinfo | grep "cpu cores" | uniq

3、邏輯CPU:/proc/cpuinfo 這個(gè)文件是用來(lái)存儲(chǔ)cpu硬件信息的(信息內(nèi)容分別列出了processor 0 – n 的規(guī)格。而這里的n是邏輯cpu數(shù)量)
  一個(gè)cpu可以有多核,加上intel的超線(xiàn)程技術(shù)(HT), 可以在邏輯上再分一倍數(shù)量的cpu core出來(lái),所以:
   cat /proc/cpuinfo| grep "processor"| wc -l
   邏輯CPU數(shù)量 = 物理cpu數(shù)量 * cpu cores 這個(gè)規(guī)格值 * 2(如果支持并開(kāi)啟ht)  
   注意:Linux下top查看的CPU也是邏輯CPU個(gè)數(shù)
   

查看每個(gè)邏輯cpu當(dāng)前的占用率 top ,然后按下數(shù)字 1;
top -H -p xxxx //看xxx進(jìn)程下的線(xiàn)程CPU占用率
perf top -Cx // 看具體函數(shù)的在CPUx占用率
綁定進(jìn)程到CPU核上:taskset -cp  cpu_id pid
查看進(jìn)程位于哪個(gè)cpu核上:taskset -p pid
查看進(jìn)程的調(diào)度策略:ps -eo class,cmd 
                      TS  SCHED_OTHER
                      FF  SCHED_FIFO
                      RR  SCHED_RR
                      B   SCHED_BATCH
                      ISO SCHED_ISO
            
            
systemctl list-unit-files | grep enabled //v5系統(tǒng)執(zhí)行服務(wù)命令systemctl
查看掛載cgroup
lssubsys -am

手工掛載cpu
mount -t cgroup -o cpu,cpuacct cpu /cgroup/cpu


[root@localhost cgroup]# systemctl status cgconfig.service
● cgconfig.service - Control Group configuration service
   Loaded: loaded (/usr/lib/systemd/system/cgconfig.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Thu 2018-08-09 10:22:51 UTC; 19min ago
  Process: 4076 ExecStart=/usr/sbin/cgconfigparser -l /etc/cgconfig.conf -L /etc/cgconfig.d -s 1664 (code=exited, status=101)
 Main PID: 4076 (code=exited, status=101)
Aug 09 10:22:51 localhost.localdomain systemd[1]: Starting Control Group configuration service...
Aug 09 10:22:51 localhost.localdomain cgconfigparser[4076]: /usr/sbin/cgconfigparser; error loading /etc/cgconfig.conf: Cgroup mounting failed
Aug 09 10:22:51 localhost.localdomain systemd[1]: cgconfig.service: main process exited, code=exited, status=101/n/a
Aug 09 10:22:51 localhost.localdomain cgconfigparser[4076]: Error: cannot mount cpu,cpuacct to /cgroup/cpu: Device or resource busy
Aug 09 10:22:51 localhost.localdomain systemd[1]: Failed to start Control Group configuration service.
Aug 09 10:22:51 localhost.localdomain systemd[1]: Unit cgconfig.service entered failed state.
Aug 09 10:22:51 localhost.localdomain systemd[1]: cgconfig.service failed.
[root@localhost cgroup]# cgclear


ps -ef | grep sleep  # 找出 sleep 1000 的pid, 這里假設(shè)是 1234
chrt -p 1234         # 可以查看 pid=1234 的進(jìn)程的 調(diào)度策略, 輸入如下:
      pid 1234's current scheduling policy: SCHED_OTHER
      pid 1234's current scheduling priority: 0
chrt -p -f 10 1234   # 修改調(diào)度策略為 SCHED_FIFO, 并且優(yōu)先級(jí)為10
chrt -p 1234         # 再次查看調(diào)度策略
      pid 1234's current scheduling policy: SCHED_FIFO
      pid 1234's current scheduling priority: 10
      
chrt -p -r 10 4572  # 修改調(diào)度策略為 SCHED_RR, 并且優(yōu)先級(jí)為10
chrt -p  4572
pid 4572's current scheduling policy: SCHED_RR
pid 4572 的當(dāng)前調(diào)度優(yōu)先級(jí):10
      
chrt -p -o 0  1234 在修改為SCHED_OTHER      

輸入chrt 列出可選參數(shù)

獲取系統(tǒng)實(shí)時(shí)進(jìn)程調(diào)度配置
sysctl -n kernel.sched_rt_period_us  #實(shí)時(shí)進(jìn)程調(diào)度的單位CPU時(shí)間 1 秒
sysctl -n kernel.sched_rt_runtime_us #實(shí)時(shí)進(jìn)程在 1 秒中實(shí)際占用的CPU時(shí)間, 0.95秒

設(shè)置實(shí)時(shí)進(jìn)程占用CPU時(shí)間

上面的默認(rèn)設(shè)置中, 實(shí)時(shí)進(jìn)程占用 95% 的CPU時(shí)間. 如果覺(jué)得占用的太多或太少, 都是可以調(diào)整的.比如:
sysctl -w kernel.sched_rt_runtime_us=900000    # 設(shè)置實(shí)時(shí)進(jìn)程每1秒中只占0.9秒的CPU時(shí)間
kernel.sched_rt_runtime_us = 900000
sysctl -n kernel.sched_rt_runtime_us 
900000
 
cgroup 中的設(shè)置
整體設(shè)置是針對(duì)整個(gè)系統(tǒng)的, 我們也可以通過(guò) cgroup 來(lái)對(duì)一組進(jìn)程的CPU資源進(jìn)行控制.
如果想在 cgroup 中對(duì) sched_rt_period_us 和 sched_rt_runtime_us 進(jìn)行控制, 需要內(nèi)核編譯選項(xiàng) CONFIG_RT_GROUP_SCHED=y

cat /boot/config-`uname -r`
查看 CONFIG_RT_GROUP_SCHED 是否啟用

/*其他模塊*/

1、blkio模塊、相關(guān)參數(shù)及其含義:

1.1. 權(quán)重比例

blkio.weight
設(shè)定默認(rèn)使用的權(quán)重比例,取值范圍:100—1000。此值會(huì)被blkio.weight_device值覆蓋。
echo 500 > blkio.weight

blkio.weight_device
設(shè)定指定設(shè)備的使用的權(quán)重比例,取值范圍:100—1000。此值會(huì)覆蓋blkio.weight設(shè)定值。該值的格式為:major:minor weight,即,主設(shè)備號(hào):次設(shè)備號(hào) 權(quán)重。例如:設(shè)定硬盤(pán)sda的訪(fǎng)問(wèn)權(quán)重為500.

ps:
# ll /dev/sda
brw-rw---- 1 root disk 8, 0 Aug 15 15:42 /dev/sda
主設(shè)備號(hào)為8,次設(shè)備號(hào)為0.
echo 8:0 500 > blkio.weight_device //測(cè)試發(fā)現(xiàn)此設(shè)備填非0,寫(xiě)失敗

echo 3 > /proc/sys/vm/drop_caches //清文件系統(tǒng)緩存,很重要,否則可能看到io的讀取速率為0

cgexec -g "blkio:test1" dd bs=1M count=4096 if=file1 of=/dev/null

cgexec -g "blkio:test2" dd bs=1M count=4096 if=file2 of=/dev/null //注意:讀取設(shè)備不能相同,否則無(wú)法看見(jiàn)速率差異

1.2. I/O 使用上限

blkio.throttle.read_bps_device / blkio.throttle.write_bps_device
指定 cgroup 中某設(shè)備每秒鐘讀/寫(xiě)數(shù)據(jù)的字節(jié)上限。其格式為 major:minor bytes_per_second。

blkio.throttle.read_iops_device / blkio.throttle.write_iops_device
指定 cgroup 中某設(shè)備每秒鐘可以執(zhí)行的讀/寫(xiě)請(qǐng)求數(shù)上限。其格式為major:minor operations_per_second。

測(cè)試:

1、echo '8:0 1000000' > blkio.throttle.read_bps_device  //設(shè)置分組讀取數(shù)據(jù)為1M/s

2、echo 3 > /proc/sys/vm/drop_caches //清文件系統(tǒng)緩存,很重要

3、dd if=/dev/sda of=/dev/null &

4、iotop -p  cmd2_pid //查看進(jìn)程讀取磁盤(pán)速率

5、將cmd2_pid加入task分組查看速率變化

//C代碼只需要調(diào)用系統(tǒng)接口read讀取磁盤(pán)設(shè)備即可

1.3. 統(tǒng)計(jì)參數(shù)
        blkio.reset_stats:向該文件中寫(xiě)入一個(gè)整數(shù),可以重置該 cgroup 中的統(tǒng)計(jì)計(jì)數(shù)。
        blkio.time          :統(tǒng)計(jì) cgroup 對(duì)具體設(shè)備的 I/O 訪(fǎng)問(wèn)時(shí)間。單位為毫秒(ms)
        blkio.sectors      :統(tǒng)計(jì) cgroup 對(duì)具體設(shè)備的扇區(qū)讀寫(xiě)數(shù)。

blkio.io_serviced:統(tǒng)計(jì) cgroup 對(duì)具體設(shè)備的讀寫(xiě)操作數(shù)。內(nèi)容有四個(gè)字段:major, minor,operation (read, write, sync, or async)和 number(表示操作的次數(shù))。

blkio.io_service_bytes:統(tǒng)計(jì) cgroup對(duì)具體設(shè)備的讀寫(xiě)字節(jié)數(shù)。內(nèi)容有四個(gè)字段:major, minor, operation (read, write, sync, or async)和 bytes(表示傳輸?shù)淖止?jié)數(shù))。

blkio.io_service_time:統(tǒng)計(jì) cgroup 對(duì)指定設(shè)備的 I/O 操作發(fā)送請(qǐng)求和完成請(qǐng)求之間的時(shí)間。條目有四個(gè)字段:major, minor, operation 和 time,其中 time 的單位為納秒(ns)。

blkio.io_wait_time:統(tǒng)計(jì) cgroup 對(duì)具體設(shè)備的 I/O 操作在隊(duì)列調(diào)度中等待的時(shí)間。內(nèi)容有四個(gè)字段:major,minor, operation 和 time,其中 time 的單位為納秒(ns),這意味著對(duì)于ssd硬盤(pán)也是有意義的。

blkio.io_merged:統(tǒng)計(jì) cgroup 將 BIOS 請(qǐng)求合并到 I/O 操作請(qǐng)求的次數(shù)。內(nèi)容有兩個(gè)字段:number和 operation。

blkio.io_queued:統(tǒng)計(jì)I/O 操作排隊(duì)的請(qǐng)求數(shù)。內(nèi)容有兩個(gè)字段:number 和 operation(read, write, sync, or async)。

blkio.throttle.io_serviced:統(tǒng)計(jì) cgroup 對(duì)具體設(shè)備的讀寫(xiě)操作數(shù)。blkio.io_serviced 與blkio.throttle.io_serviced的不同之處在于,CFQ 調(diào)度請(qǐng)求隊(duì)列時(shí),前者不會(huì)更新。
內(nèi)容有四個(gè)字段:(read, write, sync, or async)和 number(表示操作的次數(shù))。

blkio.throttle.io_service_bytes:統(tǒng)計(jì) cgroup對(duì)具體設(shè)備的讀寫(xiě)字節(jié)數(shù)。blkio.io_service_bytes 與blkio.throttle.io_service_bytes 的不同之處在于,CFQ 調(diào)度請(qǐng)求隊(duì)列時(shí),前者不會(huì)更新。內(nèi)容有四個(gè)字段:(read, write, sync, or async)和 bytes(表示傳輸?shù)淖止?jié)數(shù))。

2、memory模塊、相關(guān)參數(shù)及其含義:
 2.1、參數(shù)概要:
cgroup.event_control #用于eventfd的接口
memory.usage_in_bytes #顯示當(dāng)前已用的內(nèi)存
memory.limit_in_bytes #設(shè)置/顯示當(dāng)前限制的內(nèi)存額度
memory.failcnt #顯示內(nèi)存使用量達(dá)到限制值的次數(shù)
memory.max_usage_in_bytes #歷史內(nèi)存最大使用量
memory.soft_limit_in_bytes #設(shè)置/顯示當(dāng)前限制的內(nèi)存軟額度
memory.stat #顯示當(dāng)前cgroup的內(nèi)存使用情況
memory.use_hierarchy #設(shè)置/顯示是否將子cgroup的內(nèi)存使用情況統(tǒng)計(jì)到當(dāng)前cgroup里面
memory.force_empty #觸發(fā)系統(tǒng)立即盡可能的回收當(dāng)前cgroup中可以回收的內(nèi)存
memory.pressure_level #設(shè)置內(nèi)存壓力的通知事件,配合cgroup.event_control一起使用
memory.swappiness #設(shè)置和顯示當(dāng)前的swappiness
memory.move_charge_at_immigrate #設(shè)置當(dāng)進(jìn)程移動(dòng)到其他cgroup中時(shí),它所占用的內(nèi)存是否也隨著移動(dòng)過(guò)去
memory.oom_control #設(shè)置/顯示oom controls相關(guān)的配置
memory.numa_stat #顯示numa相關(guān)的內(nèi)存

2.2、屬性限制

memory.force_empty :當(dāng)向memory.force_empty文件寫(xiě)入0時(shí)(echo 0 > memory.force_empty),將會(huì)立即觸發(fā)系統(tǒng)盡可能的回收該cgroup占用的內(nèi)存。該功能主要使用場(chǎng)景是移除cgroup前(cgroup中沒(méi)有進(jìn)程),先執(zhí)行該命令,可以盡可能的回收該cgropu占用的內(nèi)存,這樣遷移內(nèi)存的占用數(shù)據(jù)到父cgroup或者root cgroup時(shí)會(huì)快些。

memory.swappiness :該文件的值默認(rèn)和全局的swappiness(/proc/sys/vm/swappiness)一樣,修改該文件只對(duì)當(dāng)前cgroup生效,其功能和全局的swappiness一樣

有一點(diǎn)和全局的swappiness不同,那就是如果這個(gè)文件被設(shè)置成0,就算系統(tǒng)配置的有交換空間,當(dāng)前cgroup也不會(huì)使用交換空間。

memory.use_hierarchy:該文件內(nèi)容為0時(shí),表示不使用繼承,即父子cgroup之間沒(méi)有關(guān)系;當(dāng)該文件內(nèi)容為1時(shí),子cgroup所占用的內(nèi)存會(huì)統(tǒng)計(jì)到所有祖先cgroup中。

如果該文件內(nèi)容為1,當(dāng)一個(gè)cgroup內(nèi)存吃緊時(shí),會(huì)觸發(fā)系統(tǒng)回收它以及它所有子孫cgroup的內(nèi)存。
注意: 當(dāng)該cgroup下面有子cgroup或者父cgroup已經(jīng)將該文件設(shè)置成了1,那么當(dāng)前cgroup中的該文件就不能被修改。

memory.soft_limit_in_bytes:有了hard limit(memory.limit_in_bytes),為什么還要soft limit呢?hard limit是一個(gè)硬性標(biāo)準(zhǔn),絕對(duì)不能超過(guò)這個(gè)值,而soft limit可以被超越,既然能被超越,要這個(gè)配置還有啥用?先看看它的特點(diǎn)當(dāng)系統(tǒng)內(nèi)存充裕時(shí),soft limit不起任何作用當(dāng)系統(tǒng)內(nèi)存吃緊時(shí),系統(tǒng)會(huì)盡量的將cgroup的內(nèi)存限制在soft limit值之下(內(nèi)核會(huì)盡量,但不100%保證)

從它的特點(diǎn)可以看出,它的作用主要發(fā)生在系統(tǒng)內(nèi)存吃緊時(shí),如果沒(méi)有soft limit,那么所有的cgroup一起競(jìng)爭(zhēng)內(nèi)存資源,占用內(nèi)存多的cgroup不會(huì)讓著內(nèi)存占用少的cgroup,這樣就會(huì)出現(xiàn)某些cgroup內(nèi)存饑餓的情況。如果配置了soft limit,那么當(dāng)系統(tǒng)內(nèi)存吃緊時(shí),系統(tǒng)會(huì)讓超過(guò)soft limit的cgroup釋放出超過(guò)soft limit的那部分內(nèi)存(有可能更多),這樣其它c(diǎn)group就有了更多的機(jī)會(huì)分配到內(nèi)存。所以,這其實(shí)是系統(tǒng)內(nèi)存不足時(shí)的一種妥協(xié)機(jī)制,給次等重要的進(jìn)程設(shè)置soft limit,當(dāng)系統(tǒng)內(nèi)存吃緊時(shí),把機(jī)會(huì)讓給其它重要的進(jìn)程。

注意: 當(dāng)系統(tǒng)內(nèi)存吃緊且cgroup達(dá)到soft limit時(shí),系統(tǒng)為了把當(dāng)前cgroup的內(nèi)存使用量控制在soft limit下,在收到當(dāng)前cgroup新的內(nèi)存分配請(qǐng)求時(shí),就會(huì)觸發(fā)回收內(nèi)存操作,所以一旦到達(dá)這個(gè)狀態(tài),就會(huì)頻繁的觸發(fā)對(duì)當(dāng)前cgroup的內(nèi)存回收操作,會(huì)嚴(yán)重影響當(dāng)前cgroup的性能。

memory.oom_control:內(nèi)存超限之后的 oom 行為控制。

        查看oom killer設(shè)置,不能用vi編輯,只能用echo,但是根路徑下的memory.oom_control無(wú)法設(shè)置

[root@localhost test]# echo 1 > memory.oom_control
[root@localhost test]# cat memory.oom_control
oom_kill_disable 1
under_oom 0 //只讀字段


 
       關(guān)閉oom killer:

設(shè)置 oom_kill_disable 為 1。(0 為開(kāi)啟)當(dāng)觸發(fā)oom時(shí),但是開(kāi)關(guān)關(guān)閉時(shí),對(duì)應(yīng)的線(xiàn)程仍然無(wú)法調(diào)度,出現(xiàn)D狀態(tài)

cgroup.event_control:實(shí)現(xiàn)OOM的通知,當(dāng)OOM發(fā)生時(shí),可以收到相關(guān)的事件

 memory.move_charge_at_immigrate:當(dāng)一個(gè)進(jìn)程從一個(gè)cgroup移動(dòng)到另一個(gè)cgroup時(shí),默認(rèn)情況下,該進(jìn)程已經(jīng)占用的內(nèi)存還是統(tǒng)計(jì)在原來(lái)的cgroup里面,不會(huì)占用新cgroup的配額,但新分配的內(nèi)存會(huì)統(tǒng)計(jì)到新的cgroup中(包括swap out到交換空間后再swap in到物理內(nèi)存中的部分)。我們可以通過(guò)設(shè)置memory.move_charge_at_immigrate讓進(jìn)程所占用的內(nèi)存隨著進(jìn)程的遷移一起遷移到新的cgroup中。

方法:

enable: echo 1 > memory.move_charge_at_immigrate

disable:echo 0 > memory.move_charge_at_immigrate
注意: a、就算設(shè)置為1,但如果不是thread group的leader,這個(gè)task占用的內(nèi)存也不能被遷移過(guò)去。換句話(huà)說(shuō),如果以線(xiàn)程為單位進(jìn)行遷移,必須是進(jìn)程的第一個(gè)線(xiàn)程,如果以進(jìn)程為單位進(jìn)行                  遷移,就沒(méi)有這個(gè)問(wèn)題。
               當(dāng)memory.move_charge_at_immigrate為0時(shí),就算當(dāng)前cgroup中里面的進(jìn)程都已經(jīng)移動(dòng)到其它c(diǎn)gropu中去了,由于進(jìn)程已經(jīng)占用的內(nèi)存沒(méi)有被統(tǒng)計(jì)過(guò)去,當(dāng)前cgroup有可能還占用很                多內(nèi)存,當(dāng)移除該cgroup時(shí),占用的內(nèi)存需要統(tǒng)計(jì)到誰(shuí)頭上呢?答案是依賴(lài)memory.use_hierarchy的值,如果該值為0,將會(huì)統(tǒng)計(jì)到root cgroup里;如果值為1,將統(tǒng)計(jì)到它的父cgroup               里面。

b、當(dāng)前進(jìn)程分組時(shí),如果進(jìn)程使用的內(nèi)存(memory.usage_in_bytes)大于目標(biāo)分組的內(nèi)存限制(memory.limit_in_bytes),則遷移失敗

[root@localhost memory]# echo 5750 > test_1/tasks
[root@localhost memory]# cat test_1/memory.usage_in_bytes
106496
[root@localhost memory]# cat test_2/memory.usage_in_bytes
0
[root@localhost memory]# cd test_2
[root@localhost test_2]# cat memory.limit_in_bytes
9223372036854771712
[root@localhost test_2]# echo 10240 > memory.limit_in_bytes
[root@localhost test_2]# echo 5750 > tasks
-bash: echo: 寫(xiě)錯(cuò)誤: 無(wú)法分配內(nèi)存
[root@localhost test_2]# echo 1024000 > memory.limit_in_bytes
[root@localhost test_2]# echo 5750 > tasks
[root@localhost test_2]# cat memory.usage_in_bytes
106496

c、當(dāng)進(jìn)程正在申請(qǐng)內(nèi)存時(shí),遷移分組,已經(jīng)申請(qǐng)內(nèi)存統(tǒng)計(jì)不會(huì)遷移

2.3、內(nèi)存限制

memory.memsw.limit_in_bytes:內(nèi)存+swap空間使用的總量限制。
memory.limit_in_bytes:內(nèi)存使用量限制。

memory.memsw.limit_in_bytes 必須大于或等于 memory.limit_in_byte。
要解除內(nèi)存限制,把對(duì)應(yīng)的值設(shè)為 -1 即可。

這種方式限制進(jìn)程內(nèi)存占用會(huì)有個(gè)風(fēng)險(xiǎn)。當(dāng)進(jìn)程試圖占用的內(nèi)存超過(guò)限制時(shí),會(huì)觸發(fā) oom ,導(dǎo)致進(jìn)程直接被殺,從而造成可用性問(wèn)題。即使關(guān)閉控制組的 oom killer,在內(nèi)存不足時(shí),進(jìn)程雖然不會(huì)被殺,但是會(huì)長(zhǎng)時(shí)間進(jìn)入 D 狀態(tài)(等待系統(tǒng)調(diào)用的不可中斷休眠),并被放到 OOM-waitqueue 等待隊(duì)列中, 仍然導(dǎo)致服務(wù)不可用。因此,用 memory.limit_in_bytes 或 memory.memsw.limit_in_bytes 限制進(jìn)程內(nèi)存占用僅應(yīng)當(dāng)作為一個(gè)保險(xiǎn),避免在進(jìn)程異常時(shí)耗盡系統(tǒng)資源。如,預(yù)期一組進(jìn)程最多會(huì)消耗 1G 內(nèi)存,那么可以設(shè)置為 1.5G 。這樣在發(fā)生內(nèi)存泄露等異常情況時(shí),可以避免造成更嚴(yán)重問(wèn)題。

注意:如果當(dāng)前分組下已經(jīng)存在task任務(wù),修改memory.limit_in_bytes的值必須大于memory.usage_in_bytes的值,否則修改失敗

[root@localhost test_2]# cat memory.usage_in_bytes
106496
[root@localhost test_2]# echo 106494 > memory.limit_in_bytes
-bash: echo: 寫(xiě)錯(cuò)誤: 設(shè)備或資源忙
[root@localhost test_2]# echo 106498 > memory.limit_in_bytes
[root@localhost test_2]# cat memory.limit_in_bytes
106496 //數(shù)值不一定精確寫(xiě)入
[root@localhost test_2]#

2.4、內(nèi)存資源審計(jì)

memory.memsw.usage_in_bytes:當(dāng)前 cgroup 的內(nèi)存+ swap 的使用量。

memory.usage_in_bytes:當(dāng)前 cgroup 的內(nèi)存使用量。

memory.max_usage_in_bytes:cgroup 最大的內(nèi)存+ swap 的使用量。

memory.memsw.max_usage_in_bytes:cgroup 的最大內(nèi)存使用量。

感謝各位的閱讀,以上就是“Cgroup限制CPU、IO、內(nèi)存以及l(fā)inux系統(tǒng)中的調(diào)度方法”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Cgroup限制CPU、IO、內(nèi)存以及l(fā)inux系統(tǒng)中的調(diào)度方法這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI