Tránh xé nát ứng dụng hết bộ nhớ linux


34

Đôi khi tôi thấy rằng hộp Linux của tôi hết bộ nhớ và nó bắt đầu phá vỡ các quy trình ngẫu nhiên để xử lý nó.

Tôi tò mò không biết quản trị viên làm gì để tránh điều này? Là giải pháp thực sự duy nhất để tăng dung lượng bộ nhớ (sẽ tăng trợ giúp trao đổi một mình?), Hay có cách nào tốt hơn để thiết lập hộp với phần mềm để tránh điều này? (tức là hạn ngạch, hoặc một số như vậy?).


Tôi đã tìm thấy câu trả lời ở đây: serverfault.com/questions/362589/ Phản hồi của Patrick rất mang tính hướng dẫn
Amaury

Câu trả lời:


44

Theo mặc định, Linux có một khái niệm quản lý bộ nhớ bị tổn thương não bộ: nó cho phép bạn phân bổ nhiều bộ nhớ hơn hệ thống của bạn, sau đó bắn ngẫu nhiên một quá trình vào đầu khi gặp sự cố. (Các ngữ nghĩa thực tế của những gì bị giết còn phức tạp hơn thế - Google "Linux OOM Killer" cho rất nhiều chi tiết và tranh luận về việc đó là điều tốt hay xấu).


Để khôi phục một số giá trị tinh thần cho việc quản lý bộ nhớ của bạn:

  1. Vô hiệu hóa OOM Killer (Đặt vm.oom-kill = 0trong /etc/sysctl.conf)
  2. Vô hiệu hóa bộ nhớ quá mức (Đặt vm.overcommit_memory = 2trong /etc/sysctl.conf)
    Lưu ý rằng đây là giá trị nhị phân: 0 = "ước tính nếu chúng tôi có đủ RAM", 1 = "Luôn luôn nói có", 2 = "nói không nếu chúng tôi không có bộ nhớ ")

Các cài đặt này sẽ khiến Linux hoạt động theo cách truyền thống (nếu một quy trình yêu cầu nhiều bộ nhớ hơn so với malloc () sẽ thất bại và quá trình yêu cầu bộ nhớ dự kiến ​​sẽ đối phó với thất bại đó).

Khởi động lại máy của bạn để làm cho nó tải lại /etc/sysctl.confhoặc sử dụng prochệ thống tệp để bật ngay mà không cần khởi động lại:

echo 2 > /proc/sys/vm/overcommit_memory 

11
Không phải Linux được phát triển mạnh, mà là các lập trình viên phân bổ bộ nhớ, không bao giờ sử dụng nó. Máy ảo Java nổi tiếng với điều này. Tôi, với tư cách là quản trị viên quản lý các máy chủ chạy các ứng dụng Java sẽ không tồn tại được một giây mà không gặp sự cố.
Aleksandar Ivanisevic

11
Các lập trình viên Java không phân bổ bộ nhớ không sử dụng, không có malloc trong java. Tôi nghĩ rằng bạn đang nhầm lẫn điều này với các cài đặt JVM như -Xms. Trong mọi trường hợp, tăng kích thước bộ nhớ ảo bằng cách thêm không gian hoán đổi là một giải pháp an toàn hơn nhiều so với quá mức.
jlliagre

5
Lưu ý rằng giải pháp này sẽ không ngăn hệ thống của bạn hết bộ nhớ hoặc giết quá trình. Nó sẽ chỉ đưa bạn trở lại hành vi Unix truyền thống, trong đó nếu một quá trình ăn hết bộ nhớ của bạn thì hành vi tiếp theo cố gắng malloc sẽ không gặp phải bất kỳ sự cố nào (và rất có thể là sự cố). Nếu bạn không may mắn rằng quy trình tiếp theo là init (hoặc một cái gì đó quan trọng), mà OOM Killer thường tránh.
pehrs

8
jlliagre, tôi đã nói máy ảo Java (Máy ảo), không phải chương trình Java, mặc dù từ góc độ quản trị viên là như nhau :)
Aleksandar Ivanisevic

8
Có lẽ đáng nói ở đây là việc thêm vào những điều trên /etc/sysctl.confcó thể sẽ chỉ có hiệu lực trong lần khởi động lại tiếp theo; nếu bạn muốn thực hiện thay đổi giờ đây bạn nên sử dụng các sysctllệnh với quyền root ví dụsudo sysctl vm.overcommit_memory=2
nickgrim


3

Câu trả lời ngắn, cho một máy chủ, là mua và cài đặt thêm RAM.

Một máy chủ thường xuyên gặp phải lỗi OOM (Out-Of-Memory) thường xuyên , sau đó bên cạnh tùy chọn sysctl của trình quản lý VM (bộ nhớ ảo) trong các nhân Linux, đây không phải là một điều tốt.

Giảm số lượng trao đổi (bộ nhớ ảo đã được phân phối ra đĩa bởi trình quản lý bộ nhớ của kernel) sẽ giúp ích nếu các giá trị hiện tại thấp và việc sử dụng liên quan đến nhiều tác vụ mỗi lượng bộ nhớ lớn như vậy, thay vì một hoặc một vài xử lý mỗi yêu cầu một lượng lớn tổng bộ nhớ ảo có sẵn (RAM + trao đổi).

Đối với nhiều ứng dụng phân bổ nhiều hơn hai lần (2 lần) dung lượng RAM khi trao đổi mang lại lợi tức giảm dần khi cải thiện. Trong một số mô phỏng tính toán lớn, điều này có thể được chấp nhận nếu tốc độ chậm lại có thể chịu được.

