После перезагрузки потребление памяти постепенно увеличивается

Я не уверен, когда именно это началось, но в последние несколько недель, предположительно после обновления Discourse, сайт начал работать немного медленнее. Мы используем версию 3.4.0.beta2-dev.

Я заметил, что на сервере почти не осталось свободной памяти, поэтому перезагрузил его. После запуска Discourse использование памяти сначала было в норме (около 1,2 ГБ), но затем начало постепенно расти, и, похоже, скоро достигнет уровня, при котором сайт снова начнёт тормозить.

Сайт не отличается высокой активностью (20–30 посетителей в день) и работал без проблем в течение многих лет, пока недавно не возникли трудности.

У сервера 2 ГБ оперативной памяти, что, согласно требованиям, которые я видел (минимум 1 ГБ, рекомендуется 2 ГБ), должно быть достаточно.

Мне это кажется утечкой памяти. Конечно, если утечка есть, она может быть не в Discourse, а в Docker или чём-то другом. Этот сервер используется только для Discourse.

Есть ли какие-то идеи? Можно ли проверить, что это действительно утечка, и определить процесс, который её вызывает?

Свободная память — понятие очень зыбкое; единственный верный признак её нехватки — активность подкачки.

free
или
free -h
дадут вам снимок состояния.

vmstat 5 5
очень полезен для отслеживания происходящего, включая активность подкачки.

Mem:          1.9Gi       1.5Gi        73Mi
Swap:         2.0Gi        54Mi       1.9Gi
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  55524 111624  20080 385060    1    3    68    52  965  349  4  2 93  1  0
 0  0  55524 114884  20088 385152    0    0    13     8 1047  352  2  1 96  0  0
 0  0  55524 112428  20088 385160    0    0     0     3  831  319  3  1 95  0  0
 0  0  55524 111616  20096 385164    0    0     0    51  688  278  2  0 97  0  0
 0  0  55524 109884  20104 385168    0    0     0     8 1117  281  2  1 96  0  1

Кажется ли вам что-либо из вышеперечисленного проблемным? Я получаю данные об использовании памяти из HTOP, которые, как мне кажется, совпадают с данными FREE.

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

Конечно, на данный момент всё выглядит нормально — нет активности в si и so (страничная подкачка), а также очень мало трафика диска (bi и bo).

В Linux свободная память используется для кэширования диска, поэтому не стоит беспокоиться, если показатель свободной памяти снижается. Вывод команды free показывает доступную оперативную память. Согласно странице руководства (man page):

available
Оценка того, сколько памяти доступно для запуска новых приложений без использования подкачки.

В случае с vmstat столбцы buff и cache показывают память, используемую для кэширования диска. Она может увеличиваться для улучшения производительности ввода-вывода, но уменьшаться при нехватке памяти. Таким образом, для обеих утилит (free и vmstat) показатель ‘free’ является пессимистичной оценкой.

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

Всё ещё возможно, что что-то постепенно увеличивается.

Одна из моих тактик для понимания того, что происходит:

# ps aux|sort -n +5|tail
systemd+    1659  0.0  1.3 904384 54588 ?        S    16:44   0:00 /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main
root         830  0.0  1.6 2253324 65208 ?       Ssl  16:44   0:01 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
systemd+    1682  0.0  1.9 904516 78092 ?        Ss   16:44   0:01 postgres: 13/main: checkpointer 
systemd+   18757  0.1  2.1 912368 85644 ?        Ss   18:06   0:00 postgres: 13/main: discourse discourse [local] idle
1000        1688  0.1  6.5 1006548 256428 ?      Sl   16:44   0:10 unicorn master -E production -c config/unicorn.conf.rb
1000        2189  0.1  8.5 5657760 333248 ?      Sl   16:45   0:06 unicorn worker[3] -E production -c config/unicorn.conf.rb
1000        2113  0.1  8.5 5656608 334352 ?      Sl   16:45   0:07 unicorn worker[2] -E production -c config/unicorn.conf.rb
1000        2044  0.4  8.7 6052196 342380 ?      Sl   16:44   0:23 unicorn worker[1] -E production -c config/unicorn.conf.rb
1000        2006  1.7  9.0 5628640 352492 ?      Sl   16:44   1:33 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  3.1 11.1 6033652 435388 ?      SNl  16:44   2:54 sidekiq 6.5.12 discourse [0 of 5 busy]

