Cách khắc phục lỗi "Too Many Open Files" trên Linux

Tác giả sysadmin, T.Mười 30, 2023, 01:50:04 CHIỀU

« Chủ đề trước - Chủ đề tiếp »

0 Thành viên và 2 Khách đang xem chủ đề.

Cách khắc phục lỗi "Too Many Open Files" trên Linux


Bạn cần phải xử lý nó. Nếu bạn thấy thông báo lỗi "Too Many Open Files" trong Linux thì quy trình của bạn đã đạt đến giới hạn trên của tệp được phép mở, thường là 1.024. Bạn có thể tạm thời tăng giới hạn lên, chẳng hạn như 2.048 tệp, bằng lệnh "ulimit -n 2048". Tăng giới hạn vĩnh viễn bằng cách chỉnh sửa tệp cấu hình systemd.

Trên máy tính Linux, tài nguyên hệ thống được chia sẻ giữa những người dùng. Hãy cố gắng sử dụng nhiều hơn mức chia sẻ hợp lý của bạn và bạn sẽ đạt đến giới hạn trên. Bạn cũng có thể gây tắc nghẽn cho người dùng hoặc quy trình khác.

1. Lỗi Too Many Open Files là gì?

Trong số rất nhiều công việc khác, nhân của máy tính Linux luôn bận rộn xem ai đang sử dụng bao nhiêu tài nguyên hệ thống hữu hạn, chẳng hạn như RAM và chu kỳ CPU. Hệ thống nhiều người dùng yêu cầu sự chú ý liên tục để đảm bảo mọi người và quy trình không sử dụng nhiều tài nguyên hệ thống nhất định hơn mức phù hợp.

Chẳng hạn, thật không công bằng khi ai đó chiếm quá nhiều thời gian của CPU khiến máy tính của những người khác cảm thấy chậm. Ngay cả khi bạn là người duy nhất sử dụng máy tính Linux của mình, vẫn có những giới hạn được đặt ra cho các tài nguyên mà quy trình của bạn có thể sử dụng. Suy cho cùng, bạn vẫn chỉ là một người dùng khác.

Một số tài nguyên hệ thống nổi tiếng và rõ ràng, như RAM, chu kỳ CPU và dung lượng ổ cứng. Nhưng còn rất nhiều tài nguyên khác được giám sát và mỗi người dùng - hoặc mỗi quy trình do người dùng sở hữu - đều có giới hạn trên được đặt ra. Một trong số đó là số lượng tệp mà một tiến trình có thể mở cùng một lúc.

Nếu bạn đã từng thấy thông báo lỗi "Too Many Open Files" trong cửa sổ terminal hoặc tìm thấy nó trong nhật ký hệ thống của mình, điều đó có nghĩa là giới hạn trên đã đạt đến và quy trình không được phép mở thêm bất kỳ tệp nào.

2. Tại sao có quá nhiều tập tin được mở?

Có giới hạn trên toàn hệ thống về số lượng tệp đang mở mà Linux có thể xử lý. Đó là một con số rất lớn, như chúng ta sẽ thấy, nhưng vẫn có một giới hạn. Mỗi quy trình người dùng có một sự phân bổ mà họ có thể sử dụng. Mỗi người đều nhận được một phần nhỏ trong tổng số hệ thống được phân bổ cho họ.

Những gì thực sự được phân bổ là một số thẻ xử lý tệp. Mỗi tập tin được mở đều yêu cầu một tay cầm. Ngay cả với sự phân bổ khá hào phóng, các trình xử lý tệp trên toàn hệ thống có thể được sử dụng hết nhanh hơn bạn tưởng tượng ban đầu.

Linux trừu tượng hóa hầu hết mọi thứ để nó xuất hiện như thể nó là một tập tin. Đôi khi chúng chỉ là những tập tin cũ đơn thuần. Nhưng các hành động khác như mở thư mục cũng sử dụng trình xử lý tệp. Linux sử dụng các tập tin đặc biệt dạng khối làm loại trình điều khiển cho các thiết bị phần cứng. Các tệp ký tự đặc biệt rất giống nhau, nhưng chúng thường được sử dụng nhiều hơn với các thiết bị có khái niệm về thông lượng, chẳng hạn như đường ống và cổng nối tiếp.

Khối các tệp đặc biệt xử lý các khối dữ liệu cùng một lúc và các tệp ký tự đặc biệt xử lý từng ký tự riêng biệt. Cả hai tệp đặc biệt này chỉ có thể được truy cập bằng cách sử dụng các thẻ điều khiển tệp. Các thư viện được chương trình sử dụng sử dụng trình điều khiển tệp, luồng sử dụng trình điều khiển tệp và kết nối mạng sử dụng trình điều khiển tệp.

Việc trừu tượng hóa tất cả các yêu cầu khác nhau này để chúng xuất hiện dưới dạng tệp giúp đơn giản hóa việc giao tiếp với chúng và cho phép những thứ như đường ống và luồng hoạt động.