Với RAM (ECC hoặc không) có giá cả khá phải chăng cho số lượng khiêm tốn, ví dụ 4-16 GB, tôi phải thừa nhận, bản thân tôi đã không gặp phải vấn đề này trong một thời gian dài.

Những điều cơ bản để xem xét mức tiêu thụ bộ nhớ bao gồm sử dụng freetop, được sắp xếp theo mức sử dụng bộ nhớ, như hai đánh giá nhanh phổ biến nhất về các kiểu sử dụng bộ nhớ. Vì vậy, hãy chắc chắn rằng bạn hiểu ý nghĩa của từng trường trong đầu ra của các lệnh đó ít nhất.

Không có thông tin cụ thể về ứng dụng (ví dụ: cơ sở dữ liệu, máy chủ dịch vụ mạng, xử lý video thời gian thực) và cách sử dụng của máy chủ (ít người dùng, 100-1000 kết nối người dùng / khách hàng), tôi không thể nghĩ ra bất kỳ đề xuất chung nào liên quan đến việc xử lý vấn đề OOM.


3

Tăng số lượng bộ nhớ vật lý có thể không phải là một phản ứng hiệu quả trong mọi trường hợp.

Một cách để kiểm tra điều này là lệnh 'trên đỉnh'. Riêng hai dòng này.

Đây là máy chủ khi nó khỏe mạnh:

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 |

Khi nó hoạt động kém (và trước khi chúng tôi điều chỉnh overcommit_memory từ 50 đến 90, chúng tôi sẽ thấy hành vi với vmcom chạy tốt hơn 50G, oom-killer thổi lên các quy trình cứ sau vài giây và tải vẫn bị dội lên do các quá trình con của NFSd bị thổi bay lên và tái tạo liên tục.

Gần đây, chúng tôi đã sao chép các trường hợp máy chủ đầu cuối Linux nhiều người dùng cam kết quá mức phân bổ bộ nhớ ảo nhưng rất ít trang được yêu cầu thực sự được sử dụng.

Mặc dù không nên theo lộ trình chính xác này, chúng tôi đã điều chỉnh bộ nhớ quá mức từ 50 đến 90 mặc định để giảm bớt một số vấn đề. Cuối cùng chúng tôi đã phải chuyển tất cả người dùng sang một máy chủ đầu cuối khác và khởi động lại để thấy toàn bộ lợi ích.


2

Bạn có thể sử dụng ulimit để giảm dung lượng bộ nhớ mà một quy trình được phép yêu cầu trước khi nó bị giết. Sẽ rất hữu ích nếu vấn đề của bạn là một hoặc một vài quy trình chạy khỏi máy chủ của bạn.

Nếu vấn đề của bạn là đơn giản là bạn không có đủ bộ nhớ để chạy các dịch vụ bạn cần thì chỉ có ba giải pháp:

  1. Giảm bộ nhớ được sử dụng bởi các dịch vụ của bạn bằng cách hạn chế bộ nhớ cache và tương tự

  2. Tạo một vùng trao đổi lớn hơn. Nó sẽ chi phí bạn trong hiệu suất, nhưng có thể mua cho bạn một thời gian.

  3. Mua thêm bộ nhớ


0

Tôi gặp vấn đề tương tự liên quan đến lỗi này và giải pháp là sử dụng kernel cũ hơn / mới hơn (đã sửa).

Tuy nhiên, tại thời điểm đó tôi không thể khởi động lại máy của mình, vì vậy một số cách giải quyết xấu xí là đăng nhập với quyền root và xóa bộ đệm hệ thống bằng lệnh này:

echo 3 > /proc/sys/vm/drop_caches

-5

@ voretaq7 linux không có khái niệm quản lý bộ nhớ bị tổn thương não, theo mặc định vm.overcommit_ratio là 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.

Theo cách này, nếu bạn có 4GB ram và bạn cố gắng phân bổ 4.2 GB với malloc bộ nhớ ảo, việc phân bổ của bạn sẽ thất bại.

Với 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.

Với 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.

Vì vậy, theo mặc định linux không quá quan trọng, nếu ứng dụng của bạn có nhiều bộ nhớ hơn thì có thể mã của bạn bị lỗi


2
Bạn đã mâu thuẫn với chính mình ở đây. Ở đầu bạn nói "theo mặc định vm.overcommit_ratio là 0" và sau đó ở phía dưới bạn nói "theo mặc định linux không quá quan trọng". Nếu điều sau là đúng, vm.overcommit_ratio sẽ là 2 theo mặc định!
Michael Hampton

vm.overcommit_ratio = 0, malloc không phân bổ bộ nhớ nhiều hơn ram vật lý của bạn, vì vậy đối với tôi điều đó có nghĩa là không quá quan trọng, overcommit là khi bạn có thể phân bổ ảo nhiều hơn ram vật lý của mình
c4f4t0r

2
Vâng, bạn đã hiểu lầm.
Michael Hampton

bạn đã hiểu nhầm, 0 mặc định, không phân bổ để phân bổ nhiều bộ nhớ ảo hơn ram và 2 không vượt quá cho phép vm.overcommit_ratio + không gian hoán đổi, vì vậy nếu tôi hiểu nhầm hãy cho tôi biết
c4f4t0r

2
Tất nhiên. "Rõ ràng thừa" bị từ chối. Phần còn lại trôi qua. Bạn cần đọc kỹ hơn.
Michael Hampton
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.