netch80: (Default)
[personal profile] netch80
Период смешных ошибок с неожиданными последствиями.

Не моя: в pidfile пишется просто число - PID, ничем не терминируется, файл предварительно (или после) не зачищается. Работало под pid=12347, запущен новый с pid=3642, в pidfile оказалось 36427.

Моя: в кластере живут данные, реплицирующиеся между нодами, но функция вычистки устаревших данных не доработана. Запускается узел, пытается одновременно добавить новую запись истории о своём запуске и синхронизироваться с остальными, умирает под тяжестью данных и приложений (не хватает виртуальной памяти), но остальные, кто ещё жив, запомнили этот запуск. Запускается заново, ещё добавляет, снова умирает... Когда нашли и идентифицировали проблему, уже вычитка базы с другого узла оказывалась слишком тяжёлой и рвала синхронизацию в кластере. Пришлось полностью погасить сервис динамических данных, чтобы остановить размножение мусора.

Пока не знаю, какие выводы тут делать.

Date: 2012-08-22 09:39 am (UTC)
From: [identity profile] dadv.livejournal.com
Выводы, imho, очевидны - при создании pidfile не использовать самосочиненного кода, вместо этого юзать готовые отлаженные библиотечки типа pidfile(3) с его pidfile_open() сотоварищи.

По проблеме умирания по исчерпанию виртуальной памяти вспомнить метод, использовавшийся ещё в TurboVision под DOS, когда во время старта резервируется неиспользуемый буфер памяти небольшого размера и при исчерпании памяти буфер этот используется как свободная динамическая память для завершающих действий.

Date: 2012-08-22 12:12 pm (UTC)
From: [identity profile] netch80.livejournal.com
> когда во время старта резервируется неиспользуемый буфер памяти небольшого размера и при исчерпании памяти буфер этот используется как свободная динамическая память для завершающих действий.

Осталось ядро Linux научить этому. А то сейчас "не кран надо менять, а всю систему"

Date: 2012-08-22 12:14 pm (UTC)
vitus_wagner: My photo 2005 (white)
From: [personal profile] vitus_wagner
echo 1 > /proc/sys/vm/overcommit_memory
не сойдет за "обучить"?

Date: 2012-08-22 12:24 pm (UTC)
From: [identity profile] dadv.livejournal.com
Ядро Linux не умеет лимиты?

Date: 2012-08-22 02:53 pm (UTC)
From: [identity profile] netch80.livejournal.com
При чём тут лимиты? Учить надо тому, что есть резерв памяти, который автоматически вводится при недостатке основной, но при этом начинается аккуратное свёртывание.

Date: 2012-08-22 02:56 pm (UTC)
From: [identity profile] dadv.livejournal.com
Лимиты при сведении задачи из kernel land в user land. Чтобы в момент X ядро не давало по голове процесса OOM-killer'ом, а просто возвращало ошибку в ответ на запрос памяти. А приложение уже научить тому, чтобы делало себе лимит памяти и аккуратно свертывалось.

Date: 2012-08-23 04:38 am (UTC)
From: [identity profile] netch80.livejournal.com
Ты тоже уже всё забыл. А ведь обсуждали и при тебе:

http://groups.google.com/group/fido7.ru.unix.prog/browse_thread/thread/551b8b584a43ea6c/d2032971ec69a1e8

Проблема в том, что "сделать себе лимит памяти" требует специального ядерного механизма, которого не дают.

Date: 2012-08-23 04:56 am (UTC)
From: [identity profile] dadv.livejournal.com
Весь тред перечитывать некогда, перечитал первую страницу. Нужно различать две принципиально разные ситуации: OS не даёт программисту метода писать приложение так, что оно может узнать, что память кончилась и корректно завершиться/отреагировать без запроса дополнительной памяти к тому, что у него уже есть; либо OS даёт подобный метод. Если в OS не даёт методов (например, лимиты в Linux не работают?), то эта OS плохая, негодная для твоей задачи и её надо либо чинить (патчить), либо менять. Если даёт методы, надо ими активно пользоваться.

