Connection Balancing
Connection Balancing 这种负载均衡是在用户连接这个层次进行的,也就是在用户请求建立连接时,根据每个节点的负载决定把连接分配给哪个实例,
而一旦连接建立之后,会话的所有操作就都在这个实例上完成,而不会再分派给其他节点了。
Connection Balancing 有客户端和服务端两种实现方法。
客户端均衡(Client-Side LB)
客户端均衡(Client-Side LB)是Oracle 8i 使用的方法,配置方法是在客户端的tnsnames.ora 文件中加入:LOAD_BALANCE=YES 条目。
当客户端发起连接时,会从地址列表中随机的选取一个,在使用随即算法把连接 请求分配到各个实例。
一个Clint-Side LB的TNS 配置文件如下:
rac=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.61)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.63)(PORT = 1521))
(LOAD_BALANCE = yes)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME =leo)
)
)
1.单纯的Client-Side LB 测试(1) 在节点1 客户端tnsnames.ora添加以下内容
rac=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.61)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.63)(PORT = 1521))
(LOAD_BALANCE = yes)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME =leo)
)
)
(2) 数据库的准备工作
去掉 Server-Side Load Balance 内容:
SQL> alter system set remote_listener='' scope=spfile sid='*';
System altered.
重启Database 和Listener
leo 服务名
rac1,rac2 主机名
[[email protected] ~]$srvctl stop database -d leo
[[email protected] ~]$srvctl stop listener -n rac1
[[email protected] ~]$srvctl stop listener -n rac2
[[email protected] ~]$srvctl start listener -n rac2
[[email protected] ~]$srvctl start listener -n rac1
[[email protected] ~]$srvctl start database -d leo
重启后
清空两个节点的Listener 日志
节点1 执行
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac1/listener/trace
[[email protected] trace]# cat /dev/null > listener.log
节点2 执行
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# cat /dev/null > listener.log
(3) 创建两个脚本test.sh和test.sql,test.sh 是一个shell 脚本,脚本主体就是通过一个循环建立若干个到rac的连接,然后执行test.sql脚本。 test。sql 只有一个sql语句打印输出连接到的实例名。
脚本分别如下:
test.sh 脚本内容:
#!/bin/bash
#Usage: test leo 4000
count=0
while [ $count -lt $2 ]
do
count=`expr $count + 1`
sqlplus -s leo/leo@$1 @test.sql
#sleep 1
done
test.sql 脚本内容:
col "Instance_name" format a20
select instance_name from v$instance
/
exit;
操作步骤,在节点1 执行:
[[email protected] ~]# cd /
[[email protected] /]# mkdir test
[[email protected] /]# chown -R oracle:oinstall /test
[[email protected] /]# su - oracle
[[email protected] ~]$ cd /test
[[email protected] test]$ touch test.sh
[[email protected] test]$ touch test.sql
--添加脚本内容:
[[email protected] test]$ cat test.sh
#!/bin/bash
#Usage: test leo 4000
count=0
while [ $count -lt $2 ]
do
count=`expr $count + 1`
sqlplus -s leo/leo@$1 @test.sql
#sleep 1
done
[[email protected] test]$
[[email protected] test]$ cat test.sql
col "Instance_name" format a20
select instance_name from v$instance
/
exit;
(4) 执行测试脚本,参数1000代表建立1000个连接,rac 是数据库连接的服务名
要切换到oracle 用户下执行
[[email protected] test]$ ./test.sh rac 1000 > rac.log
(5)检查结果。
节点1 执行
[[email protected] test]$ grep leo1 rac.log |wc -l
514
[[email protected] test]$ grep leo2 rac.log |wc -l
486
(6)提取两个节点的LIstener 日志内容
节点1
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac1/listener/trace
[[email protected] trace]# grep establish listener.log |wc -l
514
说明节点1 共接受了514个用户连接
[[email protected] trace]# grep INSTANCE_NAME=leo listener.log |wc -l
0
说明这514个连接中又0个是实例2的Listener路由过来的。计算Client_Side Load Balance 为514-0=514,也就是说客户端发出了514个实例到节点1
的连接请求。
节点2
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# grep establish listener.log |wc -l
486
说明节点2 共接受了486个用户连接
[[email protected] trace]# grep INSTANCE_NAME=leo listener.log |wc -l
0
说明这486个连接中又0个是实例1的Listener路由过来的。计算Client_Side Load Balance 为486-0=486,也就是说客户端发出了486个实例到节点2
的连接请求
这个例子只是用了Client-Side Load Balance ,也就是客户端从TNS 地址列表中随机选择的实例发送的请求,这个随机算法结果就是514/486,
可见在这个随机算法还是比较平均的。
服务器端均衡(Server-Side LB)
Server-Side LB 是从Oracle 9i引入的。 它的实现依赖于Listener收集负载信息。 在数据库运行过程中,
PMON后台进程会收集系统的负载信息,然后登记到Listener中。
最少1分钟,最多10分钟PMON就要做一个信息更新,并且如果节点的负载越高,更新频率就越高,
以保证Listener能掌握每个节点准确的负载情况。
如果Listener关闭了,PMON进程会每隔1秒钟检查Listener是否重启。除了这个自动的,定时的更新任务外,
用户也可以使用alter system register 命令来手工进行这个过程。
这个自动更新动作,可以从Listener的日志中看到
对于Client-Side LB,需要在客户的tnsnames条目中加入LOAD_BALANCE=YES,
对于Server-side LB,需要配置REMOTE_LISTENER这个参数。
注意:
在Oracle里面配置Service-side LB还需要从各个节点实例的listener.ora文件中删除或者注释缺省产生的SID_LIST_LISTENER_NodeName条目,
这样才能保证Listener获得的信息是动态注册的,而不是从文件中读取的静态信息。
先删除:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = leo)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1)
(SID_NAME = leo2)
)
)
2. 测试单纯的Server-Side LB
(1) 在节点1 客户端tnsnames.ora添加以下内容
rac=
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.61)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.63)(PORT = 1521))
(LOAD_BALANCE = off)
)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME =leo)
)
)
(2) 数据库的准备工作
启用 Server-Side Load Balance :
SQL> alter system set remote_listener='TEST' scope=spfile sid='*';
System altered.
SQL> show parameter remote_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
remote_listener string TEST
重启Database 和Listener
leo 服务名
rac1,rac2 主机名
[[email protected] ~]$srvctl stop database -d leo
[[email protected] ~]$srvctl stop listener -n rac1
[[email protected] ~]$srvctl stop listener -n rac2
[[email protected] ~]$srvctl start listener -n rac2
[[email protected] ~]$srvctl start listener -n rac1
[[email protected] ~]$srvctl start database -d leo
重启后
清空两个节点的Listener 日志
节点1 执行
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac1/listener/trace
[[email protected] trace]# cat /dev/null > listener.log
节点2 执行
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# cat /dev/null > listener.log
(3) 执行测试脚本,参数1000代表建立1000个连接,rac 是数据库连接的服务名
要切换到oracle 用户下执行
[[email protected] test]$ ./test.sh rac 1000 > rac.log
(4)检查结果。
节点1 执行
[[email protected] test]$ grep leo1 rac.log |wc -l
505
[[email protected] test]$ grep leo2 rac.log |wc -l
495
(5)提取两个节点的LIstener 日志内容
节点1
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac1/listener/trace
[[email protected] trace]# grep establish listener.log |wc -l
1000
说明节点1 共接受了1000个用户连接
[[email protected] trace]# grep INSTANCE_NAME=leo listener.log |wc -l
0
说明这1000个连接中又0个是实例2的Listener路由过来的。计算Client_Side Load Balance 为1000-0=1000,也就是说客户端发出了1000个实例到节点1
的连接请求。
节点2
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# pwd
/u01/app/grid/diag/tnslsnr/rac2/listener/trace
[[email protected] trace]# grep establish listener.log |wc -l
495
说明节点2 共接受了495个用户连接
[[email protected] trace]# grep INSTANCE_NAME=leo listener.log |wc -l
495
说明这495个连接中又0个是实例1的Listener路由过来的。计算Client_Side Load Balance 为495-495=0,也就是说客户端发出了0个实例到节点2
的连接请求
在这个例子中,客户端的tnsnames.ora 配置中,使用 LOAD_BALANCE = off,禁用Client-Side LB,所以用户的1000个连接全部发给节点1,因为
在地址列表中 192.168.1.61 是放在第一条,其他结果说以下几条。
Listener 路由到实例的连接请求数量:实例1=1000-495=505,实例2=0-0=0
远程的Listener 路由到本实例的连接请求数量:实例1=0,实例2=495
Server-Side Load Balance 的分配=505/495
版权声明:本文为博主原创文章,未经博主允许不得转载。