จำกัดการใช้งาน CPU และหน่วยความจำของคำสั่งด้วย cgroups ใน Ubuntu

หากคำสั่งใดคำสั่งหนึ่งทำให้เดสก์ท็อป Ubuntu ของคุณทำงานช้าลง หรือทำให้เซิร์ฟเวอร์มีหน่วยความจำไม่เพียงพอ ให้ใส่คำสั่งนั้นและกระบวนการย่อยของมันไว้ใน cgroup ที่จัดการโดย systemd โดยกำหนดโควต้า CPU และขีดจำกัดหน่วยความจำ ใน Ubuntu เวอร์ชันปัจจุบันsystemd-run --scopeวิธีนี้เป็นวิธีที่รวดเร็วและได้ผลที่สุด: มันจะเริ่มต้นคำสั่งในขอบเขตชั่วคราว และ systemd จะใช้ข้อจำกัดผ่านการควบคุม cgroup

ตัวอย่างด้านล่างจำกัดปริมาณงานไว้ที่ครึ่งหนึ่งของความจุ CPU หนึ่งตัวและหน่วยความจำ 1 GiB นี่คือข้อจำกัดสำหรับขอบเขตทั้งหมด รวมถึงกระบวนการย่อยด้วย ไม่ใช่การรับประกันว่าโปรแกรมจะทำงานด้วยความเร็วที่แน่นอน

เหตุใดกระบวนการจึงต้องการการจำกัด cgroup

กระบวนการที่ทำงานหนักอาจแย่งทรัพยากรจากแอปพลิเคชันแบบโต้ตอบ ในขณะที่กระบวนการที่ใช้หน่วยความจำมากอาจทำให้เครื่องเข้าสู่โหมดเรียกคืนหน่วยความจำหรือสภาวะหน่วยความจำไม่เพียงพอ cgroup จะจัดกลุ่มกระบวนการกับกระบวนการย่อยของมัน เพื่อให้เคอร์เนลสามารถจัดการและจำกัดกลุ่มนั้นได้ systemd ของ Ubuntu มีอินเทอร์เฟซที่สะดวกสำหรับการควบคุมเหล่านี้

การตั้งค่า CPU และหน่วยความจำทำงานแตกต่างกันCPUQuota=50%จำกัดเวลาการใช้งาน CPU ไว้ที่ครึ่งหนึ่งของความจุของ CPU หนึ่งตัว โดยเฉลี่ยตลอดช่วงเวลาการจัดกำหนดการ ค่านี้200%แสดงถึงเวลาการใช้งาน CPU สูงสุดสองตัวเมื่อมีให้ใช้งาน นี่คือขีดจำกัดสูงสุด ไม่ใช่ลำดับความสำคัญของ CPU หรือการสำรองMemoryMax=1Gกำหนดขีดจำกัดสูงสุดสำหรับหน่วยความจำที่ถูกเรียกเก็บจาก cgroup หากภาระงานไม่สามารถอยู่ต่ำกว่าขีดจำกัดนี้ได้ เคอร์เนลอาจเรียกคืนหน่วยความจำหรือเรียกใช้คำสั่งยุติการทำงานเนื่องจากหน่วยความจำไม่เพียงพอสำหรับกระบวนการใน cgroup นั้น เลือกขีดจำกัดที่มีพื้นที่เหลือสำหรับแอปพลิเคชันและกระบวนการย่อย

1. ตรวจสอบว่า Ubuntu ใช้ cgroup เวอร์ชัน 2

ระบบ Ubuntu ที่ใช้ systemd มักใช้โครงสร้างลำดับชั้น cgroup v2 แบบรวมศูนย์ โปรดตรวจสอบการตั้งค่าที่ใช้งานอยู่ก่อนที่จะนำเส้นทางที่แสดงต่อไปนี้ไปใช้:

stat -fc %T /sys/fs/cgroup
systemctl --version | head -n 1

คำสั่งแรกควรรายงานค่าcgroup2fs. หากรายงานประเภทระบบไฟล์อื่น บทความนี้จะไม่รองรับเส้นทางไฟล์ cgroup v2 ที่เขียนไว้ คุณสมบัติของ systemd อาจยังคงรองรับได้ในลำดับชั้นที่แตกต่างกัน แต่ให้ใช้เอกสารประกอบการแจกจ่ายที่ตรงกันแทนการคัดลอกเส้นทาง v2

