一些背景
我多年来一直在使用Apartment gem运行一个多租户应用程序。现在最近,将数据库扩展到单独的主机中的需求出现了,数据库服务器无法再保持同步(读写都变得太多了)-是的,我已经将硬件扩大到了极限(专用硬件、64个核心、12个Nvm-e驱动器组成RAID 10、384Gb ram等)。
我正在考虑为每个租户(1个租户=1个数据库连接配置/池)执行此操作,因为这将是一种“简单”且高效的方法,可使容量增加number-of-tenants
-倍,而不必进行大量的应用代码更改。
现在,我正在运行rails 4.2,很快就会升级到5.2。我可以看到rails 6添加了支持每个模型连接定义,但这并不是我所需要的,因为我的20个租户中每个租户都有完全相同的数据库模式。通常情况下,我会根据请求(在中间件中)或后台作业(sidekiq中间件)切换“数据库”,但目前这很简单,并由Apartment gem处理,因为它只是在Postgresql中设置search_path
并不会真正更改实际连接。当切换到每个租户的托管策略时,我将需要在每个请求中完全切换连接。
问题:
- 我知道每个请求/后台作业都可以使用
ActiveRecord::Base.establish_connection(config)
,但是据我所知,这会触发在Rails中完全新的数据库连接握手并生成新的数据库池 - 对吧?我猜这样做会对我的应用程序在每个请求上产生巨大的开销,从而影响性能。 - 因此,我想知道是否有人可以看到在rails中例如预先建立多个(总共20个)数据库连接/池的选项(例如在应用程序引导时),然后只需在每个请求之间切换这些池?以便数据库连接已经建立并准备好使用。
- 这一切只是一个不好的主意吗?我是否应该寻找其他方法?例如,1个应用实例=一个特定租户的特定连接。或者其他什么。
master
分支中添加了你需要的功能。运行 Rails Edge 是一个选项,或者将该功能回溯到你当前的 Rails 版本中? - spickermannActiveRecord::Base.connected_to(shard: :shard_one) do ... end
的意思是池将被(重新)使用,而不是每次创建一个全新的连接? - Ben