1、Oracle RAC 负载均衡和透明应用失败切换的配置和测试过程第 1 节 测试名词解释这个文档被用来给配置提供一个指引:1) 仅仅客户端连接时间负荷平衡2) 服务器和客户端同时的连接负荷平衡3) 仅仅服务器端的连接负荷平衡4) 透明的应用 failover在配置 Net Services 特征前,这有一些每种方法的单一和混合的应用的定义:1.1 客户端连接 failover连接时失败切换可以使客户端初始化连接第一次失败时可以连接到另外一个侦听器。侦听器协议地址的数量决定了有多少个侦听器可以被尝试。没有连接时失败切换,Oracle Net仅仅连接一个侦听器,默认时是 on。1.2 透明应用 F
2、ailover透明应用 Failover(TAF )是高可用运行环境的一种运行时的 failover,例如 Oracle 9i RAC和 Oracle 9i Real Application Clusters Guard。TAF 失败和重新建立应用 -到-服务的连接。它可以使客户端应用程序在连接失败时自动重新新连接到数据库,重新执行一个程序中的SELECT 操作。重新连接自动发生在 Oracle Call Interface(OCI)库。1.3 客户端连接 Load Balancing客户端 load balancing 特征能使客户端在所有的侦听器中随机选择廉洁。Oracle Net 程序通
3、过在一个随机的协议地址列表的顺序,平衡不同的侦听器的负载。没有客户端的 load balancing,Oracle Net 程序顺序的处理协议地址列表中的地址直到一个成功。1.4 服务器端侦听器连接 Load Balancing服务器端侦听器连接 load balanceing 特征在不同进程和 dispatchers 之间提高了不平衡激活的连接数目的执行性,侦听器选择最少负载的 dispatcher 来管理进行的客户端的连接。在Oracle 9i RAC 环境中,连接时的 load balancing 也有平衡多个进程的激活的连接的能力。由于 dynamic service registra
4、tion,一个侦听器总是依赖负载的信息,而无论它们的位置,而知道所有的进程和 diapathers,如果共享服务已经配置,一个侦听器决定哪一个进程,哪一个 dispathers 发送客户端的请求。在一个共享服务器的配置里,侦听器选择一个 dispatcher在以下的顺序里:1. 最小负载的节点2. 最小负载的进程3. 最小负载的 dispatcher for that instance在一个专用的服务配置,侦听器以下面的顺序选择一个进程:1.最少负载的节点2.最少负载的进程如果一个数据库服务有多个进程在多个节点上,侦听器选择在最少负载的节点上的最小负载的进程。如果共享服务已经配置,则选择进程的
5、最小负载的 dispatchers 被选择第 2 节 配置实例主要包括的是服务器端的 init.ora,listener.ora 和 tnsnames.ora 文件以及客户端的 tnsnames.ora文件。针对本项目的双节点的群集设置,主要配置如下:hostname service name sid name instance_name ORACLE_HOME= = = = =node1 test1 rac rac1 rac1 /oracle/product/9201node2 test2 rac rac2 rac2 /oracle/product/92012.1 init.ora所有节点的
6、 init.ora 文件必须配置如下:remote_listener=LISTENERS_RACrac1.local_listener=“LISTENER_rac1”rac2.local_listener=“LISTENER_rac2“# dispatchers=“(pro=ipc)(dis=0)“db_name=rac /*可以不用 */rac1.instance_name=rac1rac2.instance_name=rac22.2 show parameter既然 service_names 在 init.ora 文件中没有规定,它缺省是 db_name.db_domain。每一个节点列
7、出它的主机名和 instance_name。随着以上的设置,在你启动进程后,当你从第一个节点检查 sql 会话时,你将会发现下面的信息:1)节点一SQL show parameter db_nameNAME TYPE VALUEdb_name string racSQL show parameter db_domainNAME TYPE VALUEdb_domain stringSQL show parameter service_namesNAME TYPE VALUEservice_names string racSQL show parameter instance_nameNAME T
8、YPE VALUEinstance_name string rac1SQL show parameter listenerNAME TYPE VALUElocal_listener string LISTENER_rac1mts_listener_address stringmts_multiple_listeners boolean FALSEremote_listener string LISTENERS_RAC2)节点二SQL show parameter db_nameNAME TYPE VALUEdb_name string racSQL show parameter db_doma
9、inNAME TYPE VALUEdb_domain stringSQL show parameter service_namesNAME TYPE VALUEservice_names string racSQL show parameter instance_nameNAME TYPE VALUEinstance_name string rac2SQL show parameter listenerNAME TYPE VALUElocal_listener string LISTENER_rac2mts_listener_address stringmts_multiple_listene
10、rs boolean FALSEremote_listener string LISTENERS_RAC2.3 listener.oratest1 listener.ora fileLISTENER =(DESCRIPTION_LIST =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC)(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)SID_LIST_LISTENER =(SID_LIST =(SID_DESC
11、=(SID_NAME = PLSExtProc)(ORACLE_HOME = /oracle/product/9201)(PROGRAM = extproc)(SID_DESC =(ORACLE_HOME = /oracle/product/9201)(SID_NAME = rac1)Test2 listener.ora fileLISTENER =(DESCRIPTION_LIST =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC)(ADDRESS_LIST =(ADDRESS = (PROTOCO
12、L = TCP)(HOST = test2)(PORT = 1521)SID_LIST_LISTENER =(SID_LIST =(SID_DESC =(SID_NAME = PLSExtProc)(ORACLE_HOME = /oracle/product/9201)(PROGRAM = extproc)(SID_DESC =(ORACLE_HOME = /oracle/product/9201)(SID_NAME = rac2)2.4 tnsnames.oratest1test2 and client side tnsnames.ora fileLISTENERS_RAC =(ADDRES
13、S_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)LISTENER_RAC2 =(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)LISTENER_RAC1 =(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)RAC2 =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =
14、(PROTOCOL = TCP)(HOST = test2)(PORT = 1521)(CONNECT_DATA =(SERVICE_NAME = rac)(INSTANCE_NAME = rac2)RAC1 =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)(CONNECT_DATA =(SERVICE_NAME = rac)(INSTANCE_NAME = rac1)RAC =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL
15、 = TCP)(HOST = test1)(PORT = 1521)(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)(LOAD_BALANCE = on)(FAILOVER=on)(CONNECT_DATA =(SERVER = DEDICATED)(SERVICE_NAME = rac)(failover_mode=(type=select)(method=basic)/*TAF 使用的配置*/)EXTPROC_CONNECTION_DATA =(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PRO
16、TOCOL = IPC)(KEY = EXTPROC)(CONNECT_DATA =(SID = PLSExtProc)(PRESENTATION = RO)/failover =(DESCRIPTION =(enable=broken)(LOAD_BALANCE = yes)(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)(CONNECT_DATA =(SERVICE_NAME = rac)(failover_mode=(ty
17、pe=select)(BACKUP=cletus)(method=basic)/2.5 配置注释1) LISTENERS_RAC, LISTENER_rac1, LISTENER_rac2 是 net_service_name (连接描述) for remote_listener 和 local_listener.在客户端,你并不需要这些参数。2) failover 是为透明应用失败切换(TAF)测试的 net_service_name 。3) RAC 是客户端的负载平衡的 net_service_name,如果你不需要配置 TAF,这有另外一种设置客户端连接负载平衡的配置方法, 下面是另外一
18、种办法:RAC_alternative =(DESCRIPTION =(ADDRESS_LIST =(LOAD_BALANCE = yes)(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)(CONNECT_DATA =(SERVICE_NAME = rac)注: (load_balance=yes)可以使 Net 程序以一种随机的顺序处理地址列表中的侦听器,平衡不同侦听器之间的负载。当被设成 OFF,Net 程序将以顺序的方式处
19、理直到一个成功。这个参数必须在你的 net service name (connect descriptor)正确的配置. 缺省情况下这个参数被设成 ON, Load balancing 能联系到 ADDRESSes 和 DESCRIPTIONs 的设置并且在ADDRESS_LIST 里进行规定。如果你使用 ADDRESS_LIST,(load_balance=yes)将会在(ADDRESS_LIST=)部分。如果你不使用 ADDRESS_LIST, (load_balance=yes)将会在(description=)部分里,我建议不使用(ADDRESS_LIST=) 字句。4)(failo
20、ver=on)缺省是在 ADDRESS_LISTs, DESCRIPTION_LISTs 和一个 DESCRIPTIONs的设置里,因此你不需要规定。它是作为 connect-time-failover,请注意不要与透明应用切换(TAF) 发生冲突。5)(failover_mode=):在 FAILOVER_MODE 参数必须包括在一个 net_service_name 的CONNECT_DATA 部分。6)这儿在(failover_mode=)里没有(backup=failover),7) There is no (backup=failover) in (failover_mode=),
21、this 暗示着(failover_mode=(type=select)(method=basic)(backup=failover),它意味着无论是否 failover 发生,连接的会话将会切换到 net_service_name 又进行失败切换,当使用 PRECONNECT 来pre-establish 连接时 BACKUP 应该被规定,需要详细的 TAF 信息,请参考 Oracle 官方文档。第 3 节 测试方法测试方法论:1. 你总是先开始简单后转到更复杂的测试。2、在你启动侦听和进程之后,检查从命令“lsnrctl services”的输出, ”lsnrctl status”不论你设
22、置正确与否都不能给你提供有效的信息。如果”lsnrctl services”输出不正确,继续之前更正listener.ora 或 init.ora 文件。3、从服务器端测试客户端的 load balance 连接,检查 verify.sql 提供的信息,你可以注释出你不需要的 sql 脚本。4、从服务器端测试服务器端侦听器 load balance,并且检查它的输出信息。5、从服务器端测试 TAF 的连接,并且在关闭进程或重启服务器之前检查 failover_type 和failover_mothod。3.1 测试脚本和设置=在启动测试之前,可以使用下面的行如你所要的重复多次创建一个 loop
23、.sh 文件loop.shnohup sqlplus system/systemrac verify.sql REM the following query is for load balancing verificationselect instance_name from v$instance;exitREM you can also combine two queries:col inst_id format 999col sid format 999col serial# format 9999999col failover_type format a13col failover_me
24、thod format a15col failed_over format a11select inst_id, sid, serial#, failover_type, failover_method, failed_over from v$session where username = system;REM a simple select to see the distribution of users when testing connection REM load balancingselect inst_id, count(*) from gv$session group by i
25、nst_id;运行这个测试,简单的输入”./loop.sh”,输出文件将被定向到 nohup.out。=3.2 客户端连接 Load Balancing 测试不需要服务器端侦听器连接 load balancing,而仅仅客户端的 load balancing,移除 init.ora 文件的 remote_listener 并且重新启动所有进程,这样将没有远程进程在侦听器注册,你将仅仅为每个进程发现本地服务器。Test1$ lsnrctl service test2$ lsnrctl service 简单运行 ./loop.sh脚本,并且定期检查输出信息。 grep rac1 nohup.out
26、 | wc -l grep rac2 nohup.out | wc -l测试表格:检查次数 连接次数 RAC1RAC2测试结论1 2 3 4 5 6 总测试结论和效果 =3.3 服务器端连接 Load Balancing (混合客户端连接 Load Balancing)服务器端的侦听器负载均衡是侦听器路由连接到低负荷的进程,添加 remote_listener 参数到 init.ora 文件并且重启所有的进程,记住检查lsnrctl services的输出信息:Test1 $ lsnrctl service test2 $ lsnrctl service 注意: 比较“lsnrctl stat
27、us”下面的输出,你将会发现比上面更多的信息,请注意到在一个节点它自己的进程,例如:test1 上的 rac1,你将会有本地的服务和远程的服务。别的远程进程,你仅仅发现远程服务器。请确认远程服务器地址是正确而不是空的主机名:test1 $ lsnrctl status=简单运行 ./loop.sh脚本,并且定期检查输出信息。 grep rac1 nohup.out | wc -l grep rac2 nohup.out | wc -l测试表格:检查次数 连接次数 RAC1RAC2测试结论1 2 3 4 5 6 总测试结论和效果 After the testing, you can check
28、lsnrctl services from all 2 nodes again:=3.4 仅仅服务器端 Load Balancing 测试如你所喜欢,你去除客户端的负载平衡可以移除或注释出客户端的侦听器的(LOAD_BALANCE = yes)并且检查服务器端的负载平衡属性。客户端的 tnanames.ora 文件:( rac =# (LOAD_BALANCE = yes)(ADDRESS = (PROTOCOL = TCP)(HOST = test1)(PORT = 1521)(ADDRESS = (PROTOCOL = TCP)(HOST = test2)(PORT = 1521)(CON
29、NECT_DATA =(SERVICE_NAME = rac)在这种情况下,所有的连接全部到 test1 的侦听器并且被路由到别的进程。测试结果: grep rac1 nohup.out | wc -l grep rac2 nohup.out | wc -l测试表格:检查次数 连接次数 RAC1RAC2测试结论1 2 3 4 5 6 总测试结论和效果 在测试完成之后,在这个的测试里,可以使用下面的输出信息,与前面的测试进行比较。test1 $ lsnrctl servicestest2 $ lsnrctl services你将会注意到从 test1 的 lsnrctl service输出信息有所有的节点连接总数信息。然而,另外一个节点 test2 有它自己的进程建立连接总数信息。这是由于没有客户端的 load balancing (load_balance=on),所有的连接连接到 test1(地址列表中的第一个地址)并且被 test1 路由到别的进程。