Комментарии 21
Я всегда думал, что в современных СУБД по умолчанию включён функционал пула соединений, и свой огород городить не нужно.
-6
Если честно ожидал увидеть сравнение пулов: c3po, bonecp, apache commons, tomcat (у них какой то свой). То что надо кэшировать и так всем понятно.
+7
В данной статье я ставил целью показать, что существует такая проблема, зачастую многие не могут ответить на вопрос: зачем нужны пулы соединений. А так же показать, что писать самому реализацию кеширования не имеет смысла. Сравнение уже существующих реализация можно провести, но мне кажется, что там результаты тестов не будут сильно различаться.
+1
Тоже вариант. Есть маленькое пожелание для более простого понимания: выделите жирным, что кэшировать надо, и что писать свои пулы не надо и что PGPoolingDataSource использовать не надо если уже есть другой пулл.
0
В данной статье я ставил целью показать, что существует такая проблемаУ кого как, лично у меня сложилось впечатление, что статью надо было писать лет 10 назад, а то и больше. Тогда у "проблемы" пула соединений с БД была некая актуальность. Сейчас в большинстве движков/фреймворков/серверов приложений такие вещи включены по-умолчанию. Если крутануть лет на 5-7 (а не на 10) назад, то актуальными были уже кэширование запросов и результатов выборки. Опять же, сейчас это есть почти везде и делается просто путем указания в конфигурации флага включить/выключить. В наше время интересными темами являются вопросы распределенных кэшей.
+3
>Первый шаг открытия соединения с сервером, является довольно долгим и мы можем его исключить заранее подготовив пул уже открытых соединений и предоставляя из него соединения приложению по мере необходимости.
pgbouncer же.
pgbouncer же.
+2
Пулы соединений на стороне приложения хороши тогда, когда веб-серверов мало, и мало серверов баз данных. А вот когда у вас 100 веб-серверов и 100 серверов баз данных, причём каждый веб-сервер может обращаться к любой базе, даже при размере пула в 1 соединение мы получим 100 «висящих» соединений на каждом сервере баз данных. Поэтому правильно вам говорят про отдельные прокси-сервера типа pgbouncer, которые за вас держат коннекты ко всем серверам, а вы к ним только обращаетесь
+2
Тему статьи можно переформулировать так «Одна из причин почему в проекте надо использовать популярный|проверенный фреймворк». При использовании фреймворка, согласен на первом этапе может быть некоторый оверворк, но когда реально встанет вопрос с проблемами расширения|масштабирования, уже будет понятно есть ли на это деньги и мотивация.)
0
У меня вопрос: объект PreparedStatement привязан к Connection или нет? Иными словами, можно ли использовать один prepared statement с разными connection? Или при создании prepared statement на стороне сервера создаётся какое-то состояние?
0
Не нашел там ответа на свой вопрос.
0
Да PreparedStatement связан с объектом Connection, который его создал. Именно по этому в самописном пуле кеширование происходит в классе Connection
public PreparedStatement prepareStatement(String sql) throws SQLException {
PreparedStatement statement = statements.get(sql);
if (statement == null) {
statement = new MyStatement(connection.prepareStatement(sql));
statements.put(sql, statement);
}
return statement;
}
+1
немного удивлен олдскульному синтаксису. Вы пробовали java 7?
0
Не очень понял про синтаксис. Можете прояснить что Вам не понравилось?
0
думаю имелось ввиду это: docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
0
ну почти, в данном случае интерфейс AutoCloseable не очень подходит, я фишки Project Coin как например Diamond operator (http://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7) которые можно было бы использовать. Использование JDBC 4 тоже делает код немного прозрачнее
0
У вас слишком мало тестовых данных чтобы делать серёзные выводы.
Нужно значительно больше данных, ваш объём вообще влезает в одну страницу и ещё очень много места останется, которая самой СУБД скорее всего прокешируется в памяти, кроме того план иссполнения будет самый примитивный.
Самой большой проблемой и очень частым запросом в реальных приложениях идёт JOIN и очень часто проседание в производительности имеено здесь. Потому тэст стоило делать с JOIN.
А теперь добави сюда влияние индексов, а также тот факт что для различного количества данных СУБД может и будет исспользовать разные планы иссполнения, то мы поймём что писать свой самописный кеш не стоит, только если вы не съели зубы на даном движке СУБД и имеете очень хороший опыт в реализации. Да кстати то что работало у вас сегодна, может сломаться завтра на новой версии СУБД.
Нужно значительно больше данных, ваш объём вообще влезает в одну страницу и ещё очень много места останется, которая самой СУБД скорее всего прокешируется в памяти, кроме того план иссполнения будет самый примитивный.
Самой большой проблемой и очень частым запросом в реальных приложениях идёт JOIN и очень часто проседание в производительности имеено здесь. Потому тэст стоило делать с JOIN.
А теперь добави сюда влияние индексов, а также тот факт что для различного количества данных СУБД может и будет исспользовать разные планы иссполнения, то мы поймём что писать свой самописный кеш не стоит, только если вы не съели зубы на даном движке СУБД и имеете очень хороший опыт в реализации. Да кстати то что работало у вас сегодна, может сломаться завтра на новой версии СУБД.
0
Кажется тестировалась не производительность запросов, а издержки при постоянном открытии новых соединений. По моему достаточно показательно.
А насчет планов, я больше скажу — насколько я понял, в рамках одного PreparedStatement план не будет корректироваться относительно изменения статистики в базе (поправьте меня, если кто в курсе). Поэтому в навороченных движках также есть настройка времени жизни (TTL) Connection и PreparedStatement. Иначе может получиться, что система тормозит — нехватает индекса, создаешь его, а тормоза продолжаются, так как план устарел и не учитывает индекс. Если не предусмотрен TTL или хотя бы ручное закрытие соединений, то придется приложение перегрузить.
Так что да, самому писать такой велосипед себе дороже.
А насчет планов, я больше скажу — насколько я понял, в рамках одного PreparedStatement план не будет корректироваться относительно изменения статистики в базе (поправьте меня, если кто в курсе). Поэтому в навороченных движках также есть настройка времени жизни (TTL) Connection и PreparedStatement. Иначе может получиться, что система тормозит — нехватает индекса, создаешь его, а тормоза продолжаются, так как план устарел и не учитывает индекс. Если не предусмотрен TTL или хотя бы ручное закрытие соединений, то придется приложение перегрузить.
Так что да, самому писать такой велосипед себе дороже.
+1
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.
Пулы соединений к БД — зачем и почему