(или ps auxc)

Если легко отслеживать активность процессора и (дискового) ввода-вывода, я рекомендую следить за ними, а не за использованием памяти. Особенно за вводом-выводом. Если загрузка процессора низкая, а активность ввода-вывода высокая, и форум работает медленно, это может указывать на критическую нехватку оперативной памяти.

Несколько причин, помимо ошибок в коде, по которым сайт может замедляться: одна из них — постепенный рост числа пользователей, активности пользователей и размера базы данных; другая — постоянное увеличение размера Discourse по мере его развития, добавления новых функций и обновления программных компонентов.

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

(Кстати, я заметил, что сейчас самая дешёвая машина у Hetzner имеет 4 ГБ ОЗУ по той же цене, что и ранее недоступная самая дешёвая машина с 2 ГБ ОЗУ. Один из моих сайтов всё ещё работает на старом варианте с 2 ГБ.)

Для полноты картины, поскольку я отслеживаю использование ресурсов моего основного сайта, который недавно был мигрирован на новый сервер с только что выполненной перезагрузкой, приведу некоторые данные. Их довольно много — не обязательно изучать всё подробно!

Текущее состояние машины:

# uptime
 13:55:23 up 4 days, 21:10,  1 user,  load average: 0.07, 0.08, 0.02
# free
               total        used        free      shared  buff/cache   available
Mem:         3905344     1638012       98492      481864     2168840     1595004
Swap:        4194288      252928     3941360

Обратите внимание, что при входе система сообщает:
Memory usage: 45%
что наиболее точно отражает столбец ‘used’, а не ‘free’.

Я периодически выполнял следующие команды:

   date
   uptime
   free
   ps aux|sort -n +5|tail
   vmstat 5 5

И то, что я наблюдал, — это то, что свободная память (‘free’) постепенно использовалась для буферов (‘buffer’) и кэша (‘cache’), без увеличения потребления оперативной памяти процессами (RSS). Это, на мой взгляд, показывает, почему не стоит ориентироваться на показатель ‘free’ памяти, даже если некоторые хостинг-провайдеры делают его легко доступным. Также это, в данном случае, указывает на отсутствие утечек памяти.

Сразу после перезагрузки я видел следующее:

# free
               total        used        free      shared  buff/cache   available
Mem:         3905344     1560508      996400      179712     1348436     1974692
Swap:        4194288           0     4194288

А вскоре после этого:

# ps aux|sort -n +5|tail
...
1000        1688  0.1  6.5 1006548 256428 ?      Sl   16:44   0:10 unicorn master -E production -c config/unicorn.conf.rb
1000        2189  0.1  8.5 5657760 333248 ?      Sl   16:45   0:06 unicorn worker[3] -E production -c config/unicorn.conf.rb
1000        2113  0.1  8.5 5656608 334352 ?      Sl   16:45   0:07 unicorn worker[2] -E production -c config/unicorn.conf.rb
1000        2044  0.4  8.7 6052196 342380 ?      Sl   16:44   0:23 unicorn worker[1] -E production -c config/unicorn.conf.rb
1000        2006  1.7  9.0 5628640 352492 ?      Sl   16:44   1:33 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  3.1 11.1 6033652 435388 ?      SNl  16:44   2:54 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0      0 866112 314288 1083816    0    0    32    28  484  621  4  1 95  0  0

Как видно, sidekiq (435 МБ) и процессы unicorn (по 330–350 МБ каждый) являются самыми крупными.

Со временем свободная ОЗУ, а затем и потребление памяти sidekiq (RSS) уменьшаются, вероятно, из-за выгрузки страниц, но без негативных последствий — машина не показывает никакой активности по выгрузке страниц. Это, по моему мнению, происходит в пользу увеличения пространства для буферов и кэша.

# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0      0 679764 326988 1190840    0    0     0    11  285  396  1  1 98  0  0

Примерно через 14 часов:

# uptime
 10:12:06 up 17:27,  1 user,  load average: 0.04, 0.02, 0.00
