@orbit070

Почему так мало соединений с базой данных на 1ГБ оперативной памяти?

Всем привет.
Прошу помочь разобраться, почему приведены такие цифры у digitalocean.

Если я правильно понимаю, то там написано, что одно соединение ест около 10мб.
При этом дальше пишут, что нода с 1ГБ оперативки сможет держать примерно 25 соединений.
Сначала подумал что остальная память на обслуживание самой ноды и операционной системы и тд, но нет: даже если взять ноду с 4ГБ оперативной памяти, все равно на каждый ГБ будет +25 соединений(то есть на 4ГБ всего 100 соединений).

Прошу помочь с ответами на вопросы, кто чем может, буду очень благодарен:

1. Почему так мало соединений на каждый ГБ оперативной памяти, ведь исходя из "примерно 10МБ на соединение" их должно минимум раза в три больше чем 25?

2. Правильно ли я понимаю, что пул соединений не помогает в плане экономии оперативной памяти и каждое соединение в нем все равно кушает все те же 10МБ, а пул лишь снижает нагрузку на процессор из-за отсутствия необходимости каждый раз создавать/убивать соединение?

3. Правильно ли я понимаю, что эти 10МБ оперативки на соединение это именно на процесс, который относится к базе данных, а не к серверному коду? Имею в виду если база данных и серверный код на одной машине, из кода подключаемся к БД, тогда база будет кушать 10МБ оперативки на одно соединение а сервер будет кушать свои N МБ на соединение, и тогда на одной машине одно соединение уже будет 10+N МБ?

Заранее всем большое спасибо.
  • Вопрос задан
  • 166 просмотров
Решения вопроса 2
Melkij
@Melkij
PostgreSQL DBA
Вот честно могу ответить - ни малейших представлений как можно абстрактно сказать, сколько памяти займёт client backend процесс базы.
Это будет меняться от:
- очевидно версии базы, плюс от компилятора и настроек сборки
- session_preload_libraries, work_mem (к слову о work_mem - вы знаете, что один запрос может использовать несколько work_mem?), temp_buffers. Да ещё maintenance_work_mem для некоторых операций
- величины системного каталога - как pinned таблиц, так и затем кэшированных при обращениях
- выполняемых ранее запросов. Тот же кэш хранимых процедур у каждого backend свой

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

Помимо собственной private памяти на каждое активное соединение всё множество max_connections резервирует себе некоторое место в сегменте разделяемой памяти, независимо от того, сколько соединений вы затем используете.

Чтобы админить калькуляторы и чайники обычно DBA не нанимают. Тем более если на том же самом калькуляторе помимо базы ещё и приложение отъедает непредсказуемо сколько памяти. Чего там от этого 1гб останется? Видимо даже shared_buffers с 128мб поднимать некуда, а то может и уменьшать придётся. Так что по опыту сложно что-то сказать о такой конфигурации.

Скорей всего не трогайте max_connections. Оставьте дефолтные 100.

Правильно ли я понимаю, что пул соединений не помогает в плане экономии оперативной памяти

Смотря какой пул и как работает приложение.
pgbouncer в pool_mode = transaction вполне может свести пару сотен подключений к баунсеру на десяток коннектов в базе. Ну а 10 процессов базы будут использовать наверняка поменьше памяти чем 200.
Для pool_mode = session - да, только сгладить стоимость fork годится.
Ответ написан
@Fixid
Не спец по PSQL
Но:
1. А где хранить данные в быстро доступе? Где хранить кэш таблиц и запросов?
2. Почти так
3. Со стороны СУБД нужно держать коннект и для этого требуется 10МБ на один коннект и со стороны клиента тоже надо держать коннект и тратить уже свою память (размер зависит от конкретной реализации конкретного клиента)

P.S. зачем вам столько соединений? Обычно достаточно одного соединения одному клиенту. И если у вас просто back, то ему хватит одного коннекта
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы