如何在分片环境下管理数据库连接池?

时间:2012-10-29 09:08:43

标签: java postgresql jdbc connection-pooling sharding

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

  1. N个Web服务器(Tomcat)
  2. M DB服务器按用户名分片为分片键(PostgreSQL)
  3. 我们的碎片策略如下:

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

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

    3. 创建新用户时,我们总是以最低负载拾取分片,并存储到索引表。

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

    5. 我必须实现像getDBConnection(username)这样的API,以根据分片键(在这种情况下是登录用户)获得一个JDBC连接。

      问题是:

      1.如何以与连接池一起使用的方式实现此API?假设每个分片支持500个连接,我怎么能通过Java代码做到这一点?

1 个答案:

答案 0 :(得分:0)

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

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

由于这会导致可能存在大量连接并且存在大量连接/断开连接,因此运行服务器端连接池以限制和共享每个分片的连接也非常重要。在每个分片上使用事务池模式中的pgbouncerpgpool-II之类的东西,在来自Web工作者的大量连接中共享相对少量的真实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实例进行对话。