Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在分片环境下管理数据库连接池?_Java_Postgresql_Jdbc_Connection Pooling_Sharding - Fatal编程技术网

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

Java 如何在分片环境下管理数据库连接池?,java,postgresql,jdbc,connection-pooling,sharding,Java,Postgresql,Jdbc,Connection Pooling,Sharding,我的web应用程序需要支持web和DB层的可伸缩性。 我有以下组成部分: N个Web服务器(Tomcat) M DB服务器按用户名作为分片密钥进行分片(PostgreSQL) 我们的分片策略如下: shard策略是基于查找表的,我们有一个索引表(username,shardId),另一个shard表(shardId,connectionString,load) 我们将定期监视碎片数据库,并更新加载状态字段 当创建新用户时,我们总是选择加载量最低的碎片,并将其存储到索引表中 将动态添加或删除数据库

我的web应用程序需要支持web和DB层的可伸缩性。 我有以下组成部分:

  • N个Web服务器(Tomcat)
  • M DB服务器按用户名作为分片密钥进行分片(PostgreSQL)
  • 我们的分片策略如下:

  • shard策略是基于查找表的,我们有一个索引表(username,shardId),另一个shard表(shardId,connectionString,load)

  • 我们将定期监视碎片数据库,并更新加载状态字段

  • 当创建新用户时,我们总是选择加载量最低的碎片,并将其存储到索引表中

  • 将动态添加或删除数据库碎片

  • 我必须实现像
    getDBConnection(username)
    这样的API,以便根据shard键(在本例中是登录用户)获得一个JDBC连接

    问题是:


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

    我可能根本不会在应用程序中使用连接池,我可能只使用服务器端连接池和
    pgpool II
    pgbouncer

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

    由于这将导致潜在的大量连接和大量连接/断开连接,因此运行服务器端连接池来限制和共享到每个碎片的连接将非常重要。在事务池模式下,在每个碎片上使用类似于
    pgbouncer
    pgpool II
    的东西,在来自web workers的大量连接中共享相对较少的真正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实例对话。

    您使用的是什么连接池
    org.apache.tomcat.jdbc.pool
    <代码>dbcp<代码>c3p0?还有别的吗?(顺便说一句,我没有投反对票,但我知道为什么会投反对票:在清楚你的问题之前需要阅读一点,而且你忽略了很多重要的细节)。顺便说一句,你几乎应该总是根据密钥的散列来分片,而不是密钥本身。这样,您可以在碎片之间获得更均匀的分布,而不会在“x-z”碎片几乎处于空闲状态时使用用户名为“a-c”的碎片。使用bucket hashing。@Craig任何池实现都应该适合我。你知道碎片IP是动态的,所以我需要动态创建DB连接,而不是在spring XML中定义DS。只是不知道如何进行。@Craig对于碎片选择策略,我们通过查找表进行设计,例如碎片信息保存在何处。我们将监视一些与shard相关的数据,以给出其加载状态。当为新用户拾取一个碎片时,我们总是选择加载量最低的碎片。“这不是一个真正的问题”-是的。谢谢你的快速评论,我将尝试pgbouncer或pgpool II。但目前我们更喜欢在应用程序中实现这一层,因此可能以编程方式使用DBCP或C3P0是一种可能的解决方案。@Grace我想说,您必须使用编程连接池管理,但您也确实希望服务器位于pgbouncer后面,或者,您将有大量空闲的后端浪费内存和其他资源,并且启动/停止后端的频率将超过您必须的频率。简单来说,我想通过应用层实现PostgreSQL监控/故障转移。只需查看pgbouncer和pgpool2,它们似乎可以工作。我更喜欢在每个shard DB服务器上部署pgbouncer实例。这种用法有什么问题吗?@Grace没有;这正是我推荐的做法。非常感谢您的大力支持!