Наша система постепенно увеличивала объем памяти. После того, как было выполнено слишком много отладок с профилировщиками, точная проблема не дошла. Теперь, после проверки случайных вещей в системе, она оказалась в углу используемых нами веб-сокетов.
В этих сокетах было много непрочитанных сообщений в своей очереди. Использование памяти было прямо пропорционально количеству сообщений. При очистке сообщений в очереди была восстановлена огромная память.
Проблема:
Протестированная версия ОС: 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 сокетов), и была восстановлена огромная память.
=============================== ==============================================
Теперь мой понимание:
Реальная проблема, с которой мы столкнулись на наших серверах: объем памяти постоянно рос, машина начала использовать пространство подкачки и замедлилась. Теперь, запустив тестовые программы, я понял, что свободного места на наших серверах недостаточно для хранения до момента уплотнения.
Мои вопросы:
Является ли это сжатие встроенным поведением буферов сокетов?
Если да, когда это произойдет, на машине 2 у меня был другой опыт, чем на компьютере 1? Какое значение должно быть настроено на раннее сжатие?
Значение "mem" в sockstat и сумма значений "r" в ss складываются, чтобы дать общую память, занятую сокетом? Или это одинаковые значения, перечисленные разными инструментами.
(Согласно моим тестам, (значение mem sockstat + значение буфера skmem) равно освобождению памяти.)