นอกจากนี้ ให้ตรวจสอบเวอร์ชัน systemd ที่แน่นอนด้วย หากคุณสมบัติใดถูกปฏิเสธ เอกสาร Noble ของ Ubuntu อธิบายถึงCPUQuota=และMemoryMax=เป็นการตั้งค่าการควบคุมทรัพยากร เวอร์ชัน Ubuntu เก่าๆ อาจมี systemd เวอร์ชันที่แตกต่างกัน

2. เริ่มการทำงานภายในขอบเขตที่จำกัด

เรียกใช้โปรแกรมผ่าน โดยsystemd-runแทนที่ไฟล์ปฏิบัติการจริงและอาร์กิวเมนต์ สำหรับคำสั่งในไดเร็กทอรีปัจจุบัน ให้ใช้./และส่งอาร์กิวเมนต์ทั้งหมดต่อท้าย--:

systemd-run --scope \
  -p CPUQuota=50% \
  -p MemoryMax=1G \
  -- ./my-program --input data.csv
เปิดเทอร์มินัล Ubuntu แล้วรัน systemd-run โดยตั้งค่า CPUQuota ไว้ที่ 50 เปอร์เซ็นต์ และ MemoryMax ไว้ที่ 1G เพื่อป้อนคำสั่ง
เรียกใช้คำสั่งภายในขอบเขต systemd ชั่วคราวโดยกำหนดข้อจำกัดด้าน CPU และหน่วยความจำ

สำหรับคำสั่งที่ผู้ใช้เป็นเจ้าของ ให้ลองใช้คำสั่งนี้โดยไม่ต้องsudoมีสิทธิ์ root ก่อน หาก systemd รายงานว่าตัวควบคุมหรือคุณสมบัติที่ร้องขอไม่พร้อมใช้งาน ผู้จัดการระบบของผู้ใช้อาจไม่มีสิทธิ์ในการมอบหมายสิทธิ์นั้น การลองใหม่ในฐานะ root อาจเหมาะสมสำหรับงานที่ครอบคลุมทั้งระบบ แต่จะเปลี่ยนบริบทด้านความปลอดภัยของคำสั่ง อย่าเรียกใช้โปรแกรมที่ไม่น่าเชื่อถือในฐานะ root โดยไม่คิด หากจำเป็นต้องใช้ผู้จัดการระบบในฐานะ root ให้ใช้sudo systemd-run --scope ...หลังจากพิจารณาการเปลี่ยนแปลงนั้นแล้วเท่านั้น

เทอร์มินัลจะยังคงเชื่อมต่อกับขอบเขตการทำงานขณะที่คำสั่งกำลังทำงาน การกดปุ่มCtrl+Cจะขัดจังหวะการทำงานเบื้องหน้า ขอบเขตการทำงานนี้เป็นแบบชั่วคราวและโดยปกติจะหายไปหลังจากกระบวนการสิ้นสุดลง เป็นวิธีที่สะดวกในการเริ่มต้นคำสั่งภายใต้ข้อจำกัด แทนที่จะใช้เป็นนโยบายถาวรสำหรับการเรียกใช้งานในอนาคต

3. ค้นหาขอบเขตและตรวจสอบข้อจำกัดของขอบเขตนั้น

systemd-runแสดงชื่อหน่วยที่สร้างขึ้น โดยทั่วไปจะเป็นชื่อประมาณนี้run-….scopeขณะที่คำสั่งยังทำงานอยู่ ให้แสดงรายการโครงสร้าง cgroup:

systemd-cgls

ค้นหาขอบเขตชั่วคราวและยืนยันว่าโปรแกรมเป้าหมายและโปรแกรมย่อยปรากฏอยู่ภายใต้ขอบเขตนั้น เรื่องนี้สำคัญเพราะโปรแกรมย่อยที่ทำงานอยู่นอกขอบเขตจะไม่ได้รับการครอบคลุมโดยเพดาน cgroup เดียวกัน

