LINUX.ORG.RU
ФорумAdmin

Postgres в контейнере с ограничением по памяти

 ,


1

2

Помогите найти внятную информацию, как настроить постгрес для работы в контейнере, чтобы укладывался в целевые показатели по ограничению памяти. К примеру сейчас запустил постгрес, он скушал 90 МБ. Далее в течение нескольких дней, исходя из опыта, его потребление вырастет примерно до 2 GB. При этом он вообще-то и сейчас нормально работает и было бы неплохо его ограничить, скажем, 100 МБ. Но если я просто поставлю лимит, то его грохнет OOM Killer через несколько часов.

В конфиге я вижу следующее (значения не по умолчанию):

listen_addresses = '*'
max_connections = 1000			# (change requires restart)
shared_buffers = 128MB			# min 128kB
dynamic_shared_memory_type = posix	# the default is usually the first option
max_wal_size = 1GB
min_wal_size = 80MB

Число соединений к базе со временем не растёт, с ней работает один сервис через одно соединение.

Насколько я понял, потребляется 128 MB на весь сервер + work_mem (4MB) на каждое соединение + temp_buffers (8 MB) иногда. Ещё может быть maintenance_work_mem (64 MB). Откуда тут гигабайты набегают - непонятно.

★★★★

Последнее исправление: vbr (всего исправлений: 2)

Число соединений к базе со временем не растёт, с ней работает один сервис через одно соединение.

Ну так и выставь max_connections во что-нибудь мелкое типо 2 или 5 (очевидно что не 1, т.к. иначе ты для отладки к базе не подключишься). Это раз.

Ну и убедись что у тебя в приложении реально persistent connection, а не по соединению на каждую страницу(как любит делать вебня в PHP, например, если не использовать особые, persistent-версии функций подключения)

А еще обрати внимание на параметр maintenance_work_mem. Цитата из мануала:

maintenance_work_mem (integer)

    Specifies the maximum amount of memory to be used by maintenance operations, such as VACUUM, CREATE INDEX, and ALTER TABLE ADD FOREIGN KEY. If this value is specified without units, it is taken as kilobytes. It defaults to 64 megabytes (64MB). 

<skip>

    Note that when autovacuum runs, up to autovacuum_max_workers times this memory may be allocated, so be careful not to set the default value too high

autovacuum_max_workers (integer)

    Specifies the maximum number of autovacuum processes (other than the autovacuum launcher) that may be running at any one time. The default is three.

Pinkbyte ★★★★★
()
Последнее исправление: Pinkbyte (всего исправлений: 1)
Ответ на: комментарий от Eshkin_kot

Пока до 2 не вырос, я перезапускал недавно…

Сейчас 435 показывает.

Mem: 24993728K used, 5828048K free, 437496K shrd, 761792K buff, 12846140K cached
CPU:   2% usr   0% sys   0% nic  92% idle   0% io   0% irq   0% sirq
Load average: 1.06 1.37 1.46 1/2531 250585
  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
250525     1 postgres S     212m   1%   3   0% postgres: n8n n8n 10.163.243.211(42204) idle
250542     1 postgres S     212m   1%   3   0% postgres: n8n n8n 10.163.243.211(45874) idle
250584     1 postgres S     212m   1%   3   0% postgres: n8n n8n 10.163.243.211(33620) idle
   26     1 postgres S     211m   1%   1   0% postgres: autovacuum launcher 
   27     1 postgres S     211m   1%   2   0% postgres: logical replication launcher 
   22     1 postgres S     209m   1%   1   0% postgres: checkpointer 
   23     1 postgres S     209m   1%   1   0% postgres: background writer 
   25     1 postgres S     208m   1%   1   0% postgres: walwriter 
    1     0 postgres S     208m   1%   0   0% postgres
250468     0 root     S     2664   0%   3   0% bash
250585250468 root     R     1620   0%   0   0% top
vbr ★★★★
() автор топика
Ответ на: комментарий от vbr

не, нужен вывод ps axu, а не top, у ps в этом формате там будет две колонки: VSZ и RSS, я хотел их посмотреть и как именно они распределены между процессами, типа такого надо:

postgres@81c1da894b7e:~$ ps axu
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
postgres     219  0.0  0.1   4184  3520 pts/0    S    21:36   0:00 -bash
postgres     240  2.4  0.9 216560 28716 ?        Ss   21:37   0:00 /usr/lib/postgresql/15/bin/postgres -D data
postgres     241  0.0  0.1 216560  5564 ?        Ss   21:37   0:00 postgres: checkpointer 
postgres     242  0.0  0.1 216560  5520 ?        Ss   21:37   0:00 postgres: background writer 
postgres     244  0.0  0.1 216560  4308 ?        Ss   21:37   0:00 postgres: walwriter 
postgres     245  0.0  0.2 218140  6912 ?        Ss   21:37   0:00 postgres: autovacuum launcher 
postgres     246  0.3  0.2 218124  6828 ?        Ss   21:37   0:00 postgres: logical replication launcher 

