rails 数据库连接池的工作原理

Posted

技术标签:

【中文标题】rails 数据库连接池的工作原理【英文标题】:How rails database connection pool works 【发布时间】:2016-03-24 20:31:18 【问题描述】:

我正在学习rails数据库连接池的概念。在 Rails 应用程序中,我将池大小定义为 5。

我对连接池大小的理解如下。

    当服务器启动时,rails 会自动创建在 database.yml 文件中定义的 n 个连接。就我而言,它将创建 5 个连接,因为池大小为 5。

    在每个 http 请求上,如果需要访问数据库,rails 将使用连接池中的可用连接来处理请求。

但我的问题是,如果我一次达到 1000 个请求,那么大多数请求将无法访问数据库连接,因为我的连接池大小只有 5。

我上面对rails连接池的理解对吗?

谢谢,

【问题讨论】:

【参考方案1】:

目的: 数据库连接不是线程安全的;所以 ActiveRecord 为每个线程使用单独的数据库连接。

限制因素: 数据库连接总数受您使用的数据库服务器(例如 Posgres:default is typically 100 or lesser)、应用服务器的配置(可用进程/线程数)和 Active Record 的配置:Connection Pool 默认为 5 的限制。

池大小: Active Record 的池大小是针对单个进程的。一个线程使用来自该池的连接并在之后自动释放它。 (除非你自己产生一个线程,否则你必须手动释放它)。如果您的应用程序在多个进程上运行,则每个进程都有 5 个数据库连接。如果您的服务器同时遇到 1000 个请求,它将在这些连接之间分配请求,当它满了时,其余的请求等待轮到它们。

阅读更多:https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

【讨论】:

所以如果我的网络服务器是单进程,那么只有一个连接池,如果是多进程,那么连接池的总数将等于进程数。对吗?? 是的,没错。但通常情况下,应用程序应该基于多个进程/线程。 如果两个进程同时运行,说进程'A'和进程'B',那么会有两个独立的连接池。如果假设进程“A”创建了两个线程,并且如果这些线程需要访问数据库,那么这些线程将使用哪个连接池。由进程“A”或进程“B”创建的连接池。 当然进程A,实际上是池5,意思是..每个连接都在同一进程的不同线程上可用。 如果我的服务器是多线程的怎么办??我想在这种情况下,我将只有一个连接池,而与同时 HTTP 连接的数量无关。【参考方案2】:

是的,来自文档:

连接池将线程访问同步到有限数量的 数据库连接。基本思想是每个线程签出一个 来自池的数据库连接,使用该连接,并检查 重新连接。 ConnectionPool 是完全线程安全的,并且 将确保连接不能被两个线程使用 同时,只要正确遵循 ConnectionPool 的合同。 它还将处理线程数多于 连接:如果所有连接都已签出,以及一个线程 无论如何都会尝试签出连接,然后 ConnectionPool 将等待 直到其他线程检查了连接。

来源:http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

如果你使用 unicorn 之类的东西作为 http 服务器:

在 Unicorn 中,每个进程都会建立自己的连接池,因此如果您的数据库池设置为 5,并且您有 5 个 Unicorn 工作人员,那么您最多可以有 25 个连接。但是,由于每个独角兽工作者一次只能处理一个连接,那么除非您的应用在内部使用线程,否则每个工作者实际上只会使用一个数据库连接。

【讨论】:

***.com/questions/34251081/… 看到这个链接它指出每个工作进程都会创建一个新的连接池。 好吧,如果你使用 unicorn 之类的东西:在 Unicorn 中,每个进程都会建立自己的连接池,所以如果你的数据库池设置为 5 并且你有 5 个 Unicorn 工作者,那么你最多可以有 25 个连接.但是,由于每个独角兽工作者一次只能处理一个连接,那么除非您的应用在内部使用线程,否则每个工作者实际上只会使用一个数据库连接。 乘客怎么样。我正在使用带有 ngnix 的乘客。 我猜乘客类似于独角兽。乘客创建多个工作进程(应用程序实例)。 您可以使用 'passenger-status' 进行检查,更多信息请阅读:phusionpassenger.com/library/walkthroughs/basics/ruby/…

以上是关于rails 数据库连接池的工作原理的主要内容,如果未能解决你的问题,请参考以下文章

数据库连接池的工作原理

搞软件开发,请你来谈谈数据库连接池的原理吧

数据库连接池的工作原理以及这项技术的产生

如何调试 Rails 连接池的使用情况?

数据库连接池的工作机制

线程池的工作原理