หากคำสั่งใดคำสั่งหนึ่งทำให้เดสก์ท็อป 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
เรียกใช้คำสั่งภายในขอบเขต systemd ชั่วคราวโดยกำหนดข้อจำกัดด้าน CPU และหน่วยความจำ
สำหรับคำสั่งที่ผู้ใช้เป็นเจ้าของ ให้ลองใช้คำสั่งนี้โดยไม่ต้องsudoมีสิทธิ์ root ก่อน หาก systemd รายงานว่าตัวควบคุมหรือคุณสมบัติที่ร้องขอไม่พร้อมใช้งาน ผู้จัดการระบบของผู้ใช้อาจไม่มีสิทธิ์ในการมอบหมายสิทธิ์นั้น การลองใหม่ในฐานะ root อาจเหมาะสมสำหรับงานที่ครอบคลุมทั้งระบบ แต่จะเปลี่ยนบริบทด้านความปลอดภัยของคำสั่ง อย่าเรียกใช้โปรแกรมที่ไม่น่าเชื่อถือในฐานะ root โดยไม่คิด หากจำเป็นต้องใช้ผู้จัดการระบบในฐานะ root ให้ใช้sudo systemd-run --scope ...หลังจากพิจารณาการเปลี่ยนแปลงนั้นแล้วเท่านั้น
เทอร์มินัลจะยังคงเชื่อมต่อกับขอบเขตการทำงานขณะที่คำสั่งกำลังทำงาน การกดปุ่มCtrl+Cจะขัดจังหวะการทำงานเบื้องหน้า ขอบเขตการทำงานนี้เป็นแบบชั่วคราวและโดยปกติจะหายไปหลังจากกระบวนการสิ้นสุดลง เป็นวิธีที่สะดวกในการเริ่มต้นคำสั่งภายใต้ข้อจำกัด แทนที่จะใช้เป็นนโยบายถาวรสำหรับการเรียกใช้งานในอนาคต
3. ค้นหาขอบเขตและตรวจสอบข้อจำกัดของขอบเขตนั้น
systemd-runแสดงชื่อหน่วยที่สร้างขึ้น โดยทั่วไปจะเป็นชื่อประมาณนี้run-….scopeขณะที่คำสั่งยังทำงานอยู่ ให้แสดงรายการโครงสร้าง cgroup:
systemd-cgls
ค้นหาขอบเขตชั่วคราวและยืนยันว่าโปรแกรมเป้าหมายและโปรแกรมย่อยปรากฏอยู่ภายใต้ขอบเขตนั้น เรื่องนี้สำคัญเพราะโปรแกรมย่อยที่ทำงานอยู่นอกขอบเขตจะไม่ได้รับการครอบคลุมโดยเพดาน 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 หลักและคอนโทรลเลอร์ที่มีอยู่สามารถจำกัดผลลัพธ์ที่แท้จริงได้
ตรวจสอบกลุ่มควบคุมที่รายงานโดยขอบเขต และขีดจำกัด 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
อ่านไฟล์ 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