# ps aux|sort -n +5|tail
...
1000        2006  1.2  9.6 5647908 377424 ?      Sl   Sep05  12:42 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  1.8 11.3 6431988 444184 ?      SNl  Sep05  18:51 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0   2048 199972 342480 1576156    0    0     0    17  361  511  2  2 96  0  0

Позже…

# uptime
 19:52:00 up 1 day,  3:07,  1 user,  load average: 0.02, 0.06, 0.01
# ps aux|sort -n +5|tail
...
1000        2006  1.2  9.8 5654308 382944 ?      Sl   Sep05  20:44 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  1.5 11.1 6431668 436340 ?      SNl  Sep05  25:04 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0   2304 103356 301632 1690136    0    0     0    10  360  511  1  1 98  0  0

Ещё позже…

# uptime
 12:13:09 up 1 day, 19:28,  2 users,  load average: 0.05, 0.06, 0.01
# ps aux|sort -n +5|tail
...
1000        2006  1.2  9.1 5654820 358612 ?      Sl   Sep05  31:47 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  1.3 10.0 6431668 393584 ?      SNl  Sep05  35:08 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0 284416 281596  77904 1908528    0    0     0    38  315  450  1  1 98  0  0

Ещё позже

# uptime
 13:26:42 up 2 days, 20:42,  1 user,  load average: 0.20, 0.06, 0.02
# ps aux|sort -n +5|tail
...
1000        2006  1.2  9.3 5789072 365720 ?      Sl   Sep05  51:54 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  1.2 10.0 6433332 393472 ?      SNl  Sep05  50:44 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0 242944  82016  95188 2082180    0    0     0   131  332  488  1  1 98  0  0

Ещё позже

# uptime
 09:21:33 up 3 days, 16:36,  1 user,  load average: 0.13, 0.10, 0.03
# free
               total        used        free      shared  buff/cache   available
Mem:         3905344     1618936      323032      476664     1963376     1619208
Swap:        4194288      250112     3944176
# ps aux|sort -n +5|tail
...
1000        2006  1.2  9.3 5789200 363572 ?      Sl   Sep05  67:02 unicorn worker[0] -E production -c config/unicorn.conf.rb
1000        1971  1.1  9.6 6433652 377472 ?      SNl  Sep05  63:14 sidekiq 6.5.12 discourse [0 of 5 busy]
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 0  0 250112 321888  56052 1906672    0    0     2    13  293  420  1  0 99  0  0

Ещё позже

# uptime
 13:55:23 up 4 days, 21:10,  1 user,  load average: 0.07, 0.08, 0.02
# free
               total        used        free      shared  buff/cache   available
Mem:         3905344     1638012       98492      481864     2168840     1595004
Swap:        4194288      252928     3941360
# ps aux|sort -n +5|tail
...
1000        1971  1.1  9.5 6434676 371648 ?      SNl  Sep05  80:49 sidekiq 6.5.12 discourse [0 of 5 busy]
1000        2006  1.2  9.5 5658468 373404 ?      Sl   Sep05  88:44 unicorn worker[0] -E production -c config/unicorn.conf.rb
# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
...
 1  0 252928 101040  86736 2082372    0    0     0    10  333  482  1  0 99  0  0

Спасибо за ваши наблюдения. У меня наблюдается практически то же самое, за исключением того, что мы используем экземпляр с 2 ГБ памяти, поэтому запас прочности меньше. Также спасибо за то, что указали, что некоторые показатели «свободной» и «используемой» памяти не всегда информативны.

Когда я последний раз перезагружал экземпляр несколько дней назад, начальное использование памяти составляло 1,23 ГБ. С тех пор оно постепенно росло и сейчас достигло 1,8 ГБ. Сайт пока остаётся достаточно отзывчивым.

На самом деле у сайта не так много пользователей, и в последнее время не было роста в количестве регистраций или активности. За последний месяц было создано около 20 новых тем, опубликовано около 100 сообщений, и ежедневно активно около 4 пользователей.

Я продолжу следить за ситуацией и напишу здесь, если память экземпляра снова будет исчерпана, сайт снова начнёт работать медленно или произойдёт и то, и другое.

Обновление Discourse превращалось в рутину из-за проблем с памятью, поэтому мы наконец увеличили объем виртуальной машины с 2 ГБ до 4 ГБ. С тех пор использование памяти стабилизировалось.