一点背景
多年来,我一直在使用Apartment gem来运行多租户应用程序。现在最近有需要将数据库扩展到单独的主机,数据库服务器根本无法跟上(读和写都变得太多了)-是的,我将硬件扩展到最大(专用)硬件,64核,raid 10中的12 Nvm-e驱动器,384Gb ram等)。
我正在考虑按租户执行此操作(1个租户= 1个数据库连接配置/池),因为这是一种“简单”且有效的方法,可以在number-of-tenants
不进行应用程序代码更改的情况下获得多达两倍的容量。
现在,我正在Rails 4.2 atm上运行,不久将升级到5.2。我可以看到Rails 6增加了对每个模型的连接定义的支持,但这并不是我真正需要的,因为我为20个租户中的每一个都有一个完全镜像的数据库架构。通常,我会针对每个请求(在中间件中)或每个后台作业(sidekiq中间件)切换“数据库”,但是,这在Apartment gem中是微不足道的,并已得到处理,因为它只是search_path
在Postgresql中进行设置,而实际上并未更改实际连接。切换到每个租户托管策略时,我将需要根据请求切换整个连接。
问题:
ActiveRecord::Base.establish_connection(config)
每个请求/后台工作-但是,正如我也了解的那样,这将触发进行全新的数据库连接握手,并在Rails中产生一个新的数据库池-对吗?我猜想对我的应用程序的每个请求都会产生这种开销,这会降低性能。据我了解,多租户应用程序有4种模式:
1.专用模型/多种生产环境
每个实例或数据库实例完全托管不同的租户应用程序,并且租户之间不共享任何内容。
这是1个实例应用程序和1个租户的1个数据库。就像您仅服务一名租户一样,开发将很容易。但是如果您有100个租户,这将是开发人员的噩梦。
2.房客的物理隔离
所有租户都有1个实例应用程序,但1个租户有1个数据库。这就是您要搜索的内容。您可以使用ActiveRecord::Base.establish_connection(config)
,或使用gems,或按照其他建议更新到Rails 6。请参阅下面的(2)答案。
3.隔离的模式模型/逻辑隔离
在隔离模式中,租户表或数据库组件在逻辑模式或名称空间下分组,并与其他租户模式分开,但是该模式托管在同一数据库实例中。
1个实例应用程序和1个用于所有租户的数据库,就像您使用公寓gem一样。
4.部分隔离的组件
在此模型中,具有共同功能的组件在租户之间共享,而具有唯一或不相关功能的组件则被隔离。在数据层,公用数据(例如标识租户的数据)被分组或保存在单个表中,而租户特定的数据在表或实例层被隔离。
至于(1),ActiveRecord::Base.establish_connection(config)
如果正确使用它,则不要与每个请求握手到db。您可以在此处查看并在此处阅读所有评论。
至于(2),如果不想使用establish_connection
,可以使用gem multiverse(适用于rails 4.2)或其他gem。或者,如其他建议,您可以更新到Rails 6。
编辑:Multiverse gem正在使用establish_connection
。它将附加database.yml
,并创建一个基类,以便每个子类共享相同的连接/池。基本上,它减少了我们的使用工作量establish_connection
。
至于(3),答案是:
如果您没有那么多租户,并且您的应用程序非常复杂,建议您使用专用模型模式。因此,您选择了一个应用程序实例=一个与特定租户的特定连接。您不必通过添加多个数据库连接来使您的应用程序更复杂。
但是,如果您有很多租户,建议您根据业务流程使用租户的物理隔离或部分隔离的组件。
无论哪种方式,您都必须更新/重写您的应用程序以符合新的体系结构。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句