之前有網友在我Blog 留言說我的RAC 搭建中沒有寫SCAN 配置,這個之前應該是有寫過,但剛搜了一下,沒找到,正好重新整理一下,並做下實驗,實驗就用Oracle 12c 進行測試。
在Oracle 11g 之前,我們去連接RAC 集群,都是配置如下的內容:
dave_rac=
(DESCRIPTION =
(ADDRESS_LIST =
(LOAD_BALANCE = yes)
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.68)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.69)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = dave)
(failover_mode=(type=select)(method=basic))
)
)
這裡的68和69 是VIP 的地址,是PUBLIC 網卡上的虛擬IP。 那我們這裡只有2個節點,如果我們增加了RAC的集群數,那麼就需要修改所有的客戶端的配置,這個就很麻煩。
所以在Oracle 11gR2 中,引入了SCAN(Single ClientAccess Name)的特性。SCAN是一個域名,可以解析至少1個IP,最多解析3個SCAN IP,客戶端可以通過這個SCAN 名字來訪問數據庫,另外SCAN ip必須與public ip和VIP在一個子網。
啟用SCAN 之後,會在數據庫與客戶端之間,添加了一層虛擬的服務層,就是SCAN IP和SCAN IP Listener,在客戶端僅需要配置SCAN IP的tns信息,通過SCANIP Listener,連接後台集群數據庫。這樣,不論集群數據庫是否有添加或者刪除節點的操作,均不會對客戶端產生影響,也就不需要修改配置。
配置SCAN有3種方法:
1. 使用/etc/hosts文件
這個是我們目前用的最多的方式,但是缺點只能對應一個SCAN IP,該方法Oracle 不推薦,但是簡單,不需要單獨的DNS 服務器,使用該方法,客戶端還是需要VIP來鏈接。 Oracle 推薦使用其他的2種方法來實現SCAN 功能。
2. 在DNS中定義域名,只需要在DNS中配置即可實現SCAN 功能。
3. 通過Grid Naming Server(GNS),需要配置DNS 和DHCP才能實現SCAN 功能。
配置好之後,直接在客戶端的tnsnames裡寫SCAN NAME就可以了,如下:
RACSCAN =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan.gns.cndba.com)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dave)
)
)
以後RAC 增加刪除節點,客戶端都不需要修改。
在啟用SCAN 特性之後,除了多幾個SCAN IP 之外,還會多幾個SCAN IP Listener,每個SCAN IP對應一個SCAN IP Listener,為了性能考慮,每個SCAN IP以及其對應的SCAN IP Listener將被獨立的分配到各個節點上。
如果Cluster中其中某個運行SCAN IP的節點出現異常,則其余正常的SCAN IP節點將自動接管。
如果客戶端是11g R2的版本,則客戶端只需在tns中配置域名解析,即可實現failover,如果客戶端版本低於11g R2,則無法通過域名解析出多個SCAN IP地址,因此如果要實現failover,必須在客戶端的tns中配置3個SCAN IP的地址進行解析,這也是為何Oracle強烈建議在使用11g R2數據庫時,客戶端也最好使用11g R2的原因。
上圖是SCAN 的工作流程圖,圖的右邊是一個4個節點的RAC 集群,所以有4個Local Listener。 配置了3個SCAN IP和3個 SCAN Listeners。這3個SCAN IP 是隨機的落在RAC節點上。
客戶端鏈接的時候,會隨機的連接到某一個某一個SCAN IP及起對應的SCAN IP Listner上, SCAN IP Listener接收到連接請求時,會根據 LBA 算法(least loaded instance),將該客戶端的連接請求,轉發給對應的Instance上的VIP Listener,從而完成了整個客戶端與服務器的連接過程。
簡單點就是:
client -> scan listener -> locallistener -> local instance