แผนผัง cgroup ของเทอร์มินัลแสดงขอบเขตการทำงานชั่วคราวซึ่งประกอบด้วยโปรแกรมหนึ่งโปรแกรมและกระบวนการทำงานสองตัว
ใช้โครงสร้าง cgroup เพื่อตรวจสอบว่าโปรแกรมและเวิร์กเกอร์ของโปรแกรมนั้นถูกจัดกลุ่มอยู่ภายใต้ขอบเขตชั่วคราว (transient scope) หรือไม่

ใช้ชื่อขอบเขตที่พิมพ์ออกมาในคำสั่งถัดไป แทนที่run-abc.scopeด้วยชื่อจริง:

systemctl show run-abc.scope \
  -p ControlGroup -p CPUQuotaPerSecUSec -p MemoryMax

CPUQuotaPerSecUSec=50000สอดคล้องกับโควต้า 50% เมื่อระยะเวลาโควต้าของ systemd คือ 100 มิลลิวินาที; MemoryMax=1073741824เท่ากับ 1 กิกะไบต์ในหน่วยไบต์ ค่าแบบเรียลไทม์มีประโยชน์มากกว่าการสมมติว่าทุกโฮสต์จะยอมรับทุกคำขอโดยไม่เปลี่ยนแปลง เนื่องจาก cgroup หลักและคอนโทรลเลอร์ที่มีอยู่สามารถจำกัดผลลัพธ์ที่แท้จริงได้

คำสั่ง `systemctl show` แสดงผลลัพธ์พร้อมค่า ControlGroup, โควต้า CPU และค่าสูงสุดของหน่วยความจำสำหรับขอบเขตชั่วคราว (transient scope)
ตรวจสอบกลุ่มควบคุมที่รายงานโดยขอบเขต และขีดจำกัด CPU และหน่วยความจำที่กำหนดค่าไว้

4. ตรวจสอบไฟล์ cgroup ของเคอร์เนลและปรับแต่งอย่างปลอดภัย

คุณสมบัติ นี้ControlGroupระบุพาธของ cgroup ที่สัมพันธ์กับ/sys/fs/cgroup. เก็บค่านี้ไว้ในตัวแปรเชลล์ เพื่อให้คำสั่งต่างๆ ใช้พาธที่กำหนดไว้จริงบนเครื่องของคุณ:

UNIT=run-abc.scope
CG=$(systemctl show "$UNIT" -p ControlGroup --value)
printf 'Group: %s\n' "$CG"
cat "/sys/fs/cgroup$CG/cpu.max"
cat "/sys/fs/cgroup$CG/memory.max"

ใน cgroup v2 cpu.maxจะมีโควต้าและช่วงเวลาเป็นไมโครวินาที ตัวอย่างเช่น50000 100000หมายถึงเวลาใช้งาน CPU 50 มิลลิวินาทีในแต่ละช่วงเวลา 100 มิลลิวินาทีmemory.maxแสดงขีดจำกัดหน่วยความจำเป็นไบต์ หากไฟล์หายไป ให้ตรวจสอบว่าขอบเขตยังคงทำงานอยู่และเคอร์เนลกำลังใช้ cgroup v2

เทอร์มินัลอ่านค่า cpu.max และ memory.max จากขอบเขต systemd ภายใต้ sysfs cgroup v2
อ่านไฟล์ cgroup v2 ของเคอร์เนลเพื่อตรวจสอบโควต้าและขีดจำกัดหน่วยความจำที่กำหนดค่าไว้

หากคุณเริ่มต้นใช้งานหน่วยการทำงานระยะยาวที่มีชื่อ และต้องการปรับขีดจำกัดของมัน systemd รองรับการเปลี่ยนแปลงคุณสมบัติของทรัพยากรบนหน่วยการทำงานที่กำลังทำงานอยู่ ตัวอย่างเช่นsudo systemctl set-property --runtime my-worker.service CPUQuota=50% MemoryMax=1Gการดำเนินการนี้จะมีผลกับ cgroup ของบริการนั้น และต้องมีสิทธิ์ที่เหมาะสม มันจะไม่แนบกระบวนการที่กำลังทำงานอยู่แล้วโดยพลการเพียงเพราะทราบ PID ของมัน สำหรับกระบวนการที่ทำงานเพียงครั้งเดียว ให้หยุดกระบวนการนั้นอย่างถูกต้องและเริ่มต้นใหม่ผ่านขอบเขตที่จำกัด สำหรับบริการที่ทำงานอย่างต่อเนื่อง ให้กำหนดค่าคุณสมบัติในหน่วยบริการหรือ systemd drop-in และเริ่มต้นใหม่ในระหว่างช่วงเวลาการบำรุงรักษาที่เหมาะสม

