Как настроить пул соединений?

Каков наилучший способ настройки пула по отношению к: -

  • Когда вы создаете соединения?
  • Когда вы закрываете соединения и закрываете ли вы все из них?
  • Тестирование соединений по-прежнему хорошо. Когда и как?
  • Как вы можете найти хорошее число для максимального количества соединений?
  • Какой вид мониторинга у вас есть, чтобы убедиться, что пользователи пула хорошо себя ведут? Можете ли вы остановить один плохой фрагмент кода, чтобы вытащить все?
  • Вы написали свой собственный пул или использовали стороннюю библиотеку?

Я считаю, что это агностический вопрос, но комментарии о "функциях" конкретных баз данных/языков приветствуются. Например, в некоторых базах данных может быть медленнее или дороже, чем другие.

Чтобы уточнить, я не собираюсь писать пул с нуля, этот вопрос больше связан с настройкой существующей библиотеки, которая объединяет.

Ответ 1

Я написал пул соединений для базы данных в Java, когда это был всего лишь шаблон проектирования, а не общая библиотека. Теперь я использую встроенную в Tomcat.

Я использовал поток для контроля нескольких аспектов пула и нескольких параметров для управления его поведением...

  • minimumInPool = "3"... Эти первые три создаются при запуске. Пул никогда не может опускаться ниже трех.
  • maximumIdleTimeBeforeRemoval = "60"... Если соединение простаивает в течение часа, отбросьте его и создайте новый. Время простоя, вероятно, означает, что в пуле есть только минимум три.
  • maximumInUseTimeBeforeRemoval = "30"... Если данное соединение было проверено на протяжении более 30 минут, возможно, что-то не так. Напомните, и убейте соединение.
  • maximumTimeBeforeRemoval = "60"... Удалите его, если ему больше 60 минут.
  • maximumUsageBeforeRemoval = "1000"... Удалите его, если он был извлечен более 1000 раз.
  • monitorInterval = "15"... Проверьте указанные параметры каждые 15 минут.

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

Я использовал тонкие драйверы Oracle JDBC и подключился к базе данных Oracle.

Ответ 2

Вот обоснование, которое я использовал для недавней реализации.

  • У вас есть два типа соединений в пуле соединений. Первое готово, то есть открыто, но не используется клиентом. Второй активен, что означает использование клиентом.

  • У вашего пула соединений поддерживается небольшое количество готовых подключений, минимум N и максимум M. N можно настроить в зависимости от максимальной скорости, с которой ваши клиенты запрашивают соединения. Если количество готовых подключений когда-либо падает до нуля, вам нужно больше N. Если число постоянно высокое (скажем, выше 10), вам нужно меньше N.

  • Когда клиент хочет подключиться, дайте им один из готовых (сделав его активным), а затем немедленно откройте новый, если в настоящее время меньше N готовых (но не заставляйте клиента ждать этого для завершения, или вы потеряете преимущество объединения). Это гарантирует, что всегда будет установлено не менее N готовых подключений. Если ни один из них не готов, когда клиент хочет его, ему придется подождать, пока вы создадите новый.

  • Когда клиент закончит активным подключением, верните его в состояние готовности, если есть меньше, чем M готовых подключений. В противном случае закройте его. Это предотвратит наличие более чем готовых соединений.

  • Периодически перерабатывайте готовые соединения, чтобы предотвратить устаревшие соединения. Если подключено более N готовых подключений, просто закройте самое старое соединение. В противном случае закройте его и снова откройте другой.

Это имеет то преимущество, что в вашем пуле соединений имеется достаточно готовых и юных соединений, не перегружая сервер.

Ответ 3

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

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

