Менеджер пула соединений JDBC
Мы находимся в процессе переписывания веб-приложения на Java из PHP. Я думаю, но я не совсем уверен, что у нас могут возникнуть проблемы с пулами соединений. Приложение само по себе является мультитенантным и представляет собой комбинацию "Отдельная база данных" и "Отдельная схема".
Для каждого экземпляра сервера базы данных Postgres может быть более 1 базы данных (с именем schemax_XXX), содержащей более 1 схемы (где схема является арендатором). При регистрации может произойти одно из двух:
- Новая схема клиента создается в базе данных schema_XXX с наибольшим номером.
- Процесс регистрации видит, что база данных полностью выделена, и создает новую базу данных schemas_XXX+1. В этой новой базе данных создается схема арендатора.
Все арендаторы известны через центральный реестр (также база данных Postgres). Когда сеанс установлен, реестр разрешит хост, базу данных и схему клиента, и для этого HTTP-запроса будет установлен сеанс базы данных.
Теперь проблема, которую я вижу здесь, имеет две стороны:
- Пул соединений JDBC определяется при запуске приложения. Под этим я подразумеваю, что все базы данных (хост + база данных) известны при запуске. Это противоречит процессу регистрации.
- Когда я пишу это, у нас есть ~20 серверов баз данных с ~1000 баз данных (на общую сумму схем ~ 100 тыс. (Арендаторов). Учитывая эти цифры, мне понадобится 20*1000 источников данных для каждого экземпляра приложения. Я предполагаю, что все пулы также, в тот или иной момент, также запущены. Я не уверен, сколько ресурсов выделяет пул, но это должно быть нетривиальным количеством для пулов 20k.
Итак, возможно ли даже предположить, что для этого можно использовать пул соединений?
Для первой проблемы, я предполагаю, что пул с поддержкой JMX может быть использован, и что мы создаем новый источник данных, когда и если создается новая база данных schemas_XXX. Большая проблема заключается в огромном количестве пулов. Для этого, я думаю, следует использовать какой-то диспетчер пулов, который может завершить пул, у которого нет открытых соединений (и по требованию также запустить пул). Я не нашел ничего, что поддерживает это.
Какие варианты у меня есть? Или я должен просто откусить пулю и вернуться к пулу соединений вне процесса, такому как PgBouncer, и установить простое соединение JDBC для каждого запроса, подобно тому, как мы обрабатываем это сейчас с PHP?
1 ответ
Несколько вещей:
- Не требуется создавать экземпляр пула соединений только при запуске приложения. Вы можете создавать или уничтожать их в любое время;
- Вы, очевидно, не хотите охотно создавать один пул соединений для каждой базы данных или схемы, которые будут открыты постоянно. Вы должны были бы сохранить как минимум 20000 или 100000 открытых соединений, если бы вы это сделали, даже если вы не начали использовать ресурсы, не связанные с подключением, используемые DataSource;
- Если, скорее всего, запросы на подключения для конкретного арендатора имеют тенденцию к кластеризации, вы можете рассмотреть ленивые, динамически создаваемые экземпляры пулов и уничтожать их через некоторое время, если они некоторое время не обрабатывали запрос.
Удачи!