Как справиться с проблемами нехватки памяти в многопользовательских системах?

Когда процесс пытается выделить больше памяти, чем доступно, обычно очень трудно справиться с этой ситуацией должным образом. В некоторых случаях программы может освободить несущественную память (например, кеши), но в большинстве случаев это приведет к фатальным исключениям (см. также [1]), к подкачке и значительному замедлению системы или даже к уничтожению ( довольно произвольно), используя убийцу OOM .

В однопользовательской системе все параметры плохие, но, по крайней мере, вы можете только навредить себе (в конце концов, вы несете ответственность за весь код, запускаемый на вашем компьютере ).

Однако в многопользовательской системе можно было бы заставить убийцу OOM убить определенные процессы, возможно, принадлежащие другим пользователям. Существуют определенные ограничения, потому что убийца OOM пытается найти "процесс который использует большой объем памяти, но не так долго живет »(см. здесь ). [125 9] Тем не менее, представив ситуацию, когда процессу требуется x МБ памяти, он не существовал очень долгое время (низкое время ЦП) и принадлежит пользователю X, а x значительно превышает объем свободной памяти в системе, пользователь Y может иметь возможность выделить больше памяти, чем доступно, и заставить систему убить процесс X (потому что он использует больше памяти).

Эта ситуация звучит намного страшнее, чем аналогичные последствия для одной пользовательской машины. Можно установить ограничения памяти для каждого пользователя или даже использовать контейнеры для еще большего разделения процессов. Но насколько я понимаю, только установка лимита на total_memory / number_of_users решит проблему. Но при установке такого лимита теряются все преимущества многопользовательской системы. В этом случае машина фактически похожа на несколько однопользовательских машин в одной коробке. Обычно требуется разрешить одному пользователю использовать больше памяти в пиковое время, потому что большую часть времени пользователям потребуется меньше памяти, чем в среднем.

Меня больше всего интересует решение этой проблемы в ситуациях с большими вычислениями с огромными объемами данных. Я думаю, что в случае веб-серверов можно было бы лучше оценить, сколько памяти требуется, поскольку существует много мелких операций, а не несколько крупных. Но даже в этом случае я слышал, что в обычных ситуациях должно быть заполнено только 50% вашей памяти, чтобы избежать проблем с нехваткой памяти во время пиков. Разве это не пустая трата 50% вашей памяти?

В частности, я подумываю разместить хаб Jupyter или что-то подобное. Но я не хочу, чтобы пользователи убивали процессы друг друга.

Есть ли другое решение для смягчения этой проблемы? Как крупные облачные провайдеры, такие как Travis CI, справляются с подобными проблемами?

1
задан 11 January 2019 в 19:54
3 ответа

Tôi tin rằng ngày nay là khuyến cách để hạn chế tác động của một nhiệm vụ lên những tác vụ khác là sử dụng cgroup để giới hạn bộ nhớ mà nó có thể sử dụng. Cách dễ nhất mà tôi tìm thấy là sử dụng systemd-run . Ví dụ: điều này bắt đầu ls với giới hạn bộ nhớ thấp đến mức nực cười là 1000 byte:

sudo systemd-run --uid $USER --gid $UID -p MemoryMax=1000 ls

Chạy journalctl -f, bạn sẽ thấy quá trình đó đã bị giết ngay lập tức:

Memory cgroup out of memory: Kill process 3543 ((ls)) score 2503000 or sacrifice child
Killed process 3543 ((ls)) total-vm:205348kB, anon-rss:5612kB, file-rss:4276kB, shmem-rss:0kB

Sau đó, tất nhiên bạn sẽ muốn đăng ký máy quá mức, có thể cung cấp cho mỗi tác vụ 70% bộ nhớ khả dụng? Điều này sẽ cho phép tiêu thụ bộ nhớ cao nhất, trong khi vẫn nhanh chóng giết chết các quy trình sử dụng một lượng bộ nhớ không hợp lý.

3
ответ дан 3 December 2019 в 16:43

Отключите oom killer ( vm.oom-kill = 0 в файле, читаемом sysctl ) и отключите избыточную память ( vm .overcommit_memory = 2 ). Любой процесс, который пытается выделить больше памяти, чем доступно, будет убит. Никакой другой процесс не будет убит. Можно использовать всю память; память не тратится впустую.

Это не предотвращает потребление памяти. В контрольной группе памяти есть параметр memory.soft_limit_in_bytes , который, похоже, может быть полезным (в сочетании с memory.limit_in_bytes и memory.memsw.limit_in_bytes ), но я не нашел подробного объяснения того, как это работает.

Edit:Я смотрел, как memory.soft_limit_in_bytes используется в исходниках ядра. Если память не может быть восстановлена, ничего не происходит.

2
ответ дан 3 December 2019 в 16:43

Bạn có thể đặt sysctl vm.oom_kill_allocating_task . Khi điều này được đặt và yêu cầu bộ nhớ quy trình sẽ dẫn đến hết bộ nhớ, Linux sẽ hủy quy trình đó.

Từ tài liệu:

Điều này cho phép hoặc vô hiệu hóa việc hủy tác vụ kích hoạt OOM trong tình huống hết bộ nhớ.

Nếu điều này được đặt thành 0, kẻ giết người OOM sẽ quét toàn bộ danh sách nhiệm vụ và chọn một nhiệm vụ dựa trên kinh nghiệm để giết. Điều này bình thường chọn một tác vụ lưu trữ bộ nhớ giả mạo để giải phóng một lượng lớn bộ nhớ khi bị giết.

Nếu điều này được đặt thành khác 0, kẻ giết người OOM chỉ cần giết nhiệm vụ mà đã gây ra tình trạng hết bộ nhớ. Điều này tránh tốn kém quét danh sách tác vụ.

Nếu chọn crazy_on_oom, nó sẽ được ưu tiên hơn bất kỳ giá trị nào được sử dụng trong oom_kill_allocating_task.

Giá trị mặc định là 0.

1
ответ дан 3 December 2019 в 16:43

Теги

Похожие вопросы