Oracle RAC伺服器端的負載平衡是根據RAC中各節點的串連負荷數情況,將新的串連請求分配到負荷最小的節點上去。當資料庫處於運行時,RAC中各節點的PMON進程每3秒會將各自節點的串連負荷數更新到service_register。而對於節點中任意監聽器故障或監聽器意外失敗時,PMON進程會每1秒鐘檢查當前節點上的監聽是否重啟,以獲得最新的負載資訊來及時調整負載平衡。本文主要示範suse 10 + oracle 10g rac下的伺服器端的負載平衡。
一、伺服器端負載平衡配置
1、為tnsnames.ora 添加相應的網路服務名(每個節點配置)
oracle@bo2dbp:~> more $ORACLE_HOME/network/admin/tnsnames.ora
# tnsnames.ora Network Configuration File: /u01/oracle/db/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.
remote_lsnr_gobo4 =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))
)
local_lsnr_gobo4a =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))
)
local_lsnr_gobo4b =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))
)
2、設定remote_listener參數
alter system set remote_listener='<net_service_name>' scope=both sid='*';
SQL> show parameter instance_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
instance_name string GOBO4A
SQL> show parameter listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
remote_listener string
SQL> alter system set remote_listener='remote_lsnr_gobo4' scope=both sid='*';
System altered.
3、配置用戶端tnsnames.ora
-->用戶端為suse 10
SZDB:~ # ifconfig eth1 | grep "inet addr"|cut -d " " -f12|cut -d : -f2 #--用戶端主機的ip
192.168.7.2
SZDB:~ # su - oracle
oracle@SZDB:~> tail -10 $ORACLE_HOME/network/admin/tnsnames.ora
GOBO4 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.61)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.7.62)(PORT = 1521))
(LOAD_BALANCE = off) #--由於僅僅測試寄予伺服器端的負載平衡,因此關閉用戶端負載平衡選項
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = GOBO4)
)
)
#Author : Robinson Cheng
4、檢查監聽情況
oracle@bo2dbp:~> lsnrctl status
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.61)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.51)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM1", status BLOCKED, has 1 handler(s) for this service...
Service "GOBO4" has 2 instance(s).
Instance "GOBO4A", status READY, has 2 handler(s) for this service...
Instance "GOBO4B", status READY, has 1 handler(s) for this service..
.......
oracle@bo2dbs:~> lsnrctl status
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.62)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.52)(PORT=1521)))
Services Summary...
Service "+ASM" has 1 instance(s).
Instance "+ASM2", status BLOCKED, has 1 handler(s) for this service...
Service "GOBO4" has 2 instance(s).
Instance "GOBO4A", status READY, has 1 handler(s) for this service...
Instance "GOBO4B", status READY, has 2 handler(s) for this service...
..........
#--如果監聽或資料庫需要重啟異常請考慮重新啟動監聽器或資料庫
#--下面清空監聽日誌以便於後續統計串連資訊
oracle@bo2dbp:/u01/oracle/db/network/log> cat /dev/null>listener_bo2dbp.log
oracle@bo2dbs:/u01/oracle/db/network/log> cat /dev/null>listener_bo2dbs.log
二、測試伺服器端的負載平衡
1、從用戶端建立串連
oracle@SZDB:~> more load_balance.sh
#!/bin/bash
for i in {1..1000}
do
echo $i
sqlplus -S system/oracle@GOBO4 <<EOF
select instance_name from v\$instance;
EOF
sleep 1
done
exit 0
oracle@SZDB:~> ./load_balance.sh >srv_load_bal.log
2、分析監聽日誌
oracle@bo2dbp:/u01/oracle/db/network/log> more listener_bo2dbp.log
12-OCT-2012 12:00:10 * service_update * GOBO4B * 0 #節點bo2dbs上的執行個體GOBO4B的更新到bo2dbp上監聽器的更新資訊
12-OCT-2012 12:00:35 * service_update * GOBO4B * 0
12-OCT-2012 12:01:04 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=50322)) * establish * GOBO4 * 0
12-OCT-2012 12:01:05 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=50325)) * establish * GOBO4 * 0
12-OCT-2012 12:01:07 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=50328)) * establish * GOBO4 * 0
12-OCT-2012 12:01:08 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=50330)) * establish * GOBO4 * 0
#上面的日誌片斷中可以看出全部是用戶端發起的到bo2dbp節點上的建立串連的資訊
#下面來查看bo2dbs上的監聽日誌
oracle@bo2dbs:/u01/oracle/db/network/log> more listener_bo2dbs.log
12-OCT-2012 12:00:10 * service_update * GOBO4B * 0
12-OCT-2012 12:00:10 * service_update * GOBO4B * 0
12-OCT-2012 12:00:14 * (CONNECT_DATA=(CID=(PROGRAM=)(HOST=bo2dbs)(USER=oracle))(COMMAND=status)(ARGUMENTS=64)
(SERVICE=LISTENER_BO2DBS)(VERSION=169870080)) * status * 0
12-OCT-2012 12:00:35 * service_update * GOBO4B * 0
12-OCT-2012 12:00:35 * service_update * GOBO4B * 0
12-OCT-2012 12:01:04 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))(INSTANCE_NAME=GOBO4B)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=61862)) * establish * GOBO4 * 0
12-OCT-2012 12:01:07 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))(INSTANCE_NAME=GOBO4B)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=61868)) * establish * GOBO4 * 0
12-OCT-2012 12:01:09 * (CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=GOBO4)(CID=(PROGRAM=sqlplus@SZDB)(HOST=SZDB)
(USER=oracle))(INSTANCE_NAME=GOBO4B)) * (ADDRESS=(PROTOCOL=tcp)(HOST=192.168.7.2)(PORT=61872)) * establish * GOBO4 * 0
#在12-OCT-2012 12:01:04時刻,串連資訊中有INSTANCE_NAME=GOBO4B的串連資訊,而節點bo2dbp上也有一條類似的資訊,因此該條串連
#日誌是由節點bo2dbp轉寄過來而建立的串連請求。
#同樣在12-OCT-2012 12:01:07時刻,節點bo2dbp轉寄過來而建立的串連請求。
#小結一下,
#對於直接連接,監聽器日誌中將出現establish,且不含有INSTANCE_NAME=GOBO4B 字樣
#而對於轉寄的串連,則轉寄節點與接收的節點同時存在串連資訊,轉寄節點上存在串連資訊的與普通的串連請求一樣,
#而接收的節點上存在INSTANCE_NAME=<instance_name> 資訊
3、檢查負載平衡結果
oracle@SZDB:~> grep GOBO4A srv_load_bal.log |wc -l
755
oracle@SZDB:~> grep GOBO4B srv_load_bal.log |wc -l
245
#從上面的記錄檔中可知總共有755個用戶端串連到了gobo4a,有245各用戶端串連到了gobo4b
#下面查看監聽器日誌來獲得串連資訊
#下面的查詢中在節點bo2dbp上總共有接受了1000個使用者串連
oracle@bo2dbp:/u01/oracle/db/network/log> grep establish listener_bo2dbp.log |wc -l
1000
#下面的查詢查看是否有從節點bo2dbs轉寄過來的串連,結果為0,說明沒有任何串連請求從bo2dbs轉寄過來
oracle@bo2dbp:/u01/oracle/db/network/log> grep INSTANCE_NAME=GOBO4 listener_bo2dbp.log |wc -l
0
#接下來查看節點bo2dbs的監聽日誌,可以看出總共接受了245個串連請求
oracle@bo2dbs:/u01/oracle/db/network/log> grep establish listener_bo2dbs.log |wc -l
245
#下面的過濾情況也表明在節點bo2dbs上的串連是從bo2dbp上轉寄的串連,而非用戶端直接到bo2dbs的請求串連
oracle@bo2dbs:/u01/oracle/db/network/log> grep INSTANCE_NAME=GOBO4 listener_bo2dbs.log |wc -l
245
#從監聽器的日誌檢查可以,測試中的串連全部請求到節點bo2dbp,是由於tnsnames.ora中ADDRESS的第一個IP地址就是bo2dbp的IP
#因此所有的串連都是請求到bo2dbp,而沒有用戶端發出到bo2dbs的串連請求
#其次是儘管在bo2dbp有1000個串連請求,而真正建立串連的只有755個,有245轉寄到了節點bo2dbs
三、總結
1、伺服器端的負載平衡需要配置remote_listener參數,而該參數的值依賴於tnsnames.ora的連接字串
2、對於基於伺服器端的串連負載平衡,監聽器會根據當前節點、執行個體上的串連負載情況進行轉寄到閒置執行個體
3、轉寄的依據僅僅是當前節點監聽的串連數量的多少,而非當前執行個體的過度負載
4、從上面的測試可以得出,各個節點的串連並不算均衡,是相對的均衡,因此應結合用戶端串連負載協同工作
5、對於當前執行個體的過度負載的情形,應結合配置service方法來實現負載平衡
oracle視頻教程請關注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html