一. 服务器端均衡(Server-Side
LB)工作原理:
1.该均衡实现是依赖于Listener收集的负载信息。在数据库运行过程中,PMON后台进程会收集数系统的负载信息,然后登记到Listener中。
2.PMON进程不仅会向本地的Listener注册,也会想其他节点上的Listener注册,但到底向何处注册,是由Remote_Listeners和Local_Listener这两个参数决定。Local_Listener不用设置,而Remote_Listeners需要设置,参数值有一个tnsnames项。
3.当收到客户端连接请求时,就会把连接转给负载最小的节点,这个节点可能是自己,也可能是其他节点,也就是Listener会转发客户端的连接请求。
配置方法:
SQL> show parameter listener;
NAME TYPE
VALUE
------------------------------------ -----------
------------------------------
local_listener string
remote_listener string LISTENERS_DEVDB
tnsnames.ora
LISTENERS_DEVDB =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT =
1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT =
1521))
)
listener.ora(除掉SID_LIST_LISTENER_NAME项)
LISTENER_RAC1 =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT =
1521)(IP = FIRST))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.11)(PORT =
1521)(IP = FIRST))
)
)
二. LOCAL_LISTENER 与动态注册
关于动态注册,参考我的Blog:
Oracle Listener 动态注册 与 静态注册
动态注册是在instance启动的时候,PMON进程根据init.ora中的instance_name,service_names两个参数将实例和服务动态注册到listener中。
注册到监听器中的实例值从init.ora文件中的instance_name参数取得。如果该参数没有设定值,那么它将取init.ora文件中的db_name的值。如果在RAC中配置,您必须将集群中每个实例的instance_name参数设置为一个唯一的值。
注册到监听器中的服务值从init.ora文件中的参数service_names取得。如果该参数没有设定值,数据库将拼接init.ora文件中的
db_name和db_domain的值来注册自己。如果选择提供service_names值,您可以使用完全限定的名称(比如
orcl.oracle.com)或缩写的名称(比如orcl)。如果选择缩写的名称并设置了db_domain参数,注册到监听器中的服务将是
service_name值和db_domain值的拼接。
这里要注意的是:动态注册默认只注册到默认的监听器上(名称是LISTENER、端口是1521、协议是TCP),因为pmon只会动态注册port等于1521的监听,否则pmon不能动态注册listener,如果需要向非默认监听注册,则需要配置local_listener参数。
因此我们看到了LOCAL_LISTENER的作用。 监听的端口默认是1521,但是很多情况下,处于安装考虑,不会使用1521端口,因为在这种情况下使用动态注册就需要配置LOCAL_LISTENER参数。
将监听的信息添加到tnsnames.ora 文件中。
因为pmon在动态注册监听时要从tnsnames.ora中读取相关信息。
LISTENER _RACDB1 =
(ADDRESS_LIST =
(ADDRESS
= (PROTOCOL = TCP)(HOST = rac1)(PORT =1522))
)
然后以sys用戶修改local_listener参数:
SQL> alter system set local_listener= LISTENER _RACDB1;
也可以直接指定:
SQL> alter system set LOCAL_LISTENER='(ADDRESS = (PROTOCOL =
TCP)(HOST = rac1)(PORT = 1522))';
这样,在DB启动的时候,就会自动的把instence_name 和service_name注册到监听。
如果在这期间,监听重启了,监听里的信息也会丢失,这时就需要手动的把信息注册到监听:
SQL> alter system register;
三. LOCAL_LISTENER, REMOTE_LISTENER 与RAC CLIENT-SIDE TAF 和 LOAD
BALCANING
3.1 参数说明
在Blog:
Oracle RAC Failover 详解
中对RAC的Failover做了分类:Client-Side TAF 和 Server-side TAF.
Service-SideTAF是在服务器上配置的,Client-Side TAF是在客户端配置的。
Client-Side TAF 是在客户端修改tnsnames.ora
文件来配置的,如果有很多客户端使用这个数据库,那么每次微笑调整都需要把所有的计算机更改一遍,既低效又容易出错。而Service-Side
TAF
通过结合Service,在数据库里保存FAIL_MODE的配置,把所有的TAF配置保存在数据字典中,从而省去了客户端的配置工作,客户端的TNS文件就不需要任何TAF的配置选项了。
关于Server-side TAF 配置参考Blog:
How To Configure Server Side Transparent Application Failover [ID
460982.1]
LOCAL_LISTENER 和 REMOTE_LISTENER 这2个参数就是配置Client-Side TAF的。
官网的配置参考:
10g & 11g Configuration of TAF(Transparent Application
Failover) and Load Balancing [ID 453293.1]
3.2 Client-Side TAF 配置
3.2.1主机信息如下
Node1:
Hostname: node1.idc.oracle.com
VIP Hostname: node1-vip.idc.oracle.com
Database Service_names:
service.idc.oracle.com
SID: sid1
Node2:
Hostname:
node2.idc.oracle.com
VIP Hostname:
node2-vip.idc.oracle.com
Database Service_names:
service.idc.oracle.com
SID: sid2
3.2.2 Node1配置
(1)修改Listener.ora文件
LISTENER_NODE1=
(DESCRIPTION =
(ADDRESS_LIST
=
(ADDRESS = (PROTOCOL = TCP)(HOST =
node1-vip.idc.oracle.com)(PORT =
1521)(IP=FIRST)) --私有IP
(ADDRESS = (PROTOCOL = TCP)(HOST =
node1.idc.oracle.com)(PORT =
1521)(IP=FIRST)) --public IP
)
)
(2)启动Listener
$ lsnrctl start LISTENER_NODE1
(3)修改Tnsnames.ora文件
NODE1_LOCAL=
(ADDRESS = (PROTOCOL =
TCP)(HOST=node1-vip.idc.oracle.com)(PORT =
1521))
测试:
$ tnsping node1_local
(4) 设置node1的local_listener参数
sql > alter system set LOCAL_LISTENER='node1_local'
scope=both sid='sid1' ;
3.2.3 NODE2 配置
(1)修改Listener.ora文件
LISTENER_NODE2=
(DESCRIPTION =
(ADDRESS_LIST
=
(ADDRESS=(PROTOCOL=TCP)(HOST=node2.idc.oracle.com)(PORT=1521)(IP=FIRST))
(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip.idc.oracle.com)(PORT=1521)(IP=FIRST))
)
)
(2)启动Listener
$ lsnrctl start LISTENER_NODE2
(3)修改Tnsnames.ora文件
NODE2_LOCAL=
(ADDRESS = (PROTOCOL =
TCP)(HOST = node2-vip.idc.oracle.com)(PORT =
1521))
验证:
$ tnsping node2_local
(4)设置local_listener 参数
sql > alter system set LOCAL_LISTENER='node2_local'
scope=both sid='sid2' ;
3.2.4 在node1和node2的 tnsnames.ora 文件添加如下内容
NODE_REMOTE =
(DESCRIPTION =
(ADDRESS_LIST
=
(ADDRESS = (PROTOCOL =
TCP)(HOST=node1-vip.idc.oracle.com)(PORT =
1521))
(ADDRESS = (PROTOCOL =
TCP)(HOST=node2-vip.idc.oracle.com)(PORT =
1521))
)
)
测试:
$ tnsping node_remote
3.2.5 在所有节点设置remote listener
sql> alter system set REMOTE_LISTENER='node_remote'
scope=both;
3.2.6 在客户端设置的tnsnames.ora 设置TAF
RACTAF=
(DESCRIPTION =
(ADDRESS_LIST =
(LOAD_BALANCE = yes)
(FAILOVER=ON) -- 这个参数是默认值,可以不写
(ADDRESS = (PROTOCOL = TCP)(HOST =
node1-vip.idc.oracle.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST =
node2-vip.idc.oracle.com)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME =
service.idc.oracle.com)
(failover_mode=(type=select)(method=basic))
)
)
当客户端发出连接请求给Server端listener的时候,通过local_listener注册的服务接收这个连接请求,然后由master
instance来决定这个连接请求应该由哪个目标instance发出server
process响应这个连接请求。如果启用负载均衡,那么主节点会选择cpu负载最小的那个instance,此时:
如果master分配的目标instance是local listener machine,那么直接通过local server
listener,开启后台的server process,处理发出conn的客户端,建立连接,处理会话;
如果master分配的目标instance不是local listener
machine,那么会通过remote_listener这个参数,把连接请求转移到remote machine上的listener,
然后由remote service listener发出一个server process返回客户端,建立连接,处理会话.
当conn建立连接以后,listener就没有用了,不会再用到了,如果这个时候,已经连接的那个instance
down了,会重新由新分配的master
instance通过remote_listener切换到可用instance,此时客户不会发现连接中断。conn 和
select操作是不会中断的。
当实例1注册监听的时候,即使节点2的instance没有启动,也会通过remote_listener在节点2
server上注册相应的listener1. 它是在数据库启动的时候,添加到相应的listener
service里的。