Максимальный пул соединений также ограничивает максимальное количество подключений к базе данных? - PullRequest
0 голосов
/ 20 сентября 2018

Я использую hikari cp с приложением весенней загрузки, которое имеет более 1000 одновременно работающих пользователей.Я установил максимальный размер пула -

spring.datasource.hikari.maximum-pool-size=300

Когда я смотрю на список процессов mysql, используя

show processlist;

Он показывает максимум 300, который равен размеру пула. Он никогда не увеличиваетсячем максимальный пул. Это намерение?Я думал, что размер пула означает, что соединения поддерживаются, так что соединения могут быть использованы повторно, когда требуются будущие запросы к базе данных, но когда возникает необходимость, может быть установлено больше соединений.

Также, когда я удаляю конфигурацию максимального пула, я немедленноget-

HikariPool-0 - Соединение недоступно, время запроса истекло после 30000 мс.

Как решить эту проблему. Заранее спасибо.

1 Ответ

0 голосов
/ 20 сентября 2018

Да, это предназначено.Цитирование документации :

Это свойство контролирует максимальный размер, который разрешен для пула, включая как свободные, так и используемые соединения.В основном это значение будет определять максимальное количество фактических подключений к базе данных базы данных.Разумное значение для этого лучше всего определяется вашей средой исполнения.Когда пул достигнет этого размера и свободные соединения не будут доступны, вызовы на getConnection() будут блокироваться на срок до connectionTimeout миллисекунд до истечения времени ожидания.Пожалуйста, прочитайте о размере пула . По умолчанию: 10

Таким образом, в основном, когда используются все 300 соединений, и вы пытаетесь установить соединение 301 st , Hikari не будетсоздайте новый (поскольку maximumPoolSize является абсолютным максимумом), но он скорее будет ждать (по умолчанию 30 секунд), пока соединение снова не станет доступным.

Это также объясняет, почему вы получаете упомянутое исключение,потому что по умолчанию (если не настраивать maximumPoolSize) - 10 подключений, которые вы, вероятно, сразу достигнете.

Чтобы решить эту проблему, вы должны выяснить, почему эти подключения заблокированы более чем на 30 секунд.,Даже в ситуации с 1000 одновременно работающих пользователей не должно быть проблем, если ваш запрос занимает не более нескольких миллисекунд или нескольких секунд.

Увеличение размера пула

Если вы вызываете действительно сложные запросы, которые занимают много времени, у вас есть несколько возможностей.Первый - увеличить размер пула.Это, однако, не рекомендуется , так как рекомендуемая формула для расчета максимального размера пула:

connections = ((core_count * 2) + effective_spindle_count)

Цитата О размере пула статья:

Формула, которая довольно неплохо выдерживала многие тесты в течение многих лет, состоит в том, что для оптимальной пропускной способности число активных соединений должно быть где-то около ((core_count * 2) + effective_spindle_count).В число ядер не должны включаться потоки HT, даже если включена гиперпоточность.Эффективное число шпинделей равно нулю, если активный набор данных полностью кэширован, и приближается к фактическому количеству шпинделей при падении частоты попаданий в кэш.... До сих пор не проводился анализ того, насколько хорошо формула работает с твердотельными накопителями.

Как описано в той же статье, это означает, что 4-ядерный сервер с 1 жестким диском должен толькоесть около 10 соединений.Несмотря на то, что у вас может быть больше ядер, я предполагаю, что у вас недостаточно ядер, чтобы гарантировать 300 подключений, которые вы делаете, не говоря уже об их увеличении.


Увеличение времени ожидания соединения

Другая возможность - увеличить время ожидания соединения.Как упоминалось ранее, когда все соединения используются, по умолчанию он будет ожидать 30 секунд, что является тайм-аутом соединения.

Вы можете увеличить это значение, чтобы приложение дольше ожидало перед тем, как перейти в тайм-аут.Если ваш сложный запрос занимает 20 секунд, и у вас есть пул соединений из 300 и 1000 одновременно работающих пользователей, теоретически вы должны настроить время ожидания вашего соединения как минимум на 20 * 1000 / 300 = 67 seconds.

Однако учтите, что это означает, что вашприложение может занять много времени, прежде чем показывать ответ пользователю.Если у вас есть 67-секундный тайм-аут соединения и дополнительные 20 секунд до завершения сложного запроса, вашему пользователю, возможно, придется подождать до полутора минут.


Улучшение времени выполнения

Как упоминалось ранее, вашей основной целью было бы выяснить, почему ваши запросы так долго.С пулом соединения 300, тайм-аутом соединения 30 секунд и 1000 одновременно работающих пользователей это означает, что для выполнения ваших запросов требуется не менее 9 секунд , что очень много.

Попробуйтечтобы улучшить время выполнения:

  • Добавление правильных индексов.
  • Правильное написание запросов.
  • Улучшение аппаратного обеспечения базы данных (диски, ядра, сеть, ...)
  • Ограничьте количество записей, с которыми вы имеете дело, введя нумерацию страниц, ....
  • Разделите работу.Посмотрите, можно ли разделить запрос на более мелкие запросы, что приведет к промежуточным результатам, которые затем можно будет использовать в другом запросе и так далее.Пока вы не работаете в транзакциях, соединение будет освобождено между ними, что позволит вам обслуживать нескольких пользователей за счет некоторой производительности.
  • Использование кэширования
  • Предварительный расчет результатовЕсли вы выполняете некоторые ресурсоемкие вычисления, вы можете попытаться предварительно рассчитать результаты в тот момент, когда приложение используется не так часто, например.ночью и сохраните эти результаты в другой таблице, к которой можно легко получить запрос.
  • ...
...