连接池策略:好、坏还是丑陋?

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

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

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

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

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


答案 1

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

1)更大的可扩展性 - 因为如果需要,每个分片都可以位于单独的硬件上。

2)更高的可用性 - 因为单个分片的故障不会影响其他分片

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

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

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


答案 2

如果您有一个数据库和两个连接池(每个池有 5 个连接),则您有 10 个数据库连接。如果您有 5 个连接池,每个池有 2 个连接,则您有 10 个数据库连接。最后,您有 10 个数据库连接。数据库不知道您的池是否存在,也不知道。

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

至于“每个应用程序1个数据库”,如果你不是在为每个数据库使用单独的数据库实例,那么基本上没关系。

如果您有一个托管 5 个数据库的 DB 服务器,并且您与每个数据库有连接(例如,每个数据库 2 个连接),则与托管单个数据库的同一数据库相比,这将消耗更多的开销和内存。但是,这种开销充其量是微不足道的,并且在具有GB大小的数据缓冲区的现代计算机上完全微不足道。超过某一点,数据库所关心的只是将数据页从磁盘映射和复制到RAM,然后再复制回来。

如果您有一个在数据库之间重复的大型冗余表,那么这可能会造成潜在的浪费。

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

因此,只要您为所有应用程序访问数据库服务器的单个实例,连接池等在大局中并不重要,因为服务器将根据需要在客户端之间共享所有内存和资源。


推荐