ตรวจสอบผลลัพธ์

รักษาการทำงานของเวิร์กโหลดให้ต่อเนื่องในขณะที่คุณตรวจสอบ ยืนยันว่าsystemd-cglsกระบวนการและกระบวนการย่อยอยู่ภายใต้ขอบเขตที่ต้องการsystemctl showรายงานคุณสมบัติที่ร้องขอ และไฟล์ที่เกี่ยวข้องcpu.maxมีmemory.maxอยู่จริงพร้อมค่าที่แน่นอน เมื่อกระบวนการสิ้นสุดลง ขอบเขตชั่วคราวจะถูกลบออก ดังนั้นไฟล์ cgroup อาจหายไป

โควต้าจำกัดเวลาการใช้งาน CPU แต่ไม่รับประกันเปอร์เซ็นต์คงที่บนหน้าจอมอนิเตอร์เดสก์ท็อป และการจำกัดหน่วยความจำอย่างเข้มงวดอาจทำให้เกิดความล้มเหลวหากแอปพลิเคชันต้องการมากกว่าขีดจำกัด หากภาระงานไม่เสถียร ให้หยุดการทำงานและเพิ่มขีดจำกัดเป็นค่าที่ปลอดภัยที่วัดได้ หรือใช้MemoryHigh=เกณฑ์แรงดันที่อ่อนกว่าควบคู่ไปกับค่าที่สูงกว่าMemoryMax=สำหรับพฤติกรรมที่แน่นอน โปรดตรวจสอบเอกสารประกอบของ systemd และเคอร์เนลที่ติดตั้งไว้ เอกสารอ้างอิงที่เชื่อถือได้คือคู่มือ systemd-run ของ Ubuntu , คู่มือ resource-control ของ Ubuntuและ เอกสารประกอบ cgroup v2 ของเคอร์เนล Linux

ฝากความเห็น

แก้ไขข้อผิดพลาดลายเซ็น APT โดยการซ่อมแซมคีย์ที่เก็บข้อมูล

แก้ไขข้อผิดพลาดลายเซ็น APT โดยการซ่อมแซมคีย์ที่เก็บข้อมูล

แก้ไขคำเตือนการตรวจสอบลายเซ็น APT ของ Ubuntu อย่างปลอดภัย โดยการระบุแหล่งที่มาที่ล้มเหลว รีเฟรชคีย์ที่ได้รับการตรวจสอบแล้ว และตรวจสอบผลลัพธ์โดยไม่ต้องปิดใช้งานระบบรักษาความปลอดภัย

วิธีการแปลงค่าแรงดันไฟฟ้าสามเฟส กระแสไฟฟ้า กำลังไฟฟ้า (kW) กำลังไฟฟ้าแรงสูง (kVA) และตัวประกอบกำลัง

วิธีการแปลงค่าแรงดันไฟฟ้าสามเฟส กระแสไฟฟ้า กำลังไฟฟ้า (kW) กำลังไฟฟ้าแรงสูง (kVA) และตัวประกอบกำลัง

เรียนรู้สูตรสมดุลสามเฟสและวิธีการแปลงแรงดัน กระแส กำลังไฟฟ้า (kW) กำลังไฟฟ้าแรงสูง (kVA) และตัวประกอบกำลังทีละขั้นตอน พร้อมตัวอย่างการคำนวณและข้อจำกัดที่ต้องตรวจสอบ

จำกัดการใช้งาน CPU และหน่วยความจำของคำสั่งด้วย cgroups ใน Ubuntu

จำกัดการใช้งาน CPU และหน่วยความจำของคำสั่งด้วย cgroups ใน Ubuntu

เรียกใช้งานเวิร์กโหลดภายในขอบเขต systemd ด้วย CPUQuota และ MemoryMax จากนั้นตรวจสอบขีดจำกัดผ่าน cgroup v2

