หลีกเลี่ยงการดึงแอพพลิเคชั่นออกจากหน่วยความจำของ linux


34

ฉันพบว่าในบางครั้งกล่อง Linux ของฉันมีหน่วยความจำไม่เพียงพอและมันก็เริ่มทำลายกระบวนการสุ่มเพื่อจัดการกับมัน

ฉันอยากรู้ว่าผู้ดูแลระบบทำอะไรเพื่อหลีกเลี่ยงปัญหานี้ เป็นทางออกที่แท้จริงเพียงอย่างเดียวในการเพิ่มจำนวนหน่วยความจำ (จะเพิ่มการสลับอย่างเดียวหรือเปล่า?) หรือมีวิธีที่ดีกว่าในการตั้งค่ากล่องด้วยซอฟต์แวร์เพื่อหลีกเลี่ยงปัญหานี้หรือไม่? (เช่นโควต้าหรือบางอย่างเช่นนั้น)


ฉันพบคำตอบที่นี่: serverfault.com/questions/362589/…การตอบกลับของ Patrick เป็นคำแนะนำที่ดีมาก
Amaury

คำตอบ:


44

ตามค่าเริ่มต้น Linux มีแนวคิดเกี่ยวกับการจัดการหน่วยความจำที่เสียหายจากสมอง: ช่วยให้คุณจัดสรรหน่วยความจำได้มากกว่าระบบของคุณจากนั้นสุ่มถ่ายทำกระบวนการในหัวเมื่อมีปัญหา (ความหมายที่แท้จริงของสิ่งที่ถูกฆ่านั้นซับซ้อนกว่านั้น - Google "Linux OOM Killer" สำหรับรายละเอียดและข้อโต้แย้งมากมายว่าเป็นเรื่องดีหรือไม่ดี)


ในการคืนค่ารูปร่างหน้าตาของสติให้กลับสู่การจัดการหน่วยความจำของคุณ:

  1. ปิดการใช้งาน OOM Killer (ใส่vm.oom-kill = 0/etc/sysctl.conf)
  2. ปิดการใช้งานหน่วยความจำมากเกินไป (ใส่vm.overcommit_memory = 2/etc/sysctl.conf)
    โปรดทราบว่านี่เป็นค่า trinary: 0 = "การประเมินถ้าเรามีแรมเพียงพอ", 1 = "บอกว่าใช่เสมอ", 2 = "บอกว่าไม่ถ้าเราไม่ มีหน่วยความจำ ")

การตั้งค่าเหล่านี้จะทำให้ Linux ทำงานในลักษณะดั้งเดิม (หากกระบวนการร้องขอหน่วยความจำมากกว่าที่มีอยู่ malloc () จะล้มเหลวและกระบวนการที่ขอหน่วยความจำนั้นคาดว่าจะรับมือกับความล้มเหลวนั้นได้

รีบูทเครื่องของคุณเพื่อรีโหลด/etc/sysctl.confหรือใช้procระบบไฟล์เพื่อเปิดใช้งานทันทีโดยไม่ต้องรีบูท:

echo 2 > /proc/sys/vm/overcommit_memory 

11
ไม่ใช่ Linux ที่ระดมสมอง แต่โปรแกรมเมอร์ที่จัดสรรหน่วยความจำไม่ควรใช้ Java VMs มีชื่อเสียงในเรื่องนี้ ฉันในฐานะผู้ดูแลระบบที่จัดการเซิร์ฟเวอร์ที่เรียกใช้แอพพลิเคชั่น Java จะไม่สามารถอยู่รอดได้ภายในหนึ่งวินาที
Aleksandar Ivanisevic

11
โปรแกรมเมอร์ Java ไม่จัดสรรหน่วยความจำที่ไม่ได้ใช้ไม่มี malloc ใน java ฉันคิดว่าคุณสับสนกับการตั้งค่า JVM เช่น -Xms ไม่ว่าในกรณีใดการเพิ่มขนาดหน่วยความจำเสมือนโดยการเพิ่มพื้นที่สว็อปเป็นวิธีที่ปลอดภัยกว่าการเขียนทับมากเกินไป
jlliagre

5
โปรดทราบว่าโซลูชันนี้จะไม่หยุดระบบของคุณไม่ได้ใช้หน่วยความจำหรือกระบวนการฆ่า มันจะเปลี่ยนให้คุณกลับสู่พฤติกรรม Unix แบบดั้งเดิมเท่านั้นซึ่งหากกระบวนการหนึ่งกินหน่วยความจำทั้งหมดของคุณส่วนถัดไปที่พยายามใช้ malloc จะไม่ได้รับความเสียหายใด ๆ หากคุณโชคไม่ดีที่กระบวนการถัดไปเป็นสิ่งเริ่มต้น (หรือสิ่งอื่นที่สำคัญ) ซึ่ง OOM Killer มักหลีกเลี่ยง
pehrs

8
jlliagre ฉันกล่าวว่า Java VMs (Virtual Machines) ไม่ใช่โปรแกรมจาวาแม้ว่าจากมุมมองของผู้ดูแลระบบมันจะเหมือนกัน :)
Aleksandar Ivanisevic