Bạn có thể thấy rằng đằng sau hậu trường Linux đang mở các tệp và sử dụng các trình xử lý tệp chỉ để tự chạy - đừng bận tâm đến các quy trình người dùng của bạn. Số lượng tệp đang mở không chỉ là số lượng tệp bạn đã mở. Hầu hết mọi thứ trong hệ điều hành đều sử dụng các thẻ xử lý tệp.

3. Cách kiểm tra giới hạn xử lý tệp

Có thể xem số lượng xử lý tệp tối đa trên toàn hệ thống bằng lệnh này.

Mã nguồn [Chọn]
cat /proc/sys/fs/file-max

Điều này trả về một con số lớn đến mức phi lý là 9,2 triệu. Đó là hệ thống lý thuyết tối đa. Đó là giá trị lớn nhất có thể mà bạn có thể giữ trong số nguyên có dấu 64 bit. Liệu chiếc máy tính kém của bạn có thực sự có thể xử lý được nhiều tệp mở cùng lúc hay không lại là một vấn đề khác.

Ở cấp độ người dùng, không có giá trị rõ ràng cho số lượng tệp mở tối đa mà bạn có thể có. Nhưng đại khái chúng ta có thể giải quyết được. Để tìm ra số lượng tệp tối đa mà một trong các quy trình của bạn có thể mở, chúng tôi có thể sử dụng ulimit lệnh với -n tùy chọn (mở tệp).

Mã nguồn [Chọn]
ulimit -n

Và để tìm số lượng quy trình tối đa mà người dùng có thể có, chúng tôi sẽ sử dụng ulimittùy -uchọn (quy trình của người dùng).

Mã nguồn [Chọn]
ulimit -u

Nhân 1024 với 7640 ta được 7,823,360. Tất nhiên, nhiều quy trình trong số đó sẽ được môi trường máy tính để bàn của bạn và các quy trình nền khác sử dụng. Vì vậy, đó là một mức tối đa khác về mặt lý thuyết và là mức tối đa mà bạn sẽ không bao giờ đạt được trên thực tế.

Con số quan trọng là số lượng tệp mà một tiến trình có thể mở. Theo mặc định, đây là 1024. Điều đáng chú ý là việc mở cùng một tệp 1024 lần đồng thời cũng giống như mở đồng thời 1024 tệp khác nhau. Khi bạn đã sử dụng hết tất cả các thẻ điều khiển tệp của mình, bạn đã hoàn tất.

Có thể điều chỉnh số lượng tệp mà một tiến trình có thể mở. Thực tế có hai giá trị cần xem xét khi bạn điều chỉnh con số này. Một là giá trị mà nó hiện được đặt thành hoặc bạn đang cố gắng đặt nó thành. Đây được gọi là giới hạn mềm. Cũng có giới hạn cứng và đây là giá trị cao nhất mà bạn có thể nâng giới hạn mềm lên.

Cách nghĩ về điều này là giới hạn mềm thực sự là "giá trị hiện tại" và giới hạn trên là giá trị cao nhất mà giá trị hiện tại có thể đạt tới. Người dùng thông thường, không root, có thể tăng giới hạn mềm của họ lên bất kỳ giá trị nào lên đến giới hạn cứng của họ. Người dùng root có thể tăng giới hạn cứng của họ.

Để xem các giới hạn mềm và cứng hiện tại, hãy sử dụng ulimit các tùy chọn -S (mềm) và -H (cứng) và -n tùy chọn (mở tệp).

Mã nguồn [Chọn]
ulimit -Sn
Mã nguồn [Chọn]
ulimit -Hn

Để tạo tình huống mà chúng tôi có thể thấy giới hạn mềm đang được thực thi, chúng tôi đã tạo một chương trình mở tệp liên tục cho đến khi không thành công. Sau đó, nó chờ một lần nhấn phím trước khi từ bỏ tất cả các tệp xử lý mà nó đã sử dụng. Chương trình được gọi là open-files.

Mã nguồn [Chọn]
./open-Files

Nó mở được 1021 tệp và không thành công khi cố mở tệp 1022.

1024 trừ 1021 bằng 3. Điều gì đã xảy ra với ba phần xử lý tệp còn lại? Chúng được sử dụng cho các luồng STDIN, STDOUT, vàSTDERR. Chúng được tạo tự động cho mỗi quy trình. Chúng luôn có các giá trị mô tả tệp là 0, 1 và 2.

Chúng ta có thể thấy những điều này bằng cách sử dụng lệnh với lsof tùy chọn -p (process) và ID tiến trình của open-files chương trình. Một cách thuận tiện, nó in ID tiến trình của nó ra cửa sổ terminal.

Mã nguồn [Chọn]
lsof -p 11038

