วิธีแก้ไขข้อผิดพลาด “ไฟล์ที่เปิดมากเกินไป” บน Linux
เผยแพร่แล้ว: 2022-06-29บนคอมพิวเตอร์ Linux ทรัพยากรระบบจะถูกแชร์ระหว่างผู้ใช้ พยายามใช้มากกว่าส่วนแบ่งที่ยุติธรรมของคุณและคุณจะถึงขีดจำกัดสูงสุด คุณยังอาจคอขวดกับผู้ใช้หรือกระบวนการอื่นๆ
ทรัพยากรระบบที่ใช้ร่วมกัน
ในบรรดางานกว่าพันล้านงาน เคอร์เนลของคอมพิวเตอร์ลินุกซ์มักจะยุ่งกับการดูว่าใครกำลังใช้ทรัพยากรระบบที่มีจำกัด เช่น รอบ RAM และ CPU ระบบที่มีผู้ใช้หลายคนต้องการความเอาใจใส่อย่างต่อเนื่องเพื่อให้แน่ใจว่าผู้คนและกระบวนการต่างๆ ไม่ได้ใช้ทรัพยากรระบบที่กำหนดมากเกินความจำเป็น
มันไม่ยุติธรรม เช่น สำหรับคนที่ใช้ CPU มากจนทำให้คนอื่นรู้สึกว่าคอมพิวเตอร์ช้า แม้ว่าคุณจะเป็นคนเดียวที่ใช้คอมพิวเตอร์ Linux แต่ก็มีการจำกัดทรัพยากรที่กระบวนการของคุณสามารถใช้ได้ ท้ายที่สุด คุณยังเป็นเพียงผู้ใช้รายอื่น
ทรัพยากรระบบบางอย่างเป็นที่รู้จักและชัดเจน เช่น RAM รอบ CPU และพื้นที่ฮาร์ดไดรฟ์ แต่มีทรัพยากรอีกมากมายที่ได้รับการตรวจสอบและผู้ใช้แต่ละรายหรือแต่ละ กระบวนการ ที่ผู้ใช้เป็นเจ้าของ มีขีด จำกัด สูงสุด หนึ่งในนั้นคือจำนวนไฟล์ที่กระบวนการสามารถเปิดได้ในครั้งเดียว
หากคุณเคยเห็นข้อความแสดงข้อผิดพลาด "Too many files open" ในหน้าต่างเทอร์มินัลหรือพบข้อความดังกล่าวในบันทึกของระบบ แสดงว่ามีการใช้งานถึงขีดจำกัดบนแล้ว และกระบวนการนี้ไม่ได้รับอนุญาตให้เปิดไฟล์ได้อีก
ไม่ใช่แค่ไฟล์ที่คุณเปิด
มีการจำกัดจำนวนไฟล์ที่เปิดอยู่ทั้งระบบที่ Linux สามารถจัดการได้ เป็นจำนวนที่มากอย่างที่เราจะได้เห็น แต่ก็ยังมีจำกัด กระบวนการของผู้ใช้แต่ละคนมีการจัดสรรที่สามารถใช้ได้ พวกเขาแต่ละคนได้รับส่วนแบ่งเล็กน้อยของระบบทั้งหมดที่จัดสรรให้กับพวกเขา
สิ่งที่ได้รับการจัดสรรจริง ๆ คือจำนวน ไฟล์ที่จัดการ แต่ละไฟล์ที่เปิดขึ้นต้องมีหมายเลขอ้างอิง แม้จะมีการจัดสรรที่เพียงพอ การจัดการไฟล์ทั่วทั้งระบบก็สามารถใช้งานได้เร็วกว่าที่คุณคิดในตอนแรก
Linux ย่อเกือบทุกอย่างเพื่อให้ดูเหมือนเป็นไฟล์ บางครั้งมันก็เป็นแค่ไฟล์เก่าๆ ธรรมดาๆ แต่การดำเนินการอื่นๆ เช่น การเปิดไดเร็กทอรีก็ใช้ตัวจัดการไฟล์เช่นกัน Linux ใช้บล็อกไฟล์พิเศษเป็นไดรเวอร์สำหรับอุปกรณ์ฮาร์ดแวร์ ไฟล์พิเศษของอักขระมีความคล้ายคลึงกันมาก แต่มักใช้กับอุปกรณ์ที่มีแนวคิดเรื่องปริมาณงาน เช่น ไพพ์และพอร์ตอนุกรม
บล็อกไฟล์พิเศษจัดการบล็อกของข้อมูลในแต่ละครั้ง และไฟล์พิเศษของอักขระจะจัดการอักขระแต่ละตัวแยกกัน ไฟล์พิเศษทั้งสองนี้สามารถเข้าถึงได้โดยใช้ตัวจัดการไฟล์เท่านั้น ไลบรารีที่ใช้โดยโปรแกรมใช้ตัวจัดการไฟล์ สตรีมใช้ตัวจัดการไฟล์ และการเชื่อมต่อเครือข่ายใช้ตัวจัดการไฟล์
การสรุปข้อกำหนดที่แตกต่างกันทั้งหมดเหล่านี้เพื่อให้ปรากฏเป็นไฟล์ทำให้การเชื่อมต่อกับข้อกำหนดเหล่านี้ง่ายขึ้น และช่วยให้สิ่งต่างๆ เช่น การไพพ์และสตรีมทำงาน
คุณจะเห็นว่าเบื้องหลังของลีนุกซ์กำลังเปิดไฟล์และใช้ตัวจัดการไฟล์เพื่อรันเอง ไม่ต้องกังวลกับกระบวนการของผู้ใช้ของคุณ จำนวนไฟล์ที่เปิดไม่ได้เป็นเพียงจำนวนไฟล์ที่คุณเปิดเท่านั้น เกือบทุกอย่างในระบบปฏิบัติการใช้ตัวจัดการไฟล์
ขีด จำกัด การจัดการไฟล์
จำนวนสูงสุดของการจัดการไฟล์ทั้งระบบสามารถดูได้ด้วยคำสั่งนี้
cat /proc/sys/fs/file-max
ส่งคืนจำนวนมากอย่างผิดปกติถึง 9.2 quintillion นั่นคือค่าสูงสุดของระบบทฤษฎี เป็นค่าที่ใหญ่ที่สุดที่คุณสามารถเก็บได้ในจำนวนเต็มที่ลงนาม 64 บิต คอมพิวเตอร์ที่แย่ของคุณสามารถรับมือกับไฟล์หลาย ๆ ไฟล์ที่เปิดพร้อมกันได้หรือไม่นั้นเป็นอีกเรื่องหนึ่ง
ที่ระดับผู้ใช้ ไม่มีค่าที่ชัดเจนสำหรับจำนวนไฟล์ที่เปิดสูงสุดที่คุณสามารถมีได้ แต่เราทำได้คร่าวๆ หากต้องการทราบจำนวนไฟล์สูงสุดที่กระบวนการใดกระบวนการหนึ่งของคุณสามารถเปิดได้ เราสามารถใช้คำสั่ง ulimit
พร้อมตัวเลือก -n
(เปิดไฟล์)
ulimit -n
และเพื่อค้นหาจำนวนกระบวนการสูงสุดที่ผู้ใช้สามารถมีได้ เราจะใช้ ulimit
กับตัวเลือก -u
(กระบวนการของผู้ใช้)
ulimit -u
การคูณ 1024 และ 7640 ทำให้เราได้ 7,823,360 แน่นอนว่ากระบวนการเหล่านั้นจำนวนมากจะถูกใช้โดยสภาพแวดล้อมเดสก์ท็อปของคุณและกระบวนการพื้นหลังอื่นๆ นั่นคือค่าสูงสุดทางทฤษฎีอีกอย่างหนึ่ง และสิ่งที่คุณไม่มีวันบรรลุผลตามความเป็นจริง
ตัวเลขที่สำคัญคือจำนวนไฟล์ที่กระบวนการสามารถเปิดได้ โดยค่าเริ่มต้น นี่คือ 1024 เป็นที่น่าสังเกตว่าการเปิดไฟล์เดียวกัน 1024 ครั้งพร้อมกันนั้นเหมือนกับการเปิดไฟล์ต่างๆ 1024 ไฟล์พร้อมกัน เมื่อคุณใช้ตัวจัดการไฟล์ของคุณหมดแล้ว แสดงว่าคุณทำเสร็จแล้ว
สามารถปรับจำนวนไฟล์ที่กระบวนการสามารถเปิดได้ มีสองค่าที่ควรพิจารณาเมื่อคุณกำลังปรับตัวเลขนี้ หนึ่งคือค่าที่ตั้งค่าไว้ในปัจจุบันหรือที่คุณพยายามตั้งค่า นี้เรียกว่า ขีดจำกัดซอ ฟต์ มี ฮาร์ดลิมิต ด้วย และนี่คือค่าสูงสุดที่คุณสามารถเพิ่มขีดจำกัดซอฟต์ได้
วิธีคิดเกี่ยวกับสิ่งนี้คือขีดจำกัดซอฟต์จริงๆ คือ “ค่าปัจจุบัน” และขีดจำกัดบนคือค่าสูงสุดที่ค่าปัจจุบันสามารถเข้าถึงได้ ผู้ใช้ปกติที่ไม่ใช่รูทสามารถเพิ่มขีดจำกัดซอฟต์เป็นค่าใดก็ได้จนถึงขีดจำกัดฮาร์ด ผู้ใช้รูทสามารถเพิ่มขีดจำกัดฮาร์ดได้
หากต้องการดูขีดจำกัดซอฟต์และฮาร์ดในปัจจุบัน ให้ใช้ ulimit
กับตัวเลือก -S
(อ่อน) และ -H
(ยาก) และตัวเลือก -n
(เปิดไฟล์)
ulimit -Sn
ulimit -Hn
ในการสร้างสถานการณ์ที่เราเห็นการบังคับใช้ขีดจำกัดซอฟต์ เราได้สร้างโปรแกรมที่เปิดไฟล์ซ้ำๆ จนกว่าจะล้มเหลว จากนั้นจะรอการกดแป้นพิมพ์ก่อนที่จะละทิ้งไฟล์ทั้งหมดที่ใช้จัดการ โปรแกรมนี้เรียกว่า open-files
./open-Files
มันเปิดไฟล์ 1,021 ไฟล์และล้มเหลวในขณะที่พยายามเปิดไฟล์ 1022
1024 ลบ 1021 ได้ 3. เกิดอะไรขึ้นกับตัวจัดการไฟล์อีกสามตัว ใช้สำหรับสตรีม STDIN
, STDOUT
และ STDERR
พวกมันถูกสร้างขึ้นโดยอัตโนมัติสำหรับแต่ละกระบวนการ ค่าเหล่านี้มีค่าตัวอธิบายไฟล์เป็น 0, 1 และ 2 เสมอ
ที่เกี่ยวข้อง: วิธีใช้ Linux lsof Command
เราสามารถเห็นสิ่งเหล่านี้ได้โดยใช้คำสั่ง lsof
พร้อมตัวเลือก -p
(กระบวนการ) และ ID กระบวนการของโปรแกรม open-files
สะดวก มันพิมพ์ ID กระบวนการไปที่หน้าต่างเทอร์มินัล
lsof -p 11038
แน่นอน ในสถานการณ์จริง คุณอาจไม่รู้ว่ากระบวนการใดได้กินการจัดการไฟล์ทั้งหมดไปแล้ว เพื่อเริ่มต้นการตรวจสอบของคุณ คุณสามารถใช้ลำดับของคำสั่งไปป์นี้ มันจะบอกคุณถึงผู้ใช้ไฟล์จำนวนมากที่สุดในคอมพิวเตอร์ของคุณ 15 คน
lsof | awk '{ พิมพ์ $1 " " $2; }' | sort -rn | uniq -c | sort -rn | หัว -15
หากต้องการดูรายการมากหรือน้อยให้ปรับพารามิเตอร์ -15
เป็นคำสั่ง head
เมื่อคุณระบุกระบวนการได้แล้ว คุณต้องคิดให้ออกว่ามันโกงและเปิดไฟล์มากเกินไปหรือไม่เพราะอยู่นอกเหนือการควบคุม หรือว่ามันต้องการไฟล์เหล่านั้นจริงๆ หรือไม่ หากต้องการ คุณต้องเพิ่มขีดจำกัดการจัดการไฟล์
การเพิ่มขีดจำกัดซอฟต์
หากเราเพิ่มขีดจำกัดซอฟต์และรันโปรแกรมของเราอีกครั้ง เราควรเห็นมันเปิดไฟล์มากขึ้น เราจะใช้คำสั่ง ulimit
และตัวเลือก -n
(เปิดไฟล์) ด้วยค่าตัวเลข 2048 ซึ่งจะเป็นขีดจำกัดซอฟต์ใหม่
ulimit -n 2048
คราวนี้เราเปิดไฟล์ 2045 ได้สำเร็จ ตามที่คาดไว้ ค่านี้น้อยกว่า 2048 สามรายการ เนื่องจากตัวจัดการไฟล์ที่ใช้สำหรับ STDIN
, STDOUT
และ STDERR
ทำการเปลี่ยนแปลงถาวร
การเพิ่มขีดจำกัดซอฟต์มีผลกับเชลล์ปัจจุบันเท่านั้น เปิดหน้าต่างเทอร์มินัลใหม่และตรวจสอบขีดจำกัดซอฟต์ คุณจะเห็นว่าเป็นค่าเริ่มต้นเดิม แต่มีวิธีการตั้งค่าเริ่มต้นใหม่ทั่วโลกสำหรับจำนวนไฟล์ที่เปิดสูงสุดที่กระบวนการสามารถมีได้อย่างต่อเนื่องและสามารถรีบูตได้
คำแนะนำที่ล้าสมัยมักแนะนำให้คุณแก้ไขไฟล์ เช่น “/etc/sysctl.conf” และ “/etc/security/limits.conf” อย่างไรก็ตาม ในการแจกแจงแบบอิง systemd การแก้ไขเหล่านี้ไม่ทำงานอย่างสม่ำเสมอ โดยเฉพาะอย่างยิ่งสำหรับเซสชันการเข้าสู่ระบบแบบกราฟิก
เทคนิคที่แสดงที่นี่เป็นวิธีการทำเช่นนี้ในการแจกแจงแบบอิง systemd มีสองไฟล์ที่เราต้องใช้งาน ไฟล์แรกคือไฟล์ “/etc/systemd/system.conf” เราจะต้องใช้ sudo
sudo gedit /etc/systemd/system.conf
ค้นหาบรรทัดที่มีสตริง “DefaultLimitNOFILE” ลบแฮช “#” ออกจากจุดเริ่มต้นของบรรทัด และแก้ไขตัวเลขแรกเป็นสิ่งที่คุณต้องการให้ซอฟต์ลิมิตใหม่สำหรับกระบวนการเป็น เราเลือก 4096 ตัวเลขที่สองในบรรทัดนั้นคือฮาร์ดลิมิต เราไม่ได้ปรับสิ่งนี้
บันทึกไฟล์และปิดตัวแก้ไข
เราจำเป็นต้องทำซ้ำการดำเนินการนั้นในไฟล์ “/etc/systemd/user.conf”
sudo gedit /etc/systemd/user.conf
ทำการปรับเปลี่ยนเดียวกันกับบรรทัดที่มีสตริง “DefaultLimitNOFILE”
บันทึกไฟล์และปิดตัวแก้ไข คุณต้องรีบูตเครื่องคอมพิวเตอร์หรือใช้คำสั่ง systemctl
ด้วยตัวเลือก daemon-reexec
เพื่อให้ systemd
ดำเนินการอีกครั้งและนำเข้าการตั้งค่าใหม่
sudo systemctl daemon-reexec
การเปิดหน้าต่างเทอร์มินัลและตรวจสอบขีดจำกัดใหม่ควรแสดงค่าใหม่ที่คุณตั้งไว้ ในกรณีของเราคือ 4096
ulimit -n
เราสามารถทดสอบว่าเป็นค่าจริงและใช้งานได้โดยเรียกใช้โปรแกรม file-greedy ของเราอีกครั้ง
./open-Files
โปรแกรมไม่สามารถเปิดไฟล์หมายเลข 4094 ซึ่งหมายความว่า 4093 เป็นไฟล์ที่เปิดอยู่ นั่นคือค่าที่เราคาดหวัง 3 น้อยกว่า 4096
ทุกอย่างเป็นไฟล์
นั่นเป็นสาเหตุที่ลินุกซ์ต้องพึ่งพาการจัดการไฟล์มาก ตอนนี้ ถ้าคุณเริ่มจะหมด คุณก็รู้วิธีเพิ่มโควต้าของคุณแล้ว
ที่เกี่ยวข้อง: stdin, stdout และ stderr บน Linux คืออะไร