На фре есть RLIMIT_VMEM (vmemoryuse): /* virtual process size (inclusive of mmap) */, оно же RLIMIT_AS (это же имя упоминалось в контексте линукса в обсуждении в ru.unix.prog).

Date: 2012-08-29 08:24 am (UTC)
From: [identity profile] netch80.livejournal.com
> Весь тред перечитывать некогда, перечитал первую страницу.

Видимо, плохо прочитал. Потому что суть как раз проигнорировал.

> Если в OS не даёт методов (например, лимиты в Linux не работают?)

При чём тут вообще лимиты в нынешнем виде? Они срабатывают только при их переполнении, и уже в том месте, где попросили ресурс. А если этот запрос неявный (например, copy-on-write страницы), то и сообщить о проблеме невозможно. Надо делать так, чтобы она опознавалась заранее. А теперь покажи, как мне подсчитать лёгким образом (без залазания в /proc/$pid/), какой текущий объём VM процесса и сколько осталось до исчерпания лимита?

> Если даёт методы, надо ими активно пользоваться.

Если бы она давала методы - всё было бы хорошо. Но она ни хрена не даёт.

> На фре есть RLIMIT_VMEM

Ровно настолько же бесполезная хня.

Date: 2012-08-29 11:19 am (UTC)
From: [identity profile] dadv.livejournal.com
copy-on-write будет в память, которая предварительно аллоцирована же. Вот на это аллоцирование лимиты и действуют.

> как мне подсчитать лёгким образом (без залазания в /proc/$pid/), какой текущий объём VM процесса и сколько осталось до исчерпания лимита

Не знаю, но это не критично - когда лимит исчерпается, тебе система об этом скажет и ты просто откатишь транзакцию, используя резервную память.

Date: 2012-08-30 06:20 am (UTC)
From: [identity profile] netch80.livejournal.com
> copy-on-write будет в память, которая предварительно аллоцирована же. Вот на это аллоцирование лимиты и действуют.

Это лимиты 1 (прописью: одного) процесса. Уже лимиты группы процессов, а тем более фактический лимит всей системы, не может заранее ограничить расширение по copy-on-write.

> Не знаю, но это не критично - когда лимит исчерпается, тебе система об этом скажет и ты просто откатишь транзакцию, используя резервную память.

Отлично! Покажи мне, где этот механизм работает уже сейчас.

Date: 2012-08-30 06:41 am (UTC)
From: [identity profile] dadv.livejournal.com
> Уже лимиты группы процессов,

Зачем?

> а тем более фактический лимит всей системы, не может заранее ограничить расширение по copy-on-write.

Зачем системе иметь какой-то лимит? Своп же можно наращивать динамически, а в перспективе и RAM.

Date: 2012-08-30 06:42 am (UTC)
From: [identity profile] dadv.livejournal.com
>> Не знаю, но это не критично - когда лимит исчерпается, тебе система об этом скажет и ты просто откатишь транзакцию, используя резервную память.
> Отлично! Покажи мне, где этот механизм работает уже сейчас.

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

Date: 2012-08-23 04:42 am (UTC)
From: [identity profile] netch80.livejournal.com
А вообще, не понимаю, почему ты заговорил про проблему исчерпания виртуальной памяти.
То, о чём я рассказывал, было о другом - о подсистеме, которая замусоривает себя сама и не может без посторонней помощи (причём с большим количеством ручных действий) выйти из этого состояния.

Date: 2012-08-23 04:59 am (UTC)
From: [identity profile] dadv.livejournal.com
Ну, настучать по голове программисту подсистемы, чтобы осознал, что ресурсы не резиновые и коды ошибок надо проверять и адекватно реагировать. Можно ещё архитектору намекнуть, что архитектура созданной подсистемы неадекватна, мягко выражаясь.