Прежде чем ответить на вопрос о закрытии и закрытии соединения, позвольте мне сказать, что кеширование действительно важно. Получение объекта из кеша позволит вам сэкономить массу времени. В некоторых моих приложениях asp.net, когда кеширование включено в dev, я обнаружил, что я едва могу измерить задержку, тогда как при вызове БД может потребоваться от 15 мс до 45 мс для завершения вызова, и это даже не рассматривает другие факторы задержки или нагрузки. Другой метод, который я использую, является хорошей структурой объектов для моих данных, поэтому я только делаю обновление БД, если что-то меняется. Ive внедрил некоторые методы для моего объекта. O убедитесь, что Ive делает как можно меньше IO.

Сказано, что все мы знаем, что нам нужно в какой-то момент получить доступ к нашей БД и написать, поэтому я следую двум принципам:

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

  • Я делаю так много в пакете или сразу, как только могу, когда соединение открыто. Это немного сложнее, поэтому позвольте мне объяснить.

    • Один из методов, который Ive использовал, - это передать мои объекты соединения в трубу, чтобы все объекты могли использовать один объект соединения. Это приводит к тому, что одно соединение открыто и закрыто, а не 10 или более, в зависимости от вашего приложения. Хорошим примером этого является одна из наших моделей покупки, которая использует возможности SQL-сервера для сбора статистики и хеширования сложных шаблонов заказов. Не имеет смысла продолжать открывать и закрывать соединение, когда вы делаете поиск 200K + DB или независимо от приложений. Другая часть этого заключается в том, что когда я использую объект, я пытаюсь связать свои обновления, чтобы сократить время, в течение которого я держу соединение открытым. Таким образом, выполнение scope_identity в вызове insert позволяет мне заботиться о моей вставке и поиске уникального идентификатора для добавления к моему объекту до его кеширования. В тот же день, когда я впервые разрабатывал приложение asp apps, я действительно открываю соединение, как только страница начнет загружаться, а затем закроет его. Я больше не рекомендую это делать. Теперь в день есть большая выгода для этих видов абстракций и слоев, которые я бы рекомендовал любому начинающему программисту уделять пристальное внимание.

Мои два цента:

Кэш ваших данных! Кэш ваших данных! Кэш ваших данных! Сделайте как можно меньше доступа к БД, когда вы не можете кэшировать и затем кэшировать свои данные!

Ответ 4

Jakarta Commons DBCP уже делает все, что вы указали:

  • он создает соединения по мере необходимости и управляет ими в пуле
  • он может закрыть соединения, если они не были использованы в течение определенного периода времени
  • он может выполнить запрос в соединении, прежде чем передать его, и если есть ошибка, соединение отбрасывается и создается новый. Соединения также могут периодически проверяться в режиме ожидания.
  • вы можете установить лимит на соединения, которые будут созданы, а также на минимальное количество подключений, которые будут готовы. Предел, конечно, сильно зависит от вашего приложения.
  • Я не знаю, как только DBCP знает, когда соединение не закрывается и закрывает его для вас, генерируя исключение, чтобы вы знали, что произошло, когда вы видите свой журнал.
  • DBCP имеет параметр таймаута, который очень полезен. Если все соединения в пуле используются, он будет ждать этого периода времени для соединения, которое будет возвращено в пул, и если нет каких-либо доступных, когда предел достигнут, вы получите сообщение об ошибке.

Вы можете настроить свою пул, играя с минимальным количеством подключений, максимальным количеством подключений, которые нужно создать, и таймаутом. Более длительный тайм-аут позволит вам иметь нижний предел соединений, в то время как более короткий тайм-аут, вероятно, потребует большего количества. Это сильно зависит от того, что делает ваше приложение и как он использует соединения.

Ответ 5

Я согласен с матом b, что мы не должны изобретать велосипед.

Однако использование Commons DBCP может быть основано на ответах этого и на этом. Здесь есть лучшие альтернативы, например c3po или proxool.

Или вы можете использовать механизм объединения пула зависимых от rdbms.

Ответ 6

Зачем изобретать колесо?

Кто-то уже, вероятно, решил проблему, и лучше.

Если вы находитесь в мире Java, вы можете использовать Commons DBCP.