2

我的 Web 应用程序需要同时支持 Web 和 DB 层的可伸缩性。我有以下组件:

  1. N 个 Web 服务器 (Tomcat)
  2. 以用户名作为分片键的 M 个 DB 服务器(PostgreSQL)

我们的分片策略如下:

  1. 分片策略是基于查找表的,我们有一个索引表(用户名,shardId),另一个分片表(shardId,connectionString,loading)。

  2. 我们会定期监控分片数据库,并更新加载状态字段。

  3. 创建新用户时,我们总是选择负载最低的分片,并存储到索引表中。

  4. 数据库分片将动态添加或删除。

我必须实现一个 API,比如getDBConnection(username)根据分片键(在本例中为登录用户)获得一个 JDBC 连接。

问题是:

1.我怎样才能以一种适用于连接池的方式实现这个 API?假设每个分片支持 500 个连接,我怎么能通过 Java 代码做到这一点?

4

1 回答 1

2

我可能根本不会在应用程序中连接池,我可能只是使用带有pgpool-IIor的服务器端连接池pgbouncer

如果我要使用应用程序内池,我会创建每个分片的连接池,然后从分片的适当池中选择一个连接。这将适用于任何允许您以编程方式而不是声明方式创建池的连接池实现。每个池都应该非常积极地尝试关闭非活动连接。看起来org.apache.tomcat.jdbc.pool.DataSource很适合这个;请参阅Tomcat JDBC 池文档

由于这将导致潜在的大量连接和大量连接/断开连接,因此运行服务器端连接池以限制和共享到每个分片的连接将非常重要。在每个分片上使用类似pgbouncerpgpool-II处于事务池模式的东西,以在来自 Web Worker 的大量连接中共享相对少量的真实 PostgreSQL 连接。

我会说你会想要这样的模式:

web1 [pool1]-----------------------------[server1-pgbouncer]------[server1-pg]
     [pool2]-------------------------------v         ^
     [pool3]---------v        [server2-pgbouncer]-----------------[server2-pg]
                     |                     ^         |
                    [server3-pgbouncer]---------------------------[server3-pg]
                     |                     |         |
web2 [pool3]---------^                     |         |
     [pool2]-------------------------------|         |
     [pool1]------------------------------------------

每个应用程序池都连接到与该池对应的分片服务器上的 pgbouncer,并且只有该分片服务器的 pgbouncer 会与分片的 PostgreSQL 实例对话。

于 2012-10-29T09:41:56.847 回答