8
อาจจะน่ากล่าวถึงที่นี่ว่าการเพิ่มข้างต้น/etc/sysctl.confจะมีผลเฉพาะในการรีบูตครั้งต่อไป หากคุณต้องการทำการเปลี่ยนแปลงในตอนนี้คุณควรใช้sysctlคำสั่งด้วยการอนุญาตรูตเช่นsudo sysctl vm.overcommit_memory=2
nickgrim


3

คำตอบสั้น ๆ สำหรับเซิร์ฟเวอร์คือการซื้อและติดตั้ง RAM เพิ่มเติม

เซิร์ฟเวอร์ที่มีข้อผิดพลาดOOM (Out-Of-Memory) เป็นประจำเพียงพอนอกเหนือจากตัวเลือก overcommit sysctl ของผู้จัดการ VM (หน่วยความจำเสมือน) ใน Linux kernels นี่ไม่ใช่สิ่งที่ดี

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

สำหรับหลาย ๆ แอปพลิเคชั่นที่จัดสรรเกินสองครั้ง (2x) จำนวนแรมที่ swap จะให้ผลตอบแทนจากการปรับปรุงลดลง ในการจำลองการคำนวณขนาดใหญ่บางกรณีอาจยอมรับได้หากความเร็วช้าลงสามารถรับได้

ด้วย RAM (ECC หรือไม่) มีราคาไม่แพงสำหรับปริมาณที่พอเหมาะเช่น 4-16 GB ฉันต้องยอมรับฉันไม่ได้ประสบปัญหานี้ด้วยตัวเองมาเป็นเวลานาน

ข้อมูลเบื้องต้นเกี่ยวกับการดูปริมาณการใช้หน่วยความจำรวมถึงการใช้freeและtopเรียงลำดับตามการใช้หน่วยความจำเนื่องจากเป็นการประเมินที่รวดเร็วที่สุดสองรูปแบบของการใช้หน่วยความจำ ดังนั้นให้แน่ใจว่าคุณเข้าใจความหมายของแต่ละฟิลด์ในผลลัพธ์ของคำสั่งเหล่านั้นอย่างน้อยที่สุด

ไม่มีแอพพลิเคชั่นเฉพาะเจาะจง (เช่นฐานข้อมูลเซิร์ฟเวอร์บริการเครือข่ายการประมวลผลวิดีโอแบบเรียลไทม์) และการใช้งานเซิร์ฟเวอร์ (ผู้ใช้ที่มีกำลังงานไม่กี่คนการเชื่อมต่อผู้ใช้ / ลูกค้า 100-1000 ราย) ฉันไม่สามารถคิดถึงคำแนะนำทั่วไปใด ๆ ปัญหา OOM


3

การเพิ่มจำนวนหน่วยความจำกายภาพอาจไม่เป็นการตอบสนองที่มีประสิทธิภาพในทุกสถานการณ์

วิธีหนึ่งในการตรวจสอบนี่คือคำสั่ง 'atop' โดยเฉพาะสองบรรทัดนี้

นี่เป็นเซิร์ฟเวอร์นอกเมื่อสถานะนั้นดี:

MEM | tot   23.7G | free   10.0G | cache   3.9G | buff  185.4M | slab  207.8M |
SWP | tot    5.7G | free    5.7G |              | vmcom  28.1G | vmlim  27.0G |

