Единый процесс Erlang, потребляющий больше памяти и запускающий сигнализацию высокого уровня

У меня есть erlang gen_server, который получает сообщения от клиентов асинхронно (используя приведение). При каждой обработке сообщений сервер вставляет их в упорядоченную таблицу ETS и удаляет некоторые из них в зависимости от условий (из-за условного удаления число записей в таблице ETS в большинстве случаев составляет около 5000. Но редко сценарии, которые могут увеличить этот размер до 200 КБ, вводя накладные расходы как для вставки, так и для удаления).

Это работает нормально до тех пор, пока количество сообщений в секунду не достигнет 100 Кб, но выше этого уровня я получаю максимальный уровень памяти для памяти процесса и начинает потреблять много памяти. Когда я закомментирую вставку и удаляю часть для упорядоченных ets, она может обрабатывать более 100 Кб в секунду. Можете ли вы дать мне несколько советов, как решить эту проблему?

Существует ли максимальный предел памяти, который может выделить процесс? Я использую 35 ГБ памяти, и я устанавливаю порог водяного знака с помощью memsup:set_procmem_high_watermark(0.6), Я также попробовал gbtree и заказал словарь, но они не решили ошибку памяти.

2 ответа

У меня есть предложение. Когда скорость превышает 100 кбит / с, gen_server не может вовремя обработать очередь сообщений, поэтому он начинает расти => gen_server замедляется и происходит утечка памяти. Попробуй контролировать erlang:process_info(Pid, message_queue_len) если он растет.

Предел памяти процесса

Там нет такой опции в Эрланге. memsup:set_procmem_high_watermark/1 просто устанавливает порог для выделения памяти процесса. Если порог пройден, сигнал тревоги будет поднят.

В чем может быть причина проблемы?

В начале вы должны выяснить, почему ваш процесс замедляется. Как уже говорилось, проверьте характеристики своей очереди сообщений: растет ли она со временем? Если это так, ваш процесс не может обрабатывать сообщения с той скоростью, с которой они приходят. erlang:process_info/2 будет полезно

Еще одна вещь, которую нужно иметь в виду, - когда вы вставляете / просматриваете данные в ETS, объекты копируются. Таким образом, если условия, которые должны выполняться при удалении объектов, связаны с извлечением данных из ETS, это также может быть причиной вашей проблемы.

Как справиться с этим?

Есть несколько способов решения этой проблемы. Очевидным является простое использование механизма противодействия, например, чтобы клиенты отправляли сообщения синхронно.

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

Наконец, вы можете попытаться применить некоторую оптимизацию в отношении вашего ETS. Например, если вы храните большие объекты, вы можете проверить, не возвращаете ли вы их без необходимости (используя ets:lookup/X вместо ets:match/X или же ets:match_object/X чтобы получить именно те биты, которые вы хотите из сохраненного сообщения).

Другие вопросы по тегам