- อะไรคือวิธีที่เร็วที่สุดในการควบคุมระบบลีนุกซ์ที่ไม่ตอบสนองหรือซบเซาอย่างรุนแรงเนื่องจากการแลกเปลี่ยนมากเกินไป?
ตอบไปแล้วข้างต้นด้วยAlt-SysRq-F
- มีวิธีที่มีประสิทธิภาพในการป้องกันการสลับที่เกิดขึ้นตั้งแต่แรกเช่นโดย จำกัด จำนวนหน่วยความจำที่กระบวนการอนุญาตให้ลองจัดสรรได้หรือไม่?
ฉันกำลังตอบส่วนที่ 2 นี้ ใช่ulimit
ยังทำงานได้ดีพอที่จะ จำกัด กระบวนการเดียว คุณสามารถ:
- ตั้งค่าขีด จำกัด นุ่มนวลสำหรับกระบวนการที่คุณรู้ว่ามีแนวโน้มว่าจะอยู่นอกเหนือการควบคุม
- กำหนดวงเงินที่เข้มงวดสำหรับกระบวนการทั้งหมดหากคุณต้องการประกันเพิ่มเติม
นอกจากนี้ตามที่กล่าวไว้สั้น ๆ :
คุณสามารถใช้กลุ่มเพื่อ จำกัด การใช้ทรัพยากรและป้องกันปัญหาดังกล่าว
แน่นอนกลุ่ม cg ให้การควบคุมขั้นสูงมากขึ้น แต่ในปัจจุบันมีความซับซ้อนในการกำหนดค่าในความคิดของฉัน
ulimit โรงเรียนเก่า
ทันทีที่ปิด
นี่เป็นตัวอย่างง่ายๆ:
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
มัน:
- ตั้งค่าขีด จำกัด ซอฟต์ของการใช้หน่วยความจำโดยรวม 1GB (ulimit ถือว่า จำกัด เป็นหน่วย kB)
- รันการเรียกใช้ฟังก์ชัน bash แบบเรียกซ้ำ
r2(){ r2 $@$@;};r2 r2
ซึ่งจะทำการเคี้ยวซีพียูและ RAM อย่างทวีคูณโดยทวีคูณตัวมันเองเป็นสองเท่าในขณะที่ร้องขอหน่วยความจำสแต็ก
อย่างที่คุณเห็นมันหยุดเมื่อพยายามร้องขอมากกว่า 1GB
หมายเหตุ-v
ทำงานบนการจัดสรรหน่วยความจำเสมือน (ผลรวมคือการแลกเปลี่ยนทางกายภาพ +)
ป้องกันถาวร
เพื่อ จำกัด การจัดสรรหน่วยความจำเสมือนas
เป็นเทียบเท่าของสำหรับ-v
limits.conf
ฉันทำสิ่งต่อไปนี้เพื่อป้องกันกระบวนการที่ทำงานผิดปกติใด ๆ :
- ตั้งค่าขีด จำกัด พื้นที่แอดเดรสฮาร์ดสำหรับกระบวนการทั้งหมด
address space limit = <physical memory> - 256MB
.
- ดังนั้นไม่มีกระบวนการเดียวที่มีการใช้หน่วยความจำโลภหรือลูปที่ใช้งานอยู่และการรั่วไหลของหน่วยความจำสามารถใช้หน่วยความจำกายภาพทั้งหมด
- headroom ขนาด 256MB สำหรับการประมวลผลที่จำเป็นด้วย ssh หรือคอนโซล
หนึ่งในสายการบิน:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
ในการตรวจสอบความถูกต้องนี้จะส่งผลต่อไปนี้ (เช่นในระบบ 16GB):
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
หมายเหตุ:
- ลดผลกระทบต่อกระบวนการเดียวที่ลงน้ำด้วยการใช้หน่วยความจำ
- จะไม่ป้องกันภาระงานหลายกระบวนการด้วยแรงกดดันหน่วยความจำหนักทำให้เกิดการฟาดฟัน (กลุ่มคำตอบคือคำตอบ)
- อย่าใช้
rss
ตัวเลือกใน limit.conf มันไม่ได้เป็นที่เคารพนับถือของเมล็ดพันธุ์ใหม่
- มันอนุรักษ์นิยม
- ในทางทฤษฎีกระบวนการสามารถร้องขอหน่วยความจำจำนวนมากได้ แต่ใช้ชุดย่อยเท่านั้น (ใช้ชุดการทำงาน / การใช้หน่วยความจำขนาดเล็ก)
- ขีด จำกัด ฮาร์ดด้านบนจะทำให้กระบวนการดังกล่าวหยุดทำงาน (แม้ว่าพวกเขาอาจทำงานได้ดีเนื่องจาก Linux อนุญาตให้ใช้พื้นที่ที่อยู่หน่วยความจำเสมือนมากเกินไป)
ใหม่กว่ากลุ่ม CG
ให้การควบคุมที่มากขึ้น แต่ในปัจจุบันมีความซับซ้อนในการใช้:
- ปรับปรุงการเสนอ ulimit
memory.max_usage_in_bytes
สามารถบัญชีและ จำกัด หน่วยความจำทางกายภาพแยกจากกัน
- ในขณะที่
ulimit -m
และ / หรือrss
ในlimits.conf
หมายถึงการให้ฟังก์ชั่นที่คล้ายกัน แต่ไม่ได้ทำงานตั้งแต่ kernel Linux 2.4.30!
- ต้องเปิดใช้งานธงเคอร์เนล cgroup บางอย่างใน
cgroup_enable=memory swapaccount=1
bootloader:
- สิ่งนี้ไม่ได้เกิดขึ้นตามค่าเริ่มต้นกับ Ubuntu 16.04
- อาจเป็นเพราะความเกี่ยวเนื่องของประสิทธิภาพของค่าใช้จ่ายทางบัญชีเพิ่มเติม
- สิ่งที่ cgroup / systemd ค่อนข้างใหม่และการเปลี่ยนบิตที่เป็นธรรมดังนั้นฟลักซ์อัพสตรีมจึงสื่อถึงผู้จำหน่าย distro Linux ที่ยังไม่ได้ใช้งานง่าย ระหว่าง 14.04LTS ถึง 16.04LTS เครื่องมือพื้นที่ผู้ใช้ในการใช้กลุ่ม cg ได้เปลี่ยนไป
cgm
ตอนนี้ดูเหมือนว่าจะเป็นเครื่องมือ userspace ที่สนับสนุนอย่างเป็นทางการ
- ดูเหมือนว่าไฟล์หน่วย systemd ยังไม่มีค่าเริ่มต้น "ผู้จำหน่าย / distro" ที่กำหนดไว้ล่วงหน้าใด ๆ เพื่อจัดลำดับความสำคัญของบริการที่สำคัญเช่น ssh
เช่นเพื่อตรวจสอบการตั้งค่าปัจจุบัน:
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
เช่นเพื่อ จำกัด หน่วยความจำของกระบวนการเดียว:
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
หากต้องการดูการใช้งานในการเคี้ยว RAM เป็นกระบวนการพื้นหลังแล้วถูกฆ่า:
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
สังเกตการเติบโตแบบเอ็กซ์โพเนนเชียล (กำลัง 2) ในคำขอหน่วยความจำ
ในอนาคตเราหวังว่าจะเห็น "distro / ผู้ขาย" กำหนดค่าลำดับความสำคัญและข้อ จำกัด ของ cgroup ล่วงหน้า (ผ่าน systemd units) สำหรับสิ่งที่สำคัญเช่น SSH และกราฟิกสแต็ก