连接池策略:好,坏或丑?

我负责开发和维护一组以类似数据为中心的Web应用程序。 我当时决定的架构是每个应用程序都有自己的数据库和Web-root应用程序。 每个应用程序都维护一个连接池到它自己的数据库和一个用于共享数据的中央数据库(登录等)

一位同事一直认为这个策略不会扩展,因为有这么多不同的连接池不可扩展,我们应该重构数据库,以便所有不同的应用程序使用单个中央数据库,并且可能是任何修改系统特有的将需要从该数据库反映出来,然后使用由Tomcat提供支持的单个池。 他假定有很多“元数据”在网络中来回传递,以维护连接池。

我的理解是,通过适当的调整,在不同的池中使用尽可能多的连接(低容量应用程序获得更少的连接,大量应用程序获得更多,等等), 的数量与数量相比无关紧要。 连接或更正式地说,与1个30个连接池相比,维护3个10个连接池所需的开销差异可以忽略不计。

最初将系统分解为一个应用程序一个数据库设计的原因是,应用程序之间可能存在差异,并且每个系统都可以根据需要对架构进行修改。 同样,它消除了系统数据流入其他应用程序的可能性。

不幸的是,公司没有强有力的领导作出艰难的决定。 虽然我的同事只是模糊地支持他的担忧,但我想确保理解多个小型数据库/连接与一个大型数据库/连接池的分支。

您的原始设计基于合理的原则。 如果它有助于您的情况,此策略称为水平分区或分片 。 它提供:

1)更高的可扩展性 – 因为如果需要,每个分片可以存在于单独的硬件上。

2)更高的可用性 – 因为单个分片的失败不会影响其他分片

3)更高的性能 – 因为被搜索的表具有更少的行,因此索引更小,从而产生更快的搜索。

您的同事的建议将您转移到单点故障设置。

至于你关于3个大小为10的连接池与1个大小为30的连接池的问题,解决这个争论的最好方法是使用基准测试。 单独配置您的应用程序,然后使用ab(Apache Benchmark)进行一些压力测试,看看哪种方式表现更好。 我怀疑不会有显着差异,但做基准来certificate它。

如果您有一个数据库和两个连接池,每个连接池有5个连接,则您有10个与数据库的连接。 如果您有5个连接池,每个连接池有2个连接,则您有10个与数据库的连接。 最后,您有10个与数据库的连接。 数据库不知道您的池存在,没有意识。

池和DB之间交换的任何元数据都将在每个连接上发生。 当连接开始时,连接被拆除等等。因此,如果你有10个连接,这个流量将发生10次(至少,假设它们在池的整个生命周期内保持健康)。 无论您有1个池还是10个池,都会发生这种情况。

至于“每个应用程序1个数据库”,如果你没有与每个数据库的单独数据库实例交谈,那么它基本上无关紧要。

如果您有一个托管5个数据库的数据库服务器,并且您与每个数据库建立了连接(例如,每个连接2个连接),那么与托管单个数据库的同一个数据库相比,这将消耗更多的开销和内存。 但这种开销最多只是微不足道的,而且在具有GB大小的数据缓冲区的现代机器上完全无关紧要。 超过某一点,所有数据库关心的是将数据页面从磁盘映射和复制到RAM并再次返回。

如果您在DB中有一个重复的大型冗余表,则可能会造成浪费。

最后,当我使用“数据库”这个词时,我的意思是服务器用来合并表的逻辑实体。 例如,Oracle真的喜欢每个服务器有一个“数据库”,分解为“模式”。 Postgres有几个DB,每个都可以有模式。 但无论如何,所有现代服务器都具有可以使用的逻辑数据边界。 我这里只是使用“数据库”这个词。

因此,只要您为所有应用程序命中数据库服务器的单个实例,连接池等就无关紧要,因为服务器将共享客户端的所有内存和资源有必要的。

好问题。 我不知道哪种方式更好,但您是否考虑过以这样的方式设计代码:您可以在尽可能少的痛苦的情况下从一种策略切换到另一种策略? 也许可以使用一些轻量级数据库代理对象来掩盖来自更高级代码的此设计决策。 以防万一。

数据库和开销方面,1个具有30个连接的池和3个具有10个连接的池大致相同,假设两种情况下的负载相同。

在应用方面,让所有数据通过单个点(例如服务层)与具有每个应用程序访问点之间的差异可能非常大; 在性能和易于实现/维护方面(例如,考虑必须使用分布式缓存)。

好的,很好的问题,但使用几种数据库(A)方法或大型方法(B)进行讨论并不容易:

  1. 这取决于数据库本身。 例如,Oracle在Sybase(以及LOCK)策略方面与Sybase ASE的行为不同。 如果存在大量并行写入并且数据库使用悲观锁定策略(Sybase),那么使用几个不同的小数据库来保持较低的锁争用率可能会更好。
  2. 如果小数据库的表空间不分布在多个磁盘上,则最好使用一个大数据库来仅使用一个(缓冲区/缓存)内存。 我认为这种情况很少发生。
  3. 使用(A)是因为与性能不同的原因而更好地进行缩放。 您可以在需要时在不同的(更新/更快)硬件上移动热点数据,而无需触及其他数据库。 在我以前的公司,这种方法总是比变体(B)便宜(没有新的许可证)。

我个人更喜欢(A)有理由3。

当没有常识或简单的数学背后,设计,建筑,计划和伟大的想法都会失败。 一些更多的练习和/或经验有帮助…这里有一个简单的数学计算,为什么10个连接5个连接的池与1个连接50个连接池不同:每个池配置有最小和最大打开连接,事实是它将通常使用(99%的时间)最小数量的50%(在5分钟的情况下为2-3),如果它使用的更多,那么该池配置错误,因为它始终打开和关闭连接(昂贵) )…所以我们10个池,每个5分钟连接= 50个开放连接…意味着50个TCP连接; 在它们之上有50个JDBC连接…(你调试了JDBC连接吗?你会惊讶地发现有多少元数据流…)如果我们有1个池(服务于上面相同的基础设施),我们可以设置最小值简单到30,因为它能够更有效地平衡额外的东西……这意味着更少的JDBS连接。 我不了解你,但对我而言,这是很多……细节中的魔鬼 – 你在每个游泳池中留下的2-3个连接,以确保它不会一直打开/关闭..甚至不想进入10个游泳池管理的开销…(我不想每个人都维持10个游泳池,那么另一个不同,是吗?)现在你让我开始这个,如果它是我,我将“包装”数据库(数据源)与一个应用程序(服务层任何人?),将提供差异服务(REST / SOAP / WS / JSON – 选择你的毒药),我的应用程序甚至不会知道关于JDBC,TCP等等哦,等谷歌有它 – GAE …