多租户:每个租户有一个数据库
本文关键字:有一个 数据库 | 更新日期: 2023-09-27 18:18:45
我们正在开发一个多租户应用程序。在体系结构方面,我们为业务逻辑设计了共享中间层,为数据持久性为每个租户设计了一个数据库。也就是说,业务层将与每个租户的数据库服务器建立一组连接(连接池)。这意味着应用程序为每个租户维护单独的连接池。如果我们期望大约5000个租户,那么这个解决方案需要高资源利用率(每个租户之间的应用程序服务器和数据库服务器之间的连接),这会导致性能问题。
我们已经通过保持公共连接池解决了这个问题。为了保持跨不同数据库的单一连接池,我们创建了一个名为"App-master"的新数据库。现在,我们总是先连接到"App-master"数据库,然后将数据库更改为特定于租户的数据库。这解决了我们的连接池问题。
此解决方案在本地数据库服务器上运行良好。但是它不能与Azure Sql一起工作,因为它不支持更改数据库。
请提前建议如何维护连接池或更好的方法/最佳实践来处理这种多租户场景。
我以前在使用不同数据库的多个租赁方案中看到过这个问题。有两个重叠的问题;每个租户的web服务器数量,以及租户的总数。第一个是更大的问题——如果你通过ADO.net连接池缓存数据库连接,那么任何特定的客户连接进入一个与数据库有开放连接的web服务器的可能性与你拥有的web服务器的数量成反比。扩展得越多,任何给定的客户就越会注意到每次调用(而不是初始登录)延迟,因为web服务器代表他们初始连接到数据库。每个对非粘性、高度可扩展的web服务器层的调用将越来越不可能找到一个可以重用的现有开放数据库连接。
第二个问题是池中有这么多连接,这可能会造成内存压力或性能低下。
你可以通过建立有限数量的数据库应用服务器(简单的WCF端点)来"解决"第一个问题,这些服务器代表你的web服务器执行数据库通信。每个WCF数据库应用服务器服务于一个已知的客户连接池(东部区域到服务器a,西部区域到服务器B),这意味着对于任何给定的请求,连接池命中的可能性非常高。这也允许你单独扩展对数据库的访问,以访问HTML渲染web服务器(数据库是你最关键的性能瓶颈,所以这可能不是一件坏事)。
第二个解决方案是通过NLB路由器使用特定于内容的路由。这些路由流量基于内容,并允许您通过客户分组(西部地区,东部地区等)细分您的web服务器层,因此,每组web服务器具有更少数量的活动连接,相应增加了获得开放和未使用连接的可能性。
这两个问题通常都是缓存的问题,你越向外扩展,作为一个完全"无粘性"的架构,任何调用碰到缓存数据的可能性就越小——无论是缓存的数据库连接,还是读缓存的数据。管理用户连接以允许最大可能的缓存命中对于保持高性能非常有用。
限制每个应用服务器连接池数量的另一种方法是使用应用请求路由(Application Request Routing, ARR)来划分租户并将其分配给web层的子集。这就形成了一个更具可扩展性的"pod"架构,其中"pod"是一个web/应用服务器的小集合,与数据库的子集相耦合。这里有一篇关于这种方法的好文章:http://azure.microsoft.com/blog/2013/10/31/application-request-routing-in-csf/
如果你正在构建一个多租户DB应用程序Azure,你还应该检查新的Elastic Scale客户端库,它简化了依赖数据的路由,并促进了跨分片查询和管理操作。http://azure.microsoft.com/en-us/documentation/articles/sql-database-elastic-scale-documentation-map/