Date: 2012-08-29 08:27 am (UTC)
From: [identity profile] netch80.livejournal.com
> Ну, настучать по голове программисту подсистемы, чтобы осознал, что ресурсы не резиновые и коды ошибок надо проверять и адекватно реагировать.

Представь себе, там нет кодов ошибок в этом месте! Им неоткуда взяться.

> Можно ещё архитектору намекнуть, что архитектура созданной подсистемы неадекватна, мягко выражаясь.

1. Тут вопрос не архитектуры, как ни странно.
2. Неадекватность мы уже опознали по факту. Но непонятно, как с ней бороться, сохранив общую цель работы.

Date: 2012-08-29 11:20 am (UTC)
From: [identity profile] dadv.livejournal.com
Ну как это нет кодов ошибок. Если программа не умещается в лимит, она просто не стартует.

Date: 2012-08-30 06:22 am (UTC)
From: [identity profile] netch80.livejournal.com
> Ну как это нет кодов ошибок.

Их нет.

Программа запускается, забирает у соседа данные (на это памяти ещё хватает), парсит и складывает в постоянную копию (а вот на то чтобы держать и полученное, и сохранённое - уже нет). Никаких кодов. Просто переполнение.

> Если программа не умещается в лимит, она просто не стартует.

Я не знаю, о какой программе ты говоришь, но это точно не у меня.

Date: 2012-08-30 06:45 am (UTC)
From: [identity profile] dadv.livejournal.com
> Программа запускается, забирает у соседа данные (на это памяти ещё хватает), парсит и складывает в постоянную копию (а вот на то чтобы держать и полученное, и сохранённое - уже нет). Никаких кодов. Просто переполнение.

Если мы говорим о прикладных программах, они работают с виртуальной памятью. Чтобы начать работать с такой памятью, надо сначала получить её от операционой системы. Если памяти не хватает, она вернет ошибку вместо памяти (NULL/MAP_FAILED/что там ещё). Вот тебе код.

Date: 2012-08-30 06:46 am (UTC)
From: [identity profile] dadv.livejournal.com
>> Если программа не умещается в лимит, она просто не стартует.
>Я не знаю, о какой программе ты говоришь, но это точно не у меня.

Это про limit datasize.

Date: 2012-08-23 05:09 am (UTC)
ext_605364: geg MOPO4 (geg_MOPO4)
From: [identity profile] gegmopo4.livejournal.com
Что ещё за готовые отлаженные библиотечки?

Date: 2012-08-23 05:12 am (UTC)
From: [identity profile] dadv.livejournal.com
libutil в случае FreeBSD (часть базовой системы)

Date: 2012-08-23 10:36 am (UTC)
ext_605364: geg MOPO4 (geg_MOPO4)
From: [identity profile] gegmopo4.livejournal.com
А в случае GNU/Linux?

Date: 2012-08-30 06:19 am (UTC)
From: [identity profile] dadv.livejournal.com
Тут ничего не посоветую, но почти наверняка есть.

Date: 2012-08-29 09:57 am (UTC)
From: [identity profile] netch80.livejournal.com
Вообще-то про память я имел в виду немного другое - не само поведение процесса под такой фигнёй, а как делать, чтобы не доводить до этой ситуации, потому что зловред оказался самовоспроизводящимся именно в случае тяжёлой фигни, когда и так всем хреново. Если дойдут руки (этот продукт "в загоне", по крайней мере временно), то надо будет делать какую-то умную систему типа "мы принимаем для себя только несколько последних событий о себе же, остальные пристреливаем", но это всё равно может вылиться в достаточно длительный колбасит (-ит потому что заразный, заражает соседей в пределах кластера, спасает только разрыв связей и очистка после разрыва - очень дорогой путь).

Создание аварийного выхода в случае недостатка памяти, конечно, метод полезный, но в данном случае ещё и непонятно, как его вообще тут применять.

Profile

netch80: (Default)
netch80

January 2026

S M T W T F S
    1 23
45678910
11121314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 3rd, 2026 03:39 am
Powered by Dreamwidth Studios