เข้ารหัส Pi-hole Upstream DNS บน Ubuntu Server 24.04

เข้ารหัส Pi-hole Upstream DNS บน Ubuntu Server 24.04

ตั้งค่า dnscrypt-proxy เป็นบริดจ์ DoH ในเครื่องของ Pi-hole บน Ubuntu 24.04 โดยกำหนดให้รับฟังเฉพาะ localhost เลือกตัวแก้ไข และตรวจสอบก่อนเปลี่ยน DNS

วิธีใช้งานท่าทางสัมผัสบนทัชแพดใน Ubuntu 24.04 บน Wayland

วิธีใช้งานท่าทางสัมผัสบนทัชแพดใน Ubuntu 24.04 บน Wayland

ตรวจสอบการตั้งค่าทัชแพดของ Ubuntu ยืนยันการใช้งาน Wayland และทดสอบการปัดนิ้วในตัวของ GNOME ก่อนที่จะแก้ไขปัญหาแอปหรือฮาร์ดแวร์

สร้าง RAID 1 Mirror สำหรับ Debian 12 โดยใช้ mdadm

สร้าง RAID 1 Mirror สำหรับ Debian 12 โดยใช้ mdadm

สร้างและตรวจสอบความถูกต้องของอาร์เรย์ข้อมูล RAID 1 สองดิสก์สำหรับ Debian 12 ฟอร์แมตอย่างปลอดภัย และกำหนดค่าให้ประกอบและเมานต์หลังจากรีบูต

เข้ารหัส Swap ของ Debian 12 ด้วยคีย์ใหม่ทุกครั้งที่บูตเครื่อง

เข้ารหัส Swap ของ Debian 12 ด้วยคีย์ใหม่ทุกครั้งที่บูตเครื่อง

ตั้งค่าการเข้ารหัสแบบสุ่มคีย์สำหรับพาร์ติชัน swap ที่มีอยู่ของ Debian 12 ตรวจสอบการแมป dm-crypt ที่ใช้งานอยู่ และทำความเข้าใจข้อดีข้อเสียของการจำศีล

วิธีจำกัดสิทธิ์การเข้าถึง SSH ให้กับผู้ใช้เฉพาะในไดเร็กทอรีที่กำหนดบน Ubuntu 24.04 (คู่มือ SFTP Chroot)

วิธีจำกัดสิทธิ์การเข้าถึง SSH ให้กับผู้ใช้เฉพาะในไดเร็กทอรีที่กำหนดบน Ubuntu 24.04 (คู่มือ SFTP Chroot)

จำกัดการเข้าถึงบัญชี SSH ของ Ubuntu 24.04 ให้เฉพาะโฟลเดอร์ SFTP ที่กำหนดไว้ โดยใช้ chroot, สิทธิ์การเข้าถึงที่เหมาะสม, กฎการจับคู่ และการทดสอบที่ปลอดภัย โดยไม่ให้สิทธิ์การเข้าถึงเชลล์

ปลดล็อก APT ของ Ubuntu อย่างปลอดภัยและทำการอัปเดตให้เสร็จสมบูรณ์

ปลดล็อก APT ของ Ubuntu อย่างปลอดภัยและทำการอัปเดตให้เสร็จสมบูรณ์

ค้นหาว่ากระบวนการใดเป็นเจ้าของไฟล์ล็อกส่วนหน้าของ dpkg ใน Ubuntu ปล่อยให้การติดตั้งแพ็กเกจเสร็จสมบูรณ์ และซ่อมแซมการติดตั้งที่หยุดชะงักโดยไม่ต้องลบไฟล์ล็อก

วิธีตั้งค่าการสร้างสแนปช็อต Btrfs อัตโนมัติบน Ubuntu Desktop

วิธีตั้งค่าการสร้างสแนปช็อต Btrfs อัตโนมัติบน Ubuntu Desktop

ตั้งค่าการสร้างสแนปช็อตระบบ Btrfs ตามกำหนดเวลาบน Ubuntu Desktop ด้วย Timeshift ตรวจสอบโครงสร้างซับโวลุ่มของ Ubuntu เลือกช่วงเวลาการเก็บรักษา และทำความเข้าใจว่าสแนปช็อตไม่สามารถปกป้องอะไรได้บ้าง