一、SCAN 概念
SCAN(Single Client Access Name)是 Oracle從11g R2開始推出的,客戶端可以通過 SCAN 特性負載均衡地連接到 RAC數據庫
SCAN 最明顯的優點就是,當集群中新增加了節點或者刪除了節點,不需要額外維護客戶端
查看 SCAN 的配置信息的方式如下:
[grid@rac2 ~]$ srvctl config scan
SCAN name: rac-scan, Network: 1/192.168.56.0/255.255.255.0/bond0
SCAN VIP name: scan1, IP: /rac-scan/192.168.56.90
查看 SCAN VIP 的狀態:可以發現 SCAN VIP 運行在節點 rac2
[grid@rac2 ~]$ srvctl status scan
SCAN VIP scan1 is enabled
SCAN VIP scan1 is running on node rac2
二、IP 概念
RAC 中有很多種 IP,每種 IP 的作用分別是什么呢?
Public IP:
- 這是網卡上配置的真實IP地址,我們稱為公共IP,這個IP的存在關系到 VIP 能不能正確漂在其所在網卡上
- 注意,PUBLIC IP是不提供給客戶端去連接配置的,這並不是說通過 PUBLIC IP 無法連接實例,而是當節點服務器宕機時,所有向它請求連接的客戶端都會有等待現象並且最后得到超時信息
Private IP:
- 稱為私網 IP(私有IP),它是用於心跳同步的,也就是保證兩台服務器數據同步
- Oracle另一個高可用性連接特性(HAIP)
- 其實 Cache Fusion 會消耗節點服務器很大的私網資源,另外,私網間無法通信還會引起 brain split(腦裂),以前為解決這種問題,我們可以采用網卡 bonding 技術,而 Oracle 在 11g R2 的時候通過 HAIP 技術來實現
- HAIP(Highly Available Virtual IP)用於節點間的私網通信,支持同時使用多個網絡連接來滿足網卡間的負載均衡,並且還提高了Cache Fusion 資源通信能力
Virtual IP:
- RAC 的每個節點都需要有一個虛擬IP,這就是VIP
- VIP 會綁定到節點的 public 網卡上,需要和 PUBLIC IP同一個子網,它們是由 GI 的 Clusterware 來管理的
- VIP 在其節點服務器發生故障的時候會自動漂移到另外正常的節點服務器上,如果 RAC 是多節點運行的,那具體漂移到哪個活動的節點將由Clusterware 決定
- 等故障節點恢復正常,漂移的 VIP 也回到此節點上,繼續提供服務
三、監聽概念
下面再解釋一下 RAC 中監聽的概念
LOCAL LISTENER:
- 本地監聽,RAC 的每個節點上都會有獨立的本地監聽,它會監聽該節點的 PUBLIC IP和VIP
- 每個節點的實例在啟動的時候向本地監聽進行注冊,當 VIP 或者PUBLIC IP (這種情況比較少見)有連接請求的時候,本地監聽就接受處理並和本地實例建立連接。如果某個節點故障,其上面的VIP會進行漂移,但本地監聽並不會產生漂移
SCAN LISTENER:
- SCAN 監聽,它是實現 SCAN 負載均衡的原理所在
- SCAN 監聽跟着 SCAN VIP 隨機分配到節點服務器上,如果某個節點發生故障,運行在此節點上的 SCAN VIP 會進行漂移,這時候 SCAN 監聽也跟着漂移到正常的節點上,繼續為 SCAN VIP 監聽連接請求,當 PMON 進程下次動態更新實例信息到該 SCAN 監聽后,它又重新接受客戶端的連接
查看 SCAN 監聽的配置和狀態:
[grid@rac2 ~]$ srvctl config scan_listener
SCAN Listener LISTENER_SCAN1 exists. Port: TCP:1521
[grid@rac2 ~]$ srvctl status scan_listener
SCAN Listener LISTENER_SCAN1 is enabled
SCAN listener LISTENER_SCAN1 is running on node rac2
1、local_listener 參數
該參數控制着本地監聽的注冊,通過本地監聽的數據庫連接請求只會連接到本地節點的實例上
數據庫中,該參數設置為向本地 VIP 地址進行注冊:
SQL> show parameter local
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string (ADDRESS=(PROTOCOL=TCP)(HOST=
192.168.56.80)(PORT=1521))
查看本地監聽的狀態,可以發現本地監聽在 Public IP 和 VIP 上監聽,只監聽本地實例:
[grid@rac2 ~]$ lsnrctl status listener
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.20)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.80)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM2", status READY, has 1 handler(s) for this service...
Service "rac" has 1 instance(s).
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 1 instance(s).
Instance "rac2", status READY, has 1 handler(s) for this service...
2、remote_listener 參數
該參數控制 SCAN 監聽的注冊,每個節點上都設置,這樣的話,每個節點的 PMON 都會向 SCAN 監聽注冊實例信息,所以 SCAN監聽能夠負載均衡地分發連接請求到節點本地監聽上,也就是連接到其本地節點實例上
示例:
SQL> show parameter remote_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_listener string rac-scan:1521
查看 SCAN 監聽的狀態,可以發現它監聽了所有實例:
[grid@rac2 ~]$ lsnrctl status listener_scan1
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER_SCAN1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.90)(PORT=1521)))
Services Summary...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
3、修改 remote_listener 參數
通過 remote_listener
的修改,讓 SCAN 以及所有節點的本地監聽都可以監聽到所有數據庫實例
第一步,在節點 rac1 的 tnsnames.ora
文件中配置 tnsnames,使該節點可以被 rac2 的 listener 監聽到:
[oracle@rac1 admin]$ pwd
/u01/app/oracle/product/11.2.0/db_1/network/admin
[oracle@rac1 admin]$ vim tnsnames.ora
RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac)
)
)
在節點 rac2 的 tnsnames.ora
文件中配置 tnsnames,使該節點可以被 rac1 的 listener 監聽到:
RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = rac)
)
)
第二步,修改 remote_listener
參數(在其中一個節點操作即可):
SQL> alter system set remote_listener=rac;
System altered.
第三步,查看 LISTENER 監聽狀態,可以監控到所有的數據庫實例
[grid@rac1 admin]$ lsnrctl status
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.10)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.60)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM1", status READY, has 1 handler(s) for this service...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
第四步,查看 SCAN 監聽狀態,可以監控到所有的數據庫實例(需要先查看 SCAN 監聽在哪個節點)
[grid@rac1 ~]$ lsnrctl status listener_scan1
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER_SCAN1)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.56.90)(PORT=1521)))
Services Summary...
Service "rac" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...
Service "racXDB" has 2 instance(s).
Instance "rac1", status READY, has 1 handler(s) for this service...
Instance "rac2", status READY, has 1 handler(s) for this service...