三、接著(zhù)介紹 Connect Time Load Balancing
Connect Time Load Balancing 就是指不從連接池中取得已有連接,而是直接連接 Oracle 數據庫時(shí)的 Load Balance。Connect Time Load Balancing 又細分為兩種,分別是客戶(hù)端的 Connect Time Load Balancing 和 Server 端的 Connect Time Load Balancing。
在 Oracle RAC 11gR2 之前,客戶(hù)端的 Connect Time Load Balancing 非常容易實(shí)現,只需要在相關(guān)的 tnsnames.ora 中指定多個(gè) vip,同時(shí)指定 LOAD_BALANCE=ON 就好了。如下所示:
(DESCRIPTION= (ADDRESS_LIST= (LOAD_BALANCE=ON) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-vip)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=RAC10g)) )
這樣客戶(hù)端在連接的時(shí)候,會(huì )隨機地從上述 4 個(gè) VIP 地址中選一個(gè)來(lái)連接 Oracle 數據庫以達到 Load Balance 的目的。
之前已經(jīng)提到,Oracle RAC 11gR2 中引入了 SCAN(Single Client Access Name),并且客戶(hù)端缺省是通過(guò) SCAN 來(lái)連接整個(gè) RAC 環(huán)境的,如果使用了 DNS 或者 GNS (Grid Naming Service),那么最多可以有 3 個(gè) SCAN VIP 和 3 個(gè) SCAN Listener;如果沒(méi)有使用 DNS 或者 GNS,而是選擇使用 hosts 文件,則只會(huì )有 1 個(gè) SCAN VIP 和 1 個(gè) SCAN Listener。
這里假設你在 tnsnames.ora 中這樣配置:
(DESCRIPTION = (LOAD_BALANCE=ON) (ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g))) 嚴格意義上說(shuō),只有在 RAC 環(huán)境有 1 個(gè)以上 SCAN VIP 的時(shí)候,上述 LOAD_BALANCE=ON 才有意義——它表示的是客戶(hù)端在連接 Oracle 11gR2 RAC 的時(shí)候,會(huì )隨機的選擇三個(gè) SCAN VIP 中的一個(gè)來(lái)連接,所以 Oracle 11gR2 RAC 的客戶(hù)端 Connect Time Load Balancing 實(shí)際上是針對 SCAN VIP 而言的,而不是像 Oracle RAC 10gR2 /9iR2 那樣直接針對 RAC 節點(diǎn)的 VIP(Oracle RAC 9iR2 里沒(méi)有 VIP,此時(shí) Connect Time Load Balancing 是針對 public ip)。
當使用了 hosts 文件來(lái)指定 SCAN VIP 的時(shí)候,客戶(hù)端 Connect Time Load Balancing 實(shí)際上是不存在的,因為現在整個(gè) RAC 環(huán)境只有 1 個(gè) SCAN VIP。
現在再來(lái)介紹一下 Server 端的 Connect Time Load Balancing。Server 端的 Connect Time Load Balancing 相對來(lái)說(shuō)要復雜一些,下面針對 Oracle 數據庫不同的版本來(lái)分別加以說(shuō)明。
首先要說(shuō)明的是:無(wú)論是 Oracle RAC 9iR2/10gR2,還是 Oracle RAC 11gR2,它們的 Server 端 Connect Time Load Balancing 都是通過(guò)聯(lián)合使用 local_listener 和 remote_listener 來(lái)實(shí)現的。
先來(lái)介紹 Oracle RAC 9iR2 下的 Server 端 Connect Time Load Balancing:
這里假設是一個(gè) 4 節點(diǎn)的 Oracle RAC 9iR2,tnsnames.ora 中的連接串是如下這樣:
(DESCRIPTION= (FAILOVER=ON) (ADDRESS_LIST= (LOAD_BALANCE=ON) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-ip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-ip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-ip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-ip)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=RAC9i)) ) 再在各個(gè)節點(diǎn)的 tnsnames.ora 中加入如下設置:
LISTENER_RAC1 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-ip)(PORT = 1521))LISTENER_RAC2 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-ip)(PORT = 1521))LISTENER_RAC3 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-ip)(PORT = 1521))LISTENER_RAC4 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-ip)(PORT = 1521))LISTENERS_RAC = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-ip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-ip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-ip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-ip)(PORT = 1521)) ) 然后只需要在初始化參數文件里加入如下設置就能實(shí)現 Server 端 Connect Time Load Balancing 了:
RAC1.local_listener=LISTENER_RAC1RAC2.local_listener=LISTENER_RAC2RAC3.local_listener=LISTENER_RAC3RAC4.local_listener=LISTENER_RAC4*.remote_listener=LISTENERS_RAC
當做了上述設置后,上述 4 個(gè)節點(diǎn)的 listener 實(shí)際上除了知道本節點(diǎn)負載的情況之外,同時(shí)也知道了其余節點(diǎn)的負載情況。所以當先經(jīng)過(guò)一層客戶(hù)端的 Connect Time Load Balancing,比如這里隨機地連到了第二個(gè)節點(diǎn)上的 listener(即 LISTENER_RAC2)上,當 LISTENER_RAC2 發(fā)現自身的負載較高,是有可能把你的連接請求轉移(redirect)到其余負載較低的節點(diǎn)的 listener 上的——這就是所謂的第二層 Load Balancing,也就是 server 端的 Connect Time Load Balancing。
Oracle RAC 9iR2 里 server 端的 Connect Time Load Balancing 的依據是各節點(diǎn) CPU 的負載(CPU runqueue-based load)或各節點(diǎn)所連接的 session 的數量。我們可以在相應節點(diǎn)的 listener.ora 中通過(guò)參數 prefer_least_loaded_node_
接著(zhù)再來(lái)看 Oracle RAC 10gR2 下的 Server 端 Connect Time Load Balancing。Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 也是通過(guò)聯(lián)合使用 local_listener 和 remote_listener 來(lái)實(shí)現的,只不過(guò) Oracle RAC 10gR2 里引入了 VIP,所以這里 local_listener 和 remote_listener 一定是要監聽(tīng) VIP,而不是像 Oracle RAC 9iR2 那樣監聽(tīng) public ip 了。
這里假設是一個(gè) 4 節點(diǎn)的 Oracle RAC 10gR2,tnsnames.ora 中的連接串是如下所示(注意這里的連接地址已經(jīng)是 VIP 了):
(DESCRIPTION= (FAILOVER=ON) (ADDRESS_LIST= (LOAD_BALANCE=ON) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-vip)(PORT=1521)) (ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-vip)(PORT=1521)) ) (CONNECT_DATA=(SERVICE_NAME=RAC10g)) ) 再在各個(gè)節點(diǎn)的 tnsnames.ora 中加入如下設置(注意這里監聽(tīng)的已經(jīng)是 VIP了):
LISTENER_RAC1 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-vip)(PORT = 1521))LISTENER_RAC2 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-vip)(PORT = 1521))LISTENER_RAC3 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-vip)(PORT = 1521))LISTENER_RAC4 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-vip)(PORT = 1521))LISTENERS_RAC = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-vip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-vip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-vip)(PORT = 1521)) (ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-vip)(PORT = 1521)) ) 然后只需要在初始化參數文件里加入如下設置就能實(shí)現 Server 端 Connect Time Load Balancing 了:
RAC1.local_listener=LISTENER_RAC1RAC2.local_listener=LISTENER_RAC2RAC3.local_listener=LISTENER_RAC3RAC4.local_listener=LISTENER_RAC4*.remote_listener=LISTENERS_RAC
當做了上述設置后,與 Oracle RAC 9iR2 一樣,也可以實(shí)現 Server 端 Connect Time Load Balancing。只不過(guò)這里判斷負載的依據有了變化。(注:如果客戶(hù)端不能解析 RAC1-vip 這樣的主機名,則在連接時(shí)很可能報 ORA-12545 錯誤,local_listener 對應的 TNS 配置中應該使用 VIP 地址,而不要用主機名,這里寫(xiě)主機名只是出于演示的目的)
Oracle 10g 引入了 Service,所以在 Oracle 10g 里,判斷負載的依據就跟 Service 綁定在了一起。Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 判斷負載的依據是由相關(guān) service 的參數 CLB_GOAL 和 GOAL 聯(lián)合來(lái)決定的。
Oracle RAC 10gR2 里的負載可以通過(guò) v$servicemetric 來(lái)查看:
SQL> desc v$servicemetric;Name Type Nullable Default Comments ----------------- ------------ -------- ------- -------- BEGIN_TIME DATE Y END_TIME DATE Y INTSIZE_CSEC NUMBER Y GROUP_ID NUMBER Y SERVICE_NAME_HASH NUMBER Y SERVICE_NAME VARCHAR2(64) Y CTMHASH NUMBER Y ELAPSEDPERCALL NUMBER Y CPUPERCALL NUMBER Y DBTIMEPERCALL NUMBER Y CALLSPERSEC NUMBER Y DBTIMEPERSEC NUMBER Y GOODNESS NUMBER Y DELTA NUMBER Y FLAGS NUMBER Y
其中每個(gè) service 在 v$servicemetric 里會(huì )對應兩條記錄,一條記錄每5秒采樣一次,另外一條記錄每 60 秒采樣一次。
這里衡量每個(gè) service 的負載情況,主要是通過(guò) GOODNESS、DELTA和FLAGS 這三列來(lái)說(shuō)明的,如下是它們各自的含義:
GOODNESS 表示這個(gè)節點(diǎn)成為 Server 端 Connect Time Load Balancing 的目標節點(diǎn)的可能性,這個(gè)值越高,可能性就越低。即這個(gè) service 在某個(gè)節點(diǎn)上的 GOODNESS 的值越大,則表明這個(gè)節點(diǎn)的負載越重,這個(gè)節點(diǎn)成為 Server 端 Connect Time Load Balancing 的目標節點(diǎn)的可能性就越低。
DELTA 表示當節點(diǎn)增加了一個(gè)額外的 session 后對負載增加情況的估算。
FLAGS 是一個(gè)標志位,它的各個(gè)值的含義如下:
0 – all good 1 – blocked 2 – crossed threshold 4 – goodness unknown (usually when no sessions connected) 每個(gè) service 所對應的 CLB_GOAL 實(shí)際上表示 Client Load Balance Goal,它的值要么為 LONG,要么為 SHORT,默認值是 LONG。
LONG 和 SHORT 的區別是:LONG 是 CLB_GOAL 的缺省值,通常用于那些需要長(cháng)時(shí)間保持的連接,比如一些第三方的連接池或者 SQL*Form 應用;而 SHORT 則通常用于那些連接持續時(shí)間較短的應用,如果使用了支持訂閱 LBA(Load Balancing Advisory)的連接池,則應該把 CLB_GOAL 的值設為 SHORT。
如果一個(gè) service 的 CLB_GOAL 被設為 LONG,則意味著(zhù)衡量這個(gè) service 所在節點(diǎn)的負載情況是依據連接到這個(gè)節點(diǎn)的 session 的數量,此時(shí)與 CLB_GOAL 相對應的另外一個(gè)參數 GOAL 的設置將不再生效。
如果你把一個(gè) service 的 CLB_GOAL 設為 SHORT,則意味著(zhù)衡量這個(gè) service 的負載情況是依據 LBA,在根據 LBA 判斷負載情況時(shí)根據對應 service 的 GOAL 的設置的值的不同,又可以細分為是依據 SERVICE_TIME 還是依據 THROUGHPUT。也就是說(shuō),每個(gè) service 所對應的 GOAL 實(shí)際上表示 LBA GOAL,它的值要么為 THROUGHPUT,要么為 SERVICE_TIME,要么是 NONE,GOAL 的默認值是 NONE。即當你把 CLB_GOAL 設為 SHORT 后,這種情況下 Server 端 Connect Time Load Balancing 判斷負載的依據就是由 GOAL 的設置來(lái)決定了。
GOAL 所對應的三個(gè)值 THROUGHPUT、SERVICE_TIME 和 NONE 的區別是:
THROUGHPUT:表示判斷負載的依據是吞吐量(THROUGHPUT),這通常用于那些并發(fā)的 transaction 具有相似的完成時(shí)間、相似的完成速率的系統,比如在線(xiàn)交易系統;
SERVICE_TIME:表示判斷負載的依據是響應時(shí)間(response time),這通常用于那些并發(fā)的 transaction 具有不同的完成時(shí)間、不同的完成速率的系統,比如在線(xiàn)購物系統,不同的人完成一次在線(xiàn)購物,所購買(mǎi)的產(chǎn)品、所耗費的時(shí)間可能有很大差異;
NONE:表示不啟用 LBA。
如果再結合 service 的 CLB_GOAL 和 GOAL,以及 v$servicemetric,就可以歸納出 Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 判斷負載的依據:
1、Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 默認情況下判斷負載的依據是連接到每個(gè)節點(diǎn)的 session 的數量,即當 CLB_GOAL 為默認值 LONG 的時(shí)候,v$servicemetric 的對應 service 的 GOODNESS=number of connected sessions,DELTA=1,注意此時(shí) LBA 并沒(méi)有啟用;
2、Oracle RAC 10gR2 里如果把 service 的 CLB_GOAL 設為 SHORT,同時(shí)把 GOAL 設為 THROUGHPUT 或 SERVICE_TIME,則意味著(zhù) Server 端 Connect Time Load Balancing 判斷節點(diǎn)負載的依據是 LBA。此時(shí)如果 GOAL 設為 THROUGHPUT,則 v$servicemetric 的對應 service 的 GOODNESS 值是根據 CPUPERCALL 和 DBTIMEPERCALL 來(lái)計算;如果 GOAL 設為 SERVICE_TIME,則 v$servicemetric 的對應 service 的 GOODNESS 值是根據 CALLSPERSEC 和 DBTIMEPERSEC 來(lái)計算。
接下來(lái)再看一下 Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing:
Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing 和 Oracle RAC 10gR2 下的 Server 端 Connect Time Load Balancing 類(lèi)似,只不過(guò)因為 Oracle RAC 11gR2 里引入了 SCAN,所以 Oracle RAC 11gR2 環(huán)境下 remote_listener 應設置為 SCAN:port。
這里假設是一個(gè) 4 節點(diǎn)的 Oracle RAC 11gR2 環(huán)境,tnsnames.ora 中的連接串是如下這樣:
(DESCRIPTION = (FAILOVER=ON)(LOAD_BALANCE=ON) (ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g))) 再在各個(gè)節點(diǎn)的 tnsnames.ora 中加入如下設置(注意這里監聽(tīng)的是各個(gè)節點(diǎn)的 VIP):
LISTENER_RAC1 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-vip)(PORT = 1521))LISTENER_RAC2 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-vip)(PORT = 1521))LISTENER_RAC3 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-vip)(PORT = 1521))LISTENER_RAC4 = (ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-vip)(PORT = 1521)) 然后只需要在初始化參數文件里加入如下設置就能實(shí)現 Server 端 Connect Time Load Balancing 了:
RAC1.local_listener=LISTENER_RAC1RAC2.local_listener=LISTENER_RAC2RAC3.local_listener=LISTENER_RAC3RAC4.local_listener=LISTENER_RAC4*.remote_listener= MySCAN:1521當做了上述設置后,Oracle 11gR2 RAC 的 Server 端 Connect Time Load Balancing 也就配好了。此時(shí)所有的 SCAN Listener 實(shí)際上是都知道所有RAC節點(diǎn)的負載情況的。當先經(jīng)過(guò)一層客戶(hù)端的 Connect Time Load Balancing,比如這里隨機的連到了第二個(gè) SCAN VIP 所對應的 SCAN Listener 上后,這時(shí)候這個(gè) SCAN Listener 會(huì )選擇一個(gè)實(shí)際負載較低的 RAC 節點(diǎn),然后把連接請求轉移(redirect)到這個(gè)負載較低的 RAC 節點(diǎn)的 Local Listener 上——這就是 Oracle RAC 11gR2 的 server 端的 Connect Time Load Balancing。
實(shí)際上,local_listener 和 remote_listener 支持復雜的連接串的寫(xiě)法。所以,可以在初始化參數里面直接設置 local_listener 和 remote_listener,而不需要在 $ORACLE_HOME/network/admin 下的 tnsnames.ora 中做上述設置。
來(lái)看一個(gè)兩節點(diǎn)的 Oracle 11gR2 RAC 的實(shí)例。這個(gè)環(huán)境中用了 hosts 文件,hosts 文件內容如下所示:
10.1.15.64 P550-05-LA 10.1.15.84 P550-05-LA-vip 9.2.1.64 P550-05-LA-priv 10.1.15.65 P550-05-LB 10.1.15.85 P550-05-LB-vip 9.2.1.65 P550-05-LB-priv10.1.15.86 nbsdev-scan從上述內容可以看到,現在節點(diǎn) 1 的 vip 是 10.1.15.84,節點(diǎn) 2 的 vip 是 10.1.15.85,整個(gè) RAC 環(huán)境的 SCAN vip 是 10.1.15.86。
先登陸節點(diǎn) 1,看一下節點(diǎn) 1 上的 local_listener 和 remote_listener 的設置: SQL> show parameter instance_name;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------instance_name string NBSDEV1SQL> show parameter local_listener;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------local_listener string (DESCRIPTION=(ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.15.84)(PORT=1522))))SQL> show parameter remote_listener;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------remote_listener string nbsdev-scan:1522再登陸節點(diǎn) 2,看一下節點(diǎn) 2 上的 local_listener 和 remote_listener 的設置: SQL> show parameter instance_name;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------instance_name string NBSDEV2SQL> show parameter local_listener;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------local_listener string (DESCRIPTION=(ADDRESS_LIST=(ADDRESS= (PROTOCOL=TCP)(HOST=10.1.15.85)(PORT=1522))))SQL> show parameter remote_listener;
NAME TYPE VALUE------------------------------------ ----------- ------------------------------remote_listener string nbsdev-scan:1522上述環(huán)境 server 端的 Connect Time Load Balancing 實(shí)際上已經(jīng)配置好了,但從如下內容可以看到,我們并沒(méi)有在 $ORACLE_HOME/network/admin 下的 tnsnames.ora 中配置相關(guān)的 local_listener 和 remote_listener:
ora11g:/nbsdu01/app/oracle/product/11.2/network/admin>cat tnsnames.ora
# tnsnames.ora Network Configuration File: /nbsdu01/app/oracle/product/11.2/network/admin/tnsnames.ora# Generated by Oracle configuration tools.NBSDEV = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = nbsdev-scan)(PORT = 1522)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = NBSDEV) ) )Runtime Connection Load Balancing 是指從連接池中取得已有連接時(shí)的 Connection Load Balancing。
之前無(wú)論是 Oracle RAC 9iR2/10gR2,還是 Oracle RAC 11gR2,在存在連接池的情況下,單純的 server 端的 Connect Time Load Balancing 并不能保證當應用需要從連接池里取得一個(gè)已有連接的時(shí)候,這個(gè)連接就指向了節點(diǎn)負載較低的那個(gè)節點(diǎn)。因為這個(gè)時(shí)候應用從連接池里取得的連接很可能就是連接池初始化的時(shí)候形成的連接,只是反映了連接池初始化那個(gè)時(shí)間點(diǎn)的各個(gè)節點(diǎn)的負載情況,而隨著(zhù)時(shí)間的推移,各個(gè)節點(diǎn)的負載情況可能發(fā)生了很大的變化,所以這種情況下連接池的連接很可能并不是真正的 Load Balance。
實(shí)際上 FAN 就是為了解決上述問(wèn)題而設計的。能支持 FAN events 的連接池通過(guò)訂閱 FAN HA events,就可以保證當應用需要從連接池里取得一個(gè)已有連接的時(shí)候,這個(gè)連接肯定是有效的連接,不會(huì )指向那些 service 宕掉或者 instance 崩潰的節點(diǎn)(之前已經(jīng)提到過(guò),這是通過(guò) FCF 來(lái)實(shí)現的:當支持 FAN events 的連接池接收到包含 instance/service 宕掉的 FAN HA events 后,原先 cache 在連接池里的跟這個(gè) instance/service 相關(guān)的連接馬上會(huì )被標記為失效,同時(shí)這些連接會(huì )被清除);另外一個(gè)方面,能支持 FAN events 的連接池通過(guò)訂閱 LBA events,就能近乎實(shí)時(shí)地知道各個(gè) RAC 節點(diǎn)實(shí)際的負載情況,所以當應用需要從連接池里取得一個(gè)已有連接的時(shí)候,連接池就能提供給用戶(hù)一個(gè)真正的負載較低的 RAC 節點(diǎn),這樣就實(shí)現了真正的 Runtime Connection Load Balancing。
現在介紹兩個(gè)通過(guò)訂閱 LBA events 實(shí)現 Runtime Connection Load Balancing 的例子。
例三:JDBC Runtime Connection Load Balancing
這里的 JDBC 連接是指 JDBC thin 連接,要實(shí)現 JDBC Runtime Connection Load Balancing,只需要做如下兩步即可:
1、首先要按照“例一:JDBC Fast Connection Failover (FCF)”里那樣把 JDBC FCF 設置好;
2、啟用 LBA events:
srvctl modify service -d RAC11g -s Email -B SERVICE_TIME -j SHORT
這里首先把 CLB_GOAL 設置成了 SHORT,接著(zhù)把 GOAL 設置成了 SERVICE_TIME,這兩者缺一不可,CLB_GOAL 和 GOAL 的各個(gè)值的詳細含義已經(jīng)在 Connect Time Load Balancing 里詳細解釋過(guò),這里不再贅述。
例四:ODP.NET Runtime Connection Load Balancing
ODP.NET的Runtime Connection Load Balancing的 啟用跟“例二:ODP.NET Fast Connection Failover (FCF)”里的步驟類(lèi)似,只需要做如下 4 步就好,注意這里第 1 步和第 4 步跟“例二:ODP.NET Fast Connection Failover (FCF)”里的相應步驟是不一樣的:
1、把對應 service的AQ Notification 打開(kāi),同時(shí)設置 CLB_GOAL和GOAL:
srvctl modify service -d RAC11g -s Email -q TRUE -B SERVICE_TIME -j SHORT
2、把 aq_tm_processes 的值設為 1;
3、賦予指定用戶(hù) de-queue 的權限:
exec dbms_aqadm.grant_queue_privilege('DEQUEUE','SYS.SYS$SERVICE_METRICS',
4、在.NET連接串里設置 Load Balancing=true,如下所示:
con.ConnectionString = 'User Id=user_name;Password=password;Data Source=odpapp;' + 'Min Pool Size=10;Connection Lifetime=120;Connection Timeout=60;' + 'Load Balancing=true;Incr Pool Size=5;Decr Pool Size=2';至此我們已經(jīng)詳細的描述了 RAC 環(huán)境下的連接管理。
作為這篇文章的結束,最后我們來(lái)闡述一下如何在 Oracle 數據庫里設置 TCP timeout。
1、32 位 Windows上Oracle 數據庫 11.2.0.1 默認的操作系統TNS連接 timeout 的時(shí)間大概是 20 秒:
16:27:26 SQL> conn scott/tiger@cuihua112;ERROR:ORA-12170: TNS: 連接超時(shí)16:27:49 SQL>
這里可以看到,從開(kāi)始連接到連接超時(shí)的間隔時(shí)間是 23 秒,去掉輸入上述連接串“conn scott/tiger@cuihua112”所耗費的時(shí)間,可以知道在 32 位 Windows上Oracle 數據庫 11.2.0.1 默認的操作系統TNS連接 timeout 的時(shí)間大概是 20 秒。
2、修改一下 client 端 sqlnet.ora 文件,將 TNS 連接 timeout 時(shí)間修改為 5 秒(這是通過(guò)設置 SQLNET.OUTBOUND_CONNECT_TIMEOUT 來(lái)實(shí)現的):
# sqlnet.ora Network Configuration File: C:\app\cuihua\product\11.2.0\dbhome_1\network\admin\sqlnet.ora# Generated by Oracle configuration tools.# This file is actually generated by netca. But if customers choose to # install 'Software Only', this file wont exist and without the native # authentication, they will not be able to connect to the database on NT.SQLNET.AUTHENTICATION_SERVICES= (NTS)SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)從如下結果可以看到,從開(kāi)始連接到連接超時(shí)的間隔時(shí)間是 7 秒,去掉輸入上述連接串“conn scott/tiger@cuihua112”所耗費的時(shí)間,可以知道上述 5 秒超時(shí)的設置確實(shí)生效了。
16:28:34 SQL> conn scott/tiger@cuihua112;ERROR:ORA-12170: TNS: 連接超時(shí)16:28:41 SQL>3、注釋掉上述 SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5,在 tnsnames.ora 的 cuihua112 的連接串中將 TNS 連接 timeout 時(shí)間設置為 15 秒:
CUIHUA112 = (DESCRIPTION = (CONNECT_TIMEOUT=5)(RETRY_COUNT=2) (ADDRESS = (PROTOCOL = TCP)(HOST = 172.20.190.11)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = cuihua112) ) )從如下結果可以看到,從開(kāi)始連接到連接超時(shí)的間隔時(shí)間是 17 秒,去掉輸入上述連接串“conn scott/tiger@cuihua112”所耗費的時(shí)間,可以知道上述 15 秒超時(shí)的設置確實(shí)生效了。
16:31:08 SQL> conn scott/tiger@cuihua112;ERROR:ORA-12170: TNS: 連接超時(shí)16:31:25 SQL>4、同時(shí)啟用 SQLNET.OUTBOUND_CONNECT_TIMEOUT = 5 和上述 cuihua112 的連接串,從結果里可以看到,tnsnames.ora 中的設置取代了(override)了 sqlnet.ora 中的 TNS 連接 timeout 的設置。即在同時(shí)啟用的情況下,現在的 TNS 連接 timeout 設置還是為 15 秒。
16:33:12 SQL> conn scott/tiger@cuihua112;ERROR:ORA-12170: TNS: 連接超時(shí)16:33:29 SQL>
這里可以看到,從開(kāi)始連接到連接超時(shí)的間隔時(shí)間是 17 秒,去掉輸入上述連接串“conn scott/tiger@cuihua112”所耗費的時(shí)間,可以知道是 15 秒超時(shí)的設置生效了。
5、在 tnsnames.ora 的 cuihua112 的連接串中將 TNS 連接 timeout 時(shí)間設置為 40 秒,這已經(jīng)超過(guò)了 TNS 連接默認的 timeout 值,從如下測試里可以看到,Oracle 數據庫會(huì )以 tnsnames.ora 中的設置為準(當然,這里前提條件是單次連接的 CONNECT_TIMEOUT 設置不要超過(guò)操作系統 TNS 連接默認的 timeout 值,如果超過(guò)了則 CONNECT_TIMEOUT 設置失效,但 RETRY_COUNT 的設置依然有效)。
CUIHUA112 = (DESCRIPTION = (CONNECT_TIMEOUT=10)(RETRY_COUNT=3) (ADDRESS = (PROTOCOL = TCP)(HOST = 172.20.190.11)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = cuihua112) ) ) 這里 CONNECT_TIMEOUT 設置為 10 秒,RETRY_COUNT 設置為 3,實(shí)際上就將 TNS 連接 timeout 時(shí)間設置成了40秒
16:52:52 SQL> conn scott/tiger@cuihua112;ERROR:ORA-12170: TNS: 連接超時(shí)16:53:33 SQL>這里可以看到,從開(kāi)始連接到連接超時(shí)的間隔時(shí)間是 41 秒,去掉輸入上述連接串“conn scott/tiger@cuihua112”所耗費的時(shí)間,可以知道是 40 秒超時(shí)的設置生效了。
這篇文章詳細介紹了 RAC 環(huán)境下的連接管理及其相關(guān)內容,主要針對 RAC 環(huán)境下連接管理所涉及到的 Connect Time Load Balancing、Runtime Connection Load Balancing、Connect Time Connection Failover 和 Runtime Connection Failover 等內容,同時(shí)也描述了包括 TAF、ONS、FCF、FAN 和 LBA 等其它一些相關(guān)內容。
聯(lián)系客服