在Ruby的MongoDB2.4.3驱动版本中,通过创建一个Mongo::Client对象来构建一个Ruby的数据库连接。Mongo::Client构造器提供两种构造方式:一是通过提供主机列表和一些可选参数,另外还有通过一个连接URI。创建好的数据库连接默认连接到admin数据库。
1.使用Mongo::Client创建数据库客户端连接
1.1. 单服务器模式创建数据库连接
在单服务器模式下创建数据库连接,只需提供一个主机连接参数。另外,还可以通过消除自动发现步骤强制将集群拓扑转换为单机模式。可以通过下述三种方式创建单服务器模式下的数据库连接
Mongo::Client.new(['127.0.0.1:27017'],:database=>'mydb')
Mongo::Client.new(['127.0.0.1:27017'],:database=>'mydb',:connect=>:direct)
Mongo::Client.new('mongodb://127.0.0.1:27017/mydb')
1.2. 副本集模式创建数据库连接
通过传递一个或多个主机地址参数和副本集名字,可以创建一个到副本集的数据库连接。即使在创建时没有完全提供副本集的所有信息,MongoDB的驱动器的自动探索模式可以找到副本集中的所有成员。创建副本集中的数据库连接可以通过下面的形式创建:
Mongo::Client.new(['127.0.0.1:27017','127.0.0.1:27018'],:database=>'mydb',:replica_set=>'myapp')
Mongo::Client.new('mongdb://127.0.0.1:27017,127.0.0.1:27018/mydb?replicaSet=myapp')
1.3. 共享集群模式创建数据库连接
通过传递一个或多的Mongos 主机,来创建一个共享集群模式。自动探索模式可以限定服务器是mongos实例,但如果你关闭了自动探索模式,就要将shared参数传递到连接中来实现集群模式数据库连接的创建。通过以下三种例子可以创建数据库连接:
Mongo::Client.new(['127.0.0.1:27017'],:database=>'mydb')
Mongo::Client.new(['127.0.0.1:27017'],:database=>'mydb',:connect=>:shared)
Mongo::Client.new('mongodb://127.0.0.1:27017/mydb?connect=shared')
2. 数据库客户端连接参数选项
在使用Mongo::Client时,可以通过多个不同的可选参数来配置驱动的行为,可以通过在构造器中配置这些参数或者将它们通过URI提供给Mongo::Client.
鉴于URI的参数设置方式需要使用驼峰格式,这不是Ruby的标准格式。下面的表格中列出了URI格式的参数配置选项,以及相对应的使用Ruby构造器的参数选项。使用上述两种参数设置方式时需要注意URI参数设置中的选项时间单位是毫秒,而在Ruby构造器中对应的是float类型的秒。
3. URI参数及对应Ruby参数
URI选项 | Ruby选项 |
replicaSet=String | :replica_set=>String |
connect=String | :connect=>Symbol |
ssl=Boolean | :ssl=>true|false |
connectTimeoutMS=Integer | :connect_timeout=>Float |
socketTimeoutMS=Integer | :socket_timeout=>Float |
serverSelectionTimeoutMS=Integer | :server_selection_timeout=>Float |
localThresholdMS=Integer | :local_threshold=>Float |
maxPoolSize=Integer | :max_pool_size=>Integer |
minPoolSize=Integer | :min_pool_size=>Integer |
waitQueueTimeoutMS=Integer | :wait_queue_timeout=>Float |
w=Integer|String | { :write=>{:w=>Integer|String}} |
wtimeoutMS=Integer | { :write=>{:wtimeout=>Float}} |
journal=Boolean | { :write=>{:j=>true|false}} |
fsync=Boolean | { :write =>{:fsync=>true|false}} |
readPreference=String | { :read=>{:mode=>Symbol}} |
readPreferenceTags=String | { :read=>{:tag_sets=>Array<String> }} |
authSource=String | :auth_source=>String |
authMechanism=String | :auth_meth=>Symbol |
authMechanismProperties=Strings |
{ :auth_mech_properties=>{:service_realm=>String ,:canonicalize_host_name=>true|false,:service_name=>String}} |
4. 下面会详细讲解Ruby中每个选项的作用,默认值和类型
参数 | 参数描述 | 参数类型 | 默认值 |
:replica_set | 当使用副本集模式时,该参数用于设置副本集的名字,且可以在启用自动探索模式时通过名字过滤服务器 | String |
none |
:ssl | 通知客户端通过SSL连接到服务器 | Boolean | false |
:ssl_cert | 用于设置证书文件路径,该证书用于识别鉴定到MongoDB连接是否有效。如果设置了该选项,将会比:ssl_cret_string的值和:ssl_sret_object的值具有更高的使用优先级 | String | none |
:ssl_cert_string | 该string字段包含了使用PEM编码的用于鉴别连接有效性的证书信息。如果设置了该参数,它比:ssl_cret_object的值具有更高的使用优先级 | String | none |
:ssl_cert_object | 使用OpenSSL::X509::Certificate证书鉴别到MongoDB的连接 |
OpenSSL::X509: :Certificate |
none |
:ssl_key | 鉴别连接有效性的私钥文件。虽然秘钥文件与证书存储在同一个文件,但是两个需要被精确匹配。如果设置了该参数,它比:ssl_key_string和:ssl_key_object具有更高的使用优先级 | String | none |
:ssl_key_string | 包含用于鉴别连接有效性的使用PEM编码的私钥字符串信息。如果设置了这个参数,它比:ssl_key_object具有更高的使用优先级 | String | none |
:ssl_key_object | 鉴别连接有效性的私钥对象 | OpenSSL::PKey | none |
:ssl_key_pass_phrase | 私钥的密码信息 | String | none |
:ssl_ca_cert |
一组把授权证书连接起来的证书信息的存储路径 ,这些授权证书用于从连接的另一端验证证书是 否通过。参数:ssl_verfiy的使用需要设置 :ssl_ca_cret,:ssl_ca_cret_string, :ssl_ca_cret_object三个参数中的一个。 |
String | none |
:ssl_ca_cert_string |
包含一组把授权证书连接起来的证书信息的字符串 ,这些授权证书用于从连接的另一端验证证书是否 通过。参数:ssl_verfiy的使用需要 设置:ssl_ca_cret,:ssl_ca_cret_string, :ssl_ca_cret_object三个参数中的一个。 |
String | none |
:ssl_ca_cert_object |
代表了把授权证书连接起来的证书信息的OpenSSL::X509::Certificate数组,这 些授权证书用于从连接的另一端验证证书会否通过。参数:ssl_verfiy的使用需要设置:ssl_ca_cret,:ssl_ca_cret_string,:ssl_ca_cret_object三个参数中的一个。 |
Array<OpenSSL::X509:: Certificate> |
none |
:ssl_verify | 用于设置是否进行对等证书验证 | Boolean | false |
:connect_timeout | 创建一个socket连接,抛出异常之前的等待时间(秒) | Float | 10秒 |
:socket_timeout | 在一个socket执行操作抛出异常之前的等待时间(秒) | Float | 5秒 |
:max_pool_size | 单个服务器的连接池的最大连接数 | Integer | 5 |
:min_pool_size | 单个服务器的连接池的最小连接数 | Integer | 1 |
:wait_queue_timeout | 等待连接池中连接变为有效状态的等待时间 | Float | 1 |
:write |
具体设置与写相关的Hash类型的参数。其值可以为:w,:wtimeout,:j,:fsync 如{ :write =>{ :w=>2}} |
Hash | {:w=>1} |
:read |
Hash类型的参数,用于具体设置首选读 模式以及对于选定服务器的标签集合。 其值可以设置为:mode和:tag_sets。 例如{ :read=>{ :mode=>secondary, :tag_sets=>["berlin"]}} |
Hash | {:mode =>:primary} |
:auth_source | 具体设置了授权源信息 | String | 2.6及其之后版本,如果提供了授权证书,则默认为admin;否则的话就是当前的数据库 |
:auth_mech |
具体设置使用的授权机制 。可以是下述值的其中之一::mongodb_cr,:mongodb_x509,:plain,:scram |
Symbol | MongoDB3.0后的版本,如果用户提供了资格证书但是又没有设置:auth_mech属性,则默认为:scram。2.6版本之前,默认为:mongodb_cr |
:auth_mech_ properties |
提供了额外的授权机制属性 | Hash | none |
:user | 认证使用的用户名称 |
String | none |
:password | 认证使用的用户密码 | String | none |
:connect | 覆盖驱动的自动探索特性,并且强制将集群拓扑结构转变为一个特定的类型。包括::direct,:replica_set或者:shared | Symbol | none |
:heartbeat_ frequency |
多个监视器异步刷新服务器状态的时间(秒) | Float | 30 |
:database | 需要连接的数据库名字 | String | admin |
:server_selection_ timeout |
选定一个合适的服务器去执行某些操作,在抛出异常之前的等待时间 | Float | 30 |
:local_threshold | 设置了最近的服务器和可以被选中的服务器之间切换的最大延迟时间 | Float | 0.015 |
5. 超时相关参数的设置细节
5.1连接超时:
在初始化到服务器的连接时,该参数是用来设置在抛出连接异常之前的等待时间。这个超时参数也被用来设置监视器ping它们服务器的等待时间。默认值是10秒
5.2套接字超时 socket-timeout
进行套接字操作时抛出异常之前的等待时间。这个时间的设置需要考虑网络延时和炒作间隔。默认值没有值,默认值是正无穷大。由于scoket_timeout设置不会停止服务器上的操作,即使超过了socket_timeout的时间,一个需要长时间运行的操作也会继续在服务器上运行。因此我们在使用时一般使用每秒max_time_ms代替。
5.3服务器选择超时server_selection_timeout
数据库驱动选择合适的服务器开展操作时,抛出异常之前的等待时间,默认值30s。该值设置时需要考虑故障转移时选举服务器选举的速度。
5.4本地延迟local_threshold
最近的服务器和被认为可进行操作的服务器之间的最大延时。默认值0.015。注意区分一下,
注意:该值不是驱动和服务器之间的延迟窗口,而是最近的服务器和其他服务器之间的延迟。
5.5 排队等待超时时间 wait_queue_timeout
等待连接池中的连接可用的等待时间。当出现下述两种场景时:一是在多线程应用场景下出现多个超时的错误,还有就是当操作占用时间较长,我们需要考虑增加该值。默认值是1s。
5.6 最大连接池大小 max_pool_size
单个服务器的连接池最大的连接数,默认为5
5.7 最小的连接池大小
单个服务器的连接池最小的连接数,增加这个值可以提高初始化时池中可用的连接数,减少后续创建新连接的开销。默认大小1.
5.8 max_time_ms
用于具体化设置一个特定操作的参数,它定义了在一个游标上处理操作的累计总时间限制。如果想要服务器上的操作可以被中断,请使用该参数来代替socket_timeout参数设置。
注意:socket_timeout和max_time_ms的区别是,超过设定时间后,后者会中断服务器上的操作
6. 连接池细节
在MongoDB的拓扑结构中,Mongo::Client实例有一个单服务器上连接池的属性。当你的应用需要操作多个并行的MongoDB连接时,连接池就会为其提供服务。没有线程相关的连接。
MongoDB的拓扑结构中每台服务器上还预留了一个额外的用于监控服务器状态的连接。使用属性max_pool_size来设定每个连接池的大小被,默认值是5。当你的应用中一个线程开始操作MongoDB数据库时,它会尝试从连接池中获取到一个数据库连接供后续操作使用。如果池中存在多个可用空闲连接,它会从池中挑选出一个连接并且用该连接来进行数据库操作。如果当前池中无可用连接,并且池中的连接数小于max_pool_size,就会创建一个新的连接。如果池中所有连接均不可用,且池的大小已达到最大值,该线程会等待池中的被其他线程占用的连接被释放返回。
线程的等待时间也是可配置的。使用wait_queue_timeout,时间单位为秒。该参数确定了当连接池中午可用连接时,一个线程等待连接被返回到池中变为可用连接的等待时间。如果等待时间到了,就会抛出Timeout::Error错误。默认值为1s。
你可以使用min_pool_size来设置连接池初始化时池中的连接数目。如果你的应用会面临尖峰负荷,而且你想避免尖峰负荷时创建新连接的延迟,设置这个参数会有所帮助。默认值是1.
下面讲述一个实例,为多线程应用创建一定数目的连接:一个客户端连接到一个3节点的副本集而且打开了3个监控sockets,而且也为应用打开了支持其多线程场景的并行连接操作多个sockets连接,连接数最大不超过max_pool_size。如果应用了仅仅连接到primary节点(默认),这样只会有primary节点的连接增长了且最大值为8(5个到primary节点连接池的连接+3个监控连接)。如果应用的偏好读取方式是查询secondary节点,那么secondary节点的连接池也会增大,并达到最大值18(5+5+5+3)。
默认的Mongo::Client配置方式适用于绝大多数应用场景:
client=Mongo:Client.new(["localhost:27017"])
每个处理创建一个client连接,在所有的后续操作中重用这个client。为每个请求创建一个client连接是一个共性的错误,这种配置方式是非常低效的而且这也违背了client的设计原则。
为了支持但处理步骤中的极端并行MongoDB连接,我们需要增加max_pool_size参数值大小:
client=Mongo::Client.new(["localhost:27017"],:max_pool_size=>200)
任意数据的线程都可以等待连接变为可用,它们的等待时间(默认1s)可以通过wait_queue_timeout设置。:
client=Mongo::Client.new(["localhost:27017"],:wait_queue_timeout=>0.5)
当使用任意线程在client上调用close方法,所有的连接都会被关闭。
下一节继续讲解Ruby MongoDB的进阶,CRUD操作。
本文出自 “techFuture” 博客,谢绝转载!