1

我们正在用 Java 重写一个来自 PHP 的 Web 应用程序。我认为,但我不太确定,我们可能会在连接池方面遇到问题。应用程序本身是多租户的,是“分离数据库”和“分离模式”的组合。

对于每个 Postgres 数据库服务器实例,可以有超过 1 个数据库(名为 schemax_XXX)持有超过 1 个模式(其中模式是租户)。在注册时,可能会发生以下两种情况之一:

  1. 在编号最高的 schema_XXX 数据库中创建一个新的租户模式。
  2. 注册过程看到一个数据库已被完全分配并创建一个新的 schemas_XXX+1 数据库。在这个新数据库中,创建了租户模式。

所有租户都通过中央注册表(也是 Postgres 数据库)知道。建立会话后,注册表将解析租户的主机、数据库和模式,并为该 HTTP 请求建立数据库会话。

现在,我认为我在这里看到的问题是双重的:

  1. JDBC 连接池是在应用程序启动时定义的。我的意思是所有数据库(主机+数据库)在启动时都是已知的。这与注册过程相冲突。
  2. 当我写这篇文章时,我们有约 20 个数据库服务器和约 1000 个数据库(总计约 100k(租户)模式。鉴于这些数字,我需要为每个应用程序实例提供 20*1000 个数据源。我m 假设所有池也有时也启动了。我不确定一个池分配了多少资源,但对于 20k 个池来说,它必须是一个不平凡的数量。

那么,甚至假设可以为此使用连接池是否可行?

对于第一个问题,我想可以使用支持 JMX 的池,并且如果创建新的 schemas_XXX 数据库,我们将创建一个新的数据源。更大的问题是大量的池。为此,我想,应该使用某种池管理器来终止没有打开连接的池(并且按需也启动一个池)。我还没有找到任何支持这一点的东西。

我有什么选择?还是我应该咬紧牙关,退回到进程外的连接池,例如 PgBouncer,并为每个请求建立一个普通的 JDBC 连接,类似于我们现在使用 PHP 处理它的方式?

4

1 回答 1

1

一些东西:

  1. 连接池不需要仅在应用程序启动时实例化。您可以随时创建或销毁它们;
  2. 您显然不想急切地为每个数据库或模式创建一个连接池以始终打开。如果你这样做了,你需要保持至少 20000 或 100000 个连接打开,即使在你获得数据源使用的非连接资源之前,这也不是一个初学者;
  3. 如果(很可能)特定租户的连接请求倾向于集群,您可能会考虑懒惰地动态实例化池,如果它们有一段时间没有处理请求,则在超时后销毁它们。

祝你好运!

于 2014-06-09T07:32:50.130 回答