Tất nhiên, trong tình huống thực tế, bạn có thể không biết quy trình nào vừa xử lý tất cả các phần xử lý tệp. Để bắt đầu điều tra, bạn có thể sử dụng chuỗi lệnh theo đường dẫn này. Nó sẽ cho bạn biết 15 người dùng xử lý tệp nhiều nhất trên máy tính của bạn.

Mã nguồn [Chọn]
lsof | awk '{ print $1 " " $2; }' | sort -rn | uniq -c | sort -rn | head -15

Để xem nhiều hay ít mục, hãy điều chỉnh -15 tham số cho head lệnh. Khi bạn đã xác định được quy trình, bạn cần tìm hiểu xem liệu nó có bị lừa đảo và đang mở quá nhiều tệp vì nó nằm ngoài tầm kiểm soát hay liệu nó có thực sự cần những tệp đó hay không. Nếu nó cần chúng, bạn cần tăng giới hạn xử lý tệp của nó.

3. Cách tăng giới hạn mềm

Nếu chúng ta tăng giới hạn mềm và chạy lại chương trình, chúng ta sẽ thấy nó mở được nhiều tệp hơn. Chúng tôi sẽ sử dụng ulimitlệnh và -ntùy chọn (mở tệp) với giá trị số là 2048. Đây sẽ là giới hạn mềm mới.

Mã nguồn [Chọn]
ulimit -n 2048

Lần này chúng tôi đã mở thành công 2045 tệp. Đúng như mong đợi, con số này nhỏ hơn ba lần so với năm 2048, do các phần xử lý tệp được sử dụng cho STDIN, STDOUTvà STDERR.

4. Cách thay đổi vĩnh viễn giới hạn tệp

Việc tăng giới hạn mềm chỉ ảnh hưởng đến lớp vỏ hiện tại. Mở một cửa sổ terminal mới và kiểm tra giới hạn mềm. Bạn sẽ thấy đó là giá trị mặc định cũ. Nhưng có một cách để đặt một giá trị mặc định mới trên toàn cầu cho số lượng tệp đang mở tối đa mà một quy trình có thể có, đó là giá trị liên tục và vẫn tồn tại sau khi khởi động lại.

Lời khuyên lỗi thời thường khuyên bạn nên chỉnh sửa các tệp như "/etc/sysctl.conf" và "/etc/security/limits.conf." Tuy nhiên, trên các bản phân phối dựa trên systemd, những chỉnh sửa này không hoạt động ổn định, đặc biệt đối với các phiên đăng nhập đồ họa.

Kỹ thuật được hiển thị ở đây là cách thực hiện điều này trên các bản phân phối dựa trên systemd. Có hai tập tin chúng ta cần làm việc với. Đầu tiên là tệp "/etc/systemd/system.conf". Chúng ta sẽ cần sử dụng sudo.

Mã nguồn [Chọn]
sudo gedit /etc/systemd/system.conf

Tìm kiếm dòng chứa chuỗi "DefaultLimitNOFILE." Xóa hàm băm "#" khỏi đầu dòng và chỉnh sửa số đầu tiên thành bất cứ điều gì bạn muốn giới hạn mềm mới cho các quy trình. Chúng tôi chọn 4096. Số thứ hai trên dòng đó là giới hạn cứng. Chúng tôi đã không điều chỉnh điều này.


Lưu tệp và đóng trình chỉnh sửa.

Chúng ta cần lặp lại thao tác đó trên tệp "/etc/systemd/user.conf".

Mã nguồn [Chọn]
sudo gedit /etc/systemd/user.conf

Thực hiện các điều chỉnh tương tự cho dòng chứa chuỗi "DefaultLimitNOFILE."


Lưu tệp và đóng trình chỉnh sửa. Bạn phải khởi động lại máy tính của mình hoặc sử dụng systemctllệnh với daemon-reexectùy chọn để lệnh systemdđược thực thi lại và nhập các cài đặt mới.

Mã nguồn [Chọn]
sudo systemctl daemon-reexec

Mở cửa sổ terminal và kiểm tra giới hạn mới sẽ hiển thị giá trị mới bạn đặt. Trong trường hợp của chúng tôi đó là 4096.

Mã nguồn [Chọn]
ulimit -n

Chúng tôi có thể kiểm tra đây có phải là giá trị hoạt động trực tiếp bằng cách chạy lại chương trình tham lam tệp của chúng tôi hay không.

Mã nguồn [Chọn]
./open-Files

Chương trình không mở được tệp số 4094, nghĩa là 4093 tệp đã được mở. Đó là giá trị mong đợi của chúng tôi, 3 nhỏ hơn 4096.

Hãy nhớ rằng mọi thứ đều là một tập tin. Đó là lý do tại sao Linux phụ thuộc nhiều vào việc xử lý tập tin. Bây giờ, nếu bạn bắt đầu dùng hết chúng, bạn sẽ biết cách tăng hạn ngạch của mình.