เมื่อมันทำงานได้ไม่ดี (และก่อนที่เราจะปรับเปลี่ยน overcommit_memory จาก 50 เป็น 90 เราจะเห็นพฤติกรรมของ vmcom ทำงานได้ดีกว่า 50G, oom-killer ระเบิดกระบวนการทุกสองสามวินาทีและโหลดก็คงเด้งอย่างรุนแรง ขึ้นและสร้างใหม่อย่างต่อเนื่อง

เมื่อเร็ว ๆ นี้เราได้ทำซ้ำกรณีที่เซิร์ฟเวอร์เทอร์มินัล Linux ผู้ใช้หลายคนทุ่มเทการจัดสรรหน่วยความจำเสมือนอย่างหนาแน่น แต่มีการใช้งานหน้าเว็บที่ร้องขอน้อยมาก

แม้ว่าจะไม่แนะนำให้ทำตามเส้นทางที่แน่นอนนี้ แต่เราได้ปรับหน่วยความจำเกินพิกัดจากค่าเริ่มต้น 50 ถึง 90 ซึ่งช่วยบรรเทาปัญหาบางอย่างได้ เราต้องย้ายผู้ใช้ทั้งหมดไปยังเทอร์มินัลเซิร์ฟเวอร์อื่นและเริ่มต้นใหม่เพื่อดูประโยชน์ทั้งหมด


2

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

หากปัญหาของคุณคือคุณไม่มีหน่วยความจำเพียงพอที่จะเรียกใช้บริการที่คุณต้องการมีเพียงสามวิธีเท่านั้น:

  1. ลดหน่วยความจำที่บริการของคุณใช้โดย จำกัด แคชและสิ่งที่คล้ายกัน

  2. สร้างพื้นที่สว็อปที่ใหญ่ขึ้น มันจะทำให้คุณเสียค่าใช้จ่าย แต่สามารถซื้อเวลาได้

  3. ซื้อหน่วยความจำเพิ่ม


0

ฉันมีปัญหาที่คล้ายกันที่เกี่ยวข้องกับข้อผิดพลาดนี้และการแก้ปัญหาคือการใช้เคอร์เนลเก่า / ใหม่ (คงที่)

อย่างไรก็ตามในขณะที่ฉันไม่สามารถรีบูตเครื่องของฉันดังนั้นวิธีแก้ปัญหาที่น่าเกลียดบางอย่างก็คือการเข้าสู่ระบบในฐานะที่เป็น root และล้างแคชระบบด้วยคำสั่งนี้:

echo 3 > /proc/sys/vm/drop_caches

-5

@ voretaq7 linux ไม่มีแนวคิดเรื่องสมองที่เสียหายของการจัดการหน่วยความจำโดยค่าเริ่มต้น vm.overcommit_ratio คือ 0

0       -   Heuristic overcommit handling. Obvious overcommits of
            address space are refused. Used for a typical system. It
            ensures a seriously wild allocation fails while allowing
            overcommit to reduce swap usage.  root is allowed to
            allocate slightly more memory in this mode. This is the
            default.

ด้วยวิธีนี้ถ้าคุณมี RAM 4GB และคุณพยายามจัดสรร 4.2 GB ด้วย malloc ของหน่วยความจำเสมือนการจัดสรรของคุณจะล้มเหลว

ด้วย vm.overcommit_ratio = 1

            1    -   Always overcommit. Appropriate for some scientific
            applications. Classic example is code using sparse arrays
            and just relying on the virtual memory consisting almost
            entirely of zero pages.

ด้วย vm.overcommit_ratio = 2

           2    -   Don't overcommit. The total address space commit
            for the system is not permitted to exceed swap + a
            configurable percentage (default is 50) of physical RAM.
            Depending on the percentage you use, in most situations
            this means a process will not be killed while accessing
            pages but will receive errors on memory allocation as
            appropriate.

            Useful for applications that want to guarantee their
            memory allocations will be available in the future
            without having to initialize every page.

ดังนั้นโดยค่าเริ่มต้น linux จะไม่ overcommit ถ้าแอปพลิเคชันของคุณมีหน่วยความจำมากกว่าคุณก็อาจเป็นโค้ดของคุณ


2
คุณขัดแย้งกับตัวเองที่นี่ ที่ด้านบนคุณพูดว่า "โดยค่าเริ่มต้น vm.overcommit_ratio เป็น 0" และที่ด้านล่างคุณจะพูดว่า "โดยค่าเริ่มต้น linux จะไม่พูดเกินจริง" หากหลังเป็นจริง vm.overcommit_ratio จะเป็น 2 โดยค่าเริ่มต้น!
Michael Hampton

vm.overcommit_ratio = 0, malloc ไม่ได้จัดสรรหน่วยความจำมากกว่า ram ทางกายภาพของคุณดังนั้นสำหรับฉันนั่นหมายถึงว่าไม่ overcommit overcommit คือเมื่อคุณสามารถจัดสรรเสมือนจริงมากกว่า ram ทางกายภาพของคุณ
c4f4t0r

2
ใช่คุณเข้าใจผิด
Michael Hampton

คุณเข้าใจผิดค่าเริ่มต้น 0 ไม่จัดสรรจัดสรรหน่วยความจำเสมือนมากกว่า ram และ 2 ไม่อนุญาตให้ vm.overcommit_ratio + swap space ดังนั้นถ้าฉันเข้าใจผิดบอกฉันว่า
c4f4t0r

2
แน่นอน. "ชัดเจน overcommits" ถูกปฏิเสธ ส่วนที่เหลือผ่านไป คุณต้องอ่านให้ละเอียดยิ่งขึ้น
Michael Hampton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.