1. 程式人生 > >Ruby操作MongoDB(進階一)-建立資料庫客戶端連線

Ruby操作MongoDB(進階一)-建立資料庫客戶端連線

    在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_timeoutmax_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操作。