我正在学习Rails数据库连接池的概念。在Rails应用程序中,我定义了5个连接的池大小。
我的理解是:
当服务器启动时,Rails会自动创建在database.yml文件中定义的n个连接。在我的情况下,它将创建5个连接,因为池大小是5。
每次http请求需要访问数据库时,Rails将使用连接池中可用的连接来处理请求。
但我的问题是,如果我同时发出1000个请求,大多数请求将无法访问数据库连接,因为我的连接池大小仅为5。
我的上述理解是否正确?
谢谢。
我正在学习Rails数据库连接池的概念。在Rails应用程序中,我定义了5个连接的池大小。
我的理解是:
当服务器启动时,Rails会自动创建在database.yml文件中定义的n个连接。在我的情况下,它将创建5个连接,因为池大小是5。
每次http请求需要访问数据库时,Rails将使用连接池中可用的连接来处理请求。
但我的问题是,如果我同时发出1000个请求,大多数请求将无法访问数据库连接,因为我的连接池大小仅为5。
我的上述理解是否正确?
谢谢。
目的:
数据库连接不是线程安全的,因此ActiveRecord为每个线程使用单独的数据库连接。
限制因素:
总数据库连接数受您使用的数据库服务器(例如Posgres:默认通常为100或更少),应用程序服务器的配置(可用进程/线程数)和Active Record的配置限制: 连接池 默认为5。
池大小:
Active Record的池大小是针对单个进程的。一个线程从这个池中使用一个连接,然后自动释放它。 (除非你自己生成了一个线程,那么你就必须手动释放它)。如果您的应用程序在多个进程上运行,则每个进程都会有5个数据库连接。如果您的服务器同时收到1000个请求,则它将把这些请求分配到这些连接中,当它已满时,其余请求会等待它们的机会。
阅读更多信息:
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html
是的,来自文档:
连接池同步线程对有限数量的数据库连接的访问。基本思路是每个线程从池中检出一个数据库连接,使用该连接,并将连接还回。ConnectionPool完全是线程安全的,并确保只要正确遵循ConnectionPool的协议,连接不能被两个线程同时使用。它还处理线程数大于连接数的情况:如果所有连接都已经被检出,并且一个线程尝试检出连接,则ConnectionPool会等待直到其他某个线程检入连接。
来源:http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html
如果您使用类似独角兽(Unicorn)这样的HTTP服务器:
在Unicorn中,每个进程建立自己的连接池,所以如果您的DB池设置为5并且您有5个Unicorn工作进程,则最多可以有25个连接。但是,由于每个独角兽工作进程一次只能处理一个连接,因此除非您的应用程序在内部使用线程,否则每个工作进程实际上只使用一个数据库连接。