Потребление памяти для сокетов в linux и поведение при сжатии - PullRequest
1 голос
/ 09 апреля 2020

Наша система постепенно увеличивала объем памяти. После того, как было выполнено слишком много отладок с профилировщиками, точная проблема не дошла. Теперь, после проверки случайных вещей в системе, она оказалась в углу используемых нами веб-сокетов.

В этих сокетах было много непрочитанных сообщений в своей очереди. Использование памяти было прямо пропорционально количеству сообщений. При очистке сообщений в очереди была восстановлена ​​огромная память.

Проблема:

Протестированная версия ОС: CentOS 7.5

  • Я попытался проверить память, занятая сокетами с использованием '/ proc / net / sockstat' в столбце mem показано, что память была ~ 300 МБ

  • Общая память для recv-Q ~ 6 МБ измерено с помощью netstat -tunp (обрабатывает числа в recv-Q как байты)

Но когда я очистил непрочитанные сообщения, я получил ~ 1,5 ГБ память восстановлена. (используя команду free )

Что-нибудь еще нужно проверить, чтобы получить правильное использование памяти для сокетов?

Это нежелательное использование памяти, сделанное linux? Как отлаживать память, используемую сокетами в дальнейшем?

Почему linux инструменты, такие как top , не перечисляют использование памяти для сокетов? Он показывает нам память для процессов, кеша и буферов, но почему бы не сокеты.

Дополнительные сведения: Изменение распределителя памяти на jemallo c не остановило этот рост памяти. Так что это не проблема, связанная с glib c.

============================== =========================================

Отредактированная информация: После выполнения некоторой работы с тестовым приложением

Преобразовал нашу задачу в простую тестовую программу и запустил ее на серверах с различными версиями ядра.

Тестовая программа: 5000 сокетов и 4 входящих сообщения (3 байта) за сообщение) в эту розетку каждую минуту. Также проделал некоторую работу по использованию ss -tm для четкого понимания поведения буферной памяти.

Машина 1: Ядро: 2.6.32 / proc / sys / net / core / rmem_max = 124928

При запуске: Free mem: 2.5gb Для каждого входящего сообщения mem в ss -tm увеличивается на 512 байт на сокет. В какой-то момент произошло внезапное падение использования памяти сокетами.

До падения памяти:

free -m: свободная память: 1.1G

sockstat : TCP: inuse 6 сирота 1 tw 161 allo c 5265 mem 114138

ss -tm: mem: ( r112784 , w0, f1904, t0)

После сброса памяти:

free -m свободной памяти: 2.3G

sockstat TCP: inuse 6 orphan 1 tw 157 allo c 5266 mem 8042

ss -tm mem: ( r9528 , w0, f952, t0)

Значения в recv-Q постоянно увеличивались с ожидаемыми значениями.

Это была точка, в которой значение «r» достигло значения, равного core / rmem_max. Похоже, там произошел процесс уплотнения.

Машина 2: Ядро: 3.10.0 / proc / sys / net / core / rmem_max = 212992

Здесь я ожидал, что память упадет на ~ 212992. Но у этой машины была обновленная версия ss, которая показала размер rb = 367360. Итак, дождался точного процесса уплотнения.

При запуске:

ss -tm: skmem: (r0, rb367360, t0, tb87040, f53248, w0, o0, bl0 )

sockstat: TCP: inuse 4 сирота 0 tw 97 allo c 5042 mem 4992

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

В точке сброса памяти 1: До сброса памяти:

свободен: свободная память: 2,1 ГБ

sockstat: TCP: inuse 4 orphan 0 tw 89 allo c 5097 mem 354398

ss -tm: skmem: (r290560, rb367360, t0, tb87040, f256, w0, o0, bl0 )

После сброса памяти:

свободен: свободная память: 3,1 ГБ

sockstat: TCP: не используется 4 сирота 0 tw 93 allo c 5099 мем 187542

приходя к ss -tm, на этот раз видел другое поведение:

50% сокетов имели сжатые значения,

skmem: (r4352, rb367360, t0, tb87040, f3840, w0, o0, bl0)

, а остальные имели действительные значения (не уплотнены)

skmem: (r291072, rb367360, t0, tb87040, f3840, w0, o0, bl0)

Таким образом, сжатие произошло незадолго до того, как значение "r" достигло "rb"

Далее, дождалось, пока значение "r" не достигло "rb"

Точка сброса памяти 2 Там произошла следующая точка падения памяти. Все буферы сокетов были сжаты (кроме 100 сокетов), и была восстановлена ​​огромная память.

=============================== ==============================================

Теперь мой понимание:

Реальная проблема, с которой мы столкнулись на наших серверах: объем памяти постоянно рос, машина начала использовать пространство подкачки и замедлилась. Теперь, запустив тестовые программы, я понял, что свободного места на наших серверах недостаточно для хранения до момента уплотнения.

Мои вопросы:

  1. Является ли это сжатие встроенным поведением буферов сокетов?

  2. Если да, когда это произойдет, на машине 2 у меня был другой опыт, чем на компьютере 1? Какое значение должно быть настроено на раннее сжатие?

  3. Значение "mem" в sockstat и сумма значений "r" в ss складываются, чтобы дать общую память, занятую сокетом? Или это одинаковые значения, перечисленные разными инструментами.

(Согласно моим тестам, (значение mem sockstat + значение буфера skmem) равно освобождению памяти.)

...