RAC 是由多個 Server 所組成,當其中一個節點發生故障時,還有其它的節點可以提供服務,這個特性我們將其稱為 Failover ;當我們透過 SQL*Net 連線到 RAC 資料庫時, RAC 會自動將這些連線平均的分配到每一個擁有此 Database Instance 的節點上,這個特性我們稱作為 Load Balance 。
RAC 資料庫的連線方式可以透過 vip 直接連線或者是使用 SCAN ,透過 vip 連線如果想要達到 Load Balance 的效果,必須把每個節點的 vip 設定到 tnsnames.ora 並使用 LOAD_BALANCE=ON ,這樣系統就會平均將連線分散到每個節點上;如果是使用 SCAN-NAME 連線,那麼就會先去 DNS 查詢此 SCAN-NAME 所對應的 IP ,然後由 SCAN Listener 接收到連線的資訊,最後再將連線平均分配到每個節點上。
RAC 的 Load Balance 可以分為 Client Side Load Balance 與 Server Side Load Balance 兩種:
Client Side Load Balance : 透過 tnsnames.ora 的 LOAD_BALANCE=ON 設定所實現,例如:
這樣連線到 ORCL 時就會隨機使用 node1-vip 或 node2-vip 進行連線,如果不使用 LOAD_BALANCE=ON ,那麼只會先使用第一組 node1-vip 進行連線,同樣的設定也適用於 scan ip :
192.168.49.110 ~ 112 這三組是 SCAN-NAME 註冊到 DNS 上所對應的三組 IP 。以上兩種設定都可以達到 Client Side Load Balance 的效果。
Server Side Load Balance : tnsnames.ora 裡面不使用 LOAD_BALANCE=ON ,而是透過資料庫參數的 remote_listener 來實現,也就是說先連線到某一個節點上,然後再經由 remote_listener 來平均分配連線。 remote_listener 的設定可以使用 vip 或者是 SCAN-NAME ,在 Grid Infrastructure 的架構下, remote_listener 預設都是為 SCAN-NAME 。如果要使用 vip 來達成 Server Side Load Balance ,首先必須於 tnsnames.ora 定義 remote_listener 所對應的 vip 資訊:
定義好之後將參數 remote_listener 設定為此:
設定好之後,資料庫的連線字串就不需要使用 LOAD_BALANCE=ON :
如果是使用 SCAN-NAME 來連線,那麼連線字串就簡單使用 SCAN-NAME 再搭配 remote_listener 就可以達到 Server Side Load Balance 的效果:
至於 Failover 的類型可以分為 Client-Side Connect Time Failover 、 Transparent Application Failover (TAF) 與 Sever-Side TAF 三種 :
Client-Side Connect Time Failover : 在連線的階段進行 Failover ,透過 tnsnames.ora 的 FAILOVER=ON 設定所實現,例如:
這個設定當中由於沒有 LOAD_BALANCE=ON ,所以會優先使用第一個 ip ,也就是 node1-vip 進行連線,由於設定了 FAILOVER=ON ,當 node1-vip 無法連線時,就會自動改用 node2-vip 來嘗試連線。
Transparent Application Failover : 已經成功連進資料庫並進行作業的時候,若當前的節點發生問題,則自動將 session 轉移到另一個節點上繼續作業,透過 tnsname.ora 的 FAILOVER_MODE 設定來實現,例如:
FAILOVER_MODE 共有四個參數可做設定:
TYPE : 可設定為 session 或者是 select 。 session - 當節點發生問題時, Client 必須要重新連線; select – 當節點發生問題時,自動將當前的 session 導向另一個節點,此時連線不會中斷。
METHOD : 可設定為 basic 或者是 preconnect 。 basic – 當前節點發生問題時才會連線到另一個節點上。 preconnect – 除了當前節點的連線外,同時也建立 shadow connect 到其它節點上。
RETRIES : 用來設定 failover 的重新嘗試次數。
DELAY : 用來設定重新嘗試的間隔時間,以秒為單位。
這邊要注意的是,只有在做 select 行為時的 failover 連線才不會中斷,如果是 DML 的行為,那麼當前的 session 就會中斷,必須重新連線才行。
透過 v$session 可以查詢此 session 是否被 failover :
Server-Side TAF : 透過 Oracle Service 所實現,當我們建立好一個資料庫時,預設會產生以 db_unique_name 為名稱的 service ,除此之外,我們還可以針對此資料庫建立其它的 service 來使用。在 RAC 架構中,建立額外的 DB Service 可以用來將工作群組化,例如一組四個節點的 RAC ,此時可以建立兩個 Service , Service A 只啟用在 node1 與 node2 、 Service B 則啟用在 node3 與 node4 ,此時所有的交易型作業都使用 Service A 來連線,那麼交易就只會使用到 node1 與 node2 、 批次型的作業則是使用 Service B 連線,則批次作業就只會跑在 node3 與 node4 ,工作群組化的好處是,可以將每個 RAC 節點所需要扮演的角色定義清楚,各司其職,避免一個節點同時執行太多不同種類的作業,增加系統的負擔。
建立 Service 的另一個好處是可以達到 TAF 的效果,例如建立一個 Service C ,那麼此時可以設定 Service C 主要只啟用在 node1 而 node2 則是當備援,當 node1 發生問題時再把 Service C 導向 node2 繼續進行服務。
在 RAC 架構中,以 srvctl 指令來建立 Service ,若是 single instance 的架構,則是使用 dbms_service 來建立。在 RAC 節點為 Administrator Managed 的情況下, Service 可以設定 Preferred Server (將 Service 啟用在哪些節點) 以及 Available Server (將哪些節點作為此 Service 的備援) ,例如建立一個 orcl_job 的 Service :
這邊設定了 Preferred Server 為 node1 、 Available Server 為 node2 ,表示 orcl_job 這個 Service 只運行在 node1 ,當 node1 發生故障時再把 Service 轉移到 node2 進行服務。
在 Policy Managed 的架構下,則是設定此 Service 為 Uniform (Server Pool 中的所有節點都啟用此 Service) 或是 Singleton (只將此 Service 啟用在此 Server Pool 中的一個節點上) ,例如:
建立好 Service 之後便可透過 srvctl 來操作:
Load Balance 與 Failover 這兩個功能是 RAC 架構下的特性,不過 Load Balance 功能算是一個雙面刃,好處是可以將連線平均分配到所有節點上達到均衡負載的效果,缺點是資料庫容易產生 GC (Global Cache) 的等待事件,有時候 GC 事件對於效能來說會產生重大影響,比較好的做法是使用 Service ,利用 Service 將作業分配到指定的節點上運行,用指定節點的方式來運行不僅可以達到負載平衡的目的,同時由於作業類型的不同也可以避免 GC 等待事件的產生,再加上 Service 也具有 TAF 的特性,不用擔心會單點故障,使用 Service 可以說是一舉數得。
沒有留言:
張貼留言