ну либо включи колонки VIRT RES SHR в top, что бы типа такого было:

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                                                                               
    219 postgres  20   0    4184   3524   2972 S   0.0   0.1   0:00.15 -bash                                                                                 
    240 postgres  20   0  216560  28904  26612 S   0.0   1.0   0:00.21 /usr/lib/postgresql/15/bin/postgres -D data                                           
    241 postgres  20   0  216712  12044   9656 S   0.0   0.4   0:00.19 postgres: checkpointer                                                                
    242 postgres  20   0  216696   5520   3188 S   0.0   0.2   0:00.06 postgres: background writer                                                           
    244 postgres  20   0  216560   9872   7540 S   0.0   0.3   0:12.05 postgres: walwriter                                                                   
    245 postgres  20   0  218140   6912   4372 S   0.0   0.2   0:00.00 postgres: autovacuum launcher                                                         
    246 postgres  20   0  218124   6828   4300 S   0.0   0.2   0:00.01 postgres: logical replication launcher                                                
    252 postgres  20   0  219172  22376  19040 S   0.0   0.8   0:00.07 postgres: postgres postgres [local] idle                                              
Eshkin_kot ★★
()
Ответ на: комментарий от Eshkin_kot

449 MB сейчас, вывод такой:

postgres-d65747f5-z772q:/# ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
postgres       1  0.0  0.1 213804 52976 ?        Ss   Aug21   0:39 postgres
postgres      22  0.0  0.4 214256 143300 ?       Ss   Aug21   0:35 postgres: checkpointer 
postgres      23  0.0  0.4 214176 127348 ?       Ss   Aug21   0:02 postgres: background writer 
postgres      25  0.0  0.0 213884  8964 ?        Ss   Aug21   0:12 postgres: walwriter 
postgres      26  0.0  0.0 216144  6940 ?        Ss   Aug21   0:00 postgres: autovacuum launcher 
postgres      27  0.0  0.0 216064  6916 ?        Ss   Aug21   0:00 postgres: logical replication launcher 
root      470823  0.0  0.0   2664  2348 pts/0    Ss   01:02   0:00 bash
postgres  470907  0.0  0.0 217688 22296 ?        Ss   01:02   0:00 postgres: n8n n8n 10.163.243.234(46996) idle
postgres  471001  0.0  0.0 217620 18984 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55194) idle
postgres  471002  0.1  0.0 217620 19228 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55204) idle
postgres  471003  0.1  0.0 217620 19336 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55218) idle
postgres  471004  0.1  0.0 217620 20916 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55226) idle
postgres  471005  0.1  0.0 217620 20076 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55236) idle
postgres  471006  0.0  0.0 217344 15608 ?        Ss   01:03   0:00 postgres: n8n n8n 10.163.243.234(55246) idle
root      471024  0.0  0.0   1712   860 pts/0    R+   01:04   0:00 ps aux

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

vbr ★★★★
() автор топика
Ответ на: комментарий от vbr

может из-за этого

Скорее всего, у бекендов shared_buffers = 128MB — общий, но у них есть ещё свои локальные данные, например кеш каталога, он у каждой сессии — свой, и с вашим max_connections = 1000 это может быть и 20 Гб в сумме если все 1000 одновременно будут подключены.

Eshkin_kot ★★
()
Ответ на: комментарий от einhander

Потому что docker - это stateless, а postgres - statefull app.

Вот еще мнение DBA

Речь, конечно, идет о проде. Во время разработки - почему бы и нет.

Turbid ★★★★★
()
Последнее исправление: Turbid (всего исправлений: 2)
Ответ на: комментарий от Turbid

Потому что docker

Контейнеры не только докер. Я вообще имел в виду lxc и ему подобные.

За ссылку спасибо, интересно. Там написано про написано про то что фс докера не подходит для интенсивной нагрузки на запись, а как дела у lxc? С сетью та же засада? Я считал, что накладные расходы на контейнер, сильно меньше чем на VM, выходит что не все так однозначно?

einhander ★★★★★
()
Последнее исправление: einhander (всего исправлений: 1)
Ответ на: комментарий от Turbid

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

vbr ★★★★
() автор топика
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от Turbid

Могу только посоветовать изучать технологиии по документации, а не по хабра статьям сомнительного качества. Чтобы контейнер удалить, нужно выполнить команду docker rm <containerid>. Чтобы контейнер сам удалился после остановки, его надо создавать с флагом --rm и используется это обычно для каких-то временных контейнеров, экспериментов, когда их состояние действительно не нужно. Также есть команда docker system prune, которая действительно удаляет все остановленные контейнеры и многое другое.

Просто так контейнеры не удаляются.

И, да, контейнеры с важными данными, конечно, надо запускать с volume-ами. Хотя бы потому, что завтра выйдет новая версия образа и захочется обновиться. Тем не менее никакой эфемерности в докер контейнерах нет и сами по себе они не исчезают, а только с прямым участием пользователя. Так и файлы можно назвать эфемерными, их же можно удалить.

vbr ★★★★
() автор топика
Ответ на: комментарий от anc

Да что тут развертывать… У контейнера помимо read-only образа есть еще writable layer. И он вполне персистентный. Если будет рестартоваться контейнер, данные в нем не пропадут.

А в статье на хабре написана ересь, что после рестарта контейнера пропадают данные.

bigbit ★★★★★
()
Последнее исправление: bigbit (всего исправлений: 1)
Ответ на: комментарий от vbr

Вообще не понимаю, какая логика может быть в том, чтобы назвать докер stateless.

Тем не менее никакой эфемерности в докер контейнерах нет и сами по себе они не исчезают

Containers were originally designed to be stateless and ephemeral (temporary). … Maintaining state in an app means finding a way to connect containers to stateful storage.

https://www.docker.com/blog/deploy-stateful-docker-containers-with-amazon-ecs-with-amazon-efs/

Turbid ★★★★★
()