♣
问题
在Oracle中,如何在RAC服务器端配置TAF?
♣
答案
RAC的本质是提供负载均衡(Load Balancing)和故障切换(Failover),如下图所示:
(一)负载均衡(Load Balancing)
负载均衡就是使工作负载均匀地分配到集群的各个节点,从而尽可能地发挥集群中的每个节点的性能,并提高集群的可用性和吞吐量。在RAC中,负载均衡分为两种,一种是基于客户端连接的负载均衡(Client-Side Load Balancing),也称连接数负载均衡;另外一种是基于服务器端的负载均衡(Server-Side Load Balancing)。客户端负载均衡通常是在客户端的tnsnames.ora中多添加一个链接地址以及LOAD_BALANCE=yes,而服务器端的负载均衡则相对复杂。
下面给出客户端连接的负载均衡配置:
lhrdb =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
)
(CONNECT_DATA =
(SERVICE_NAME = lhrdb)
)
)
而下面这种配置方式永远只能连接到节点1,只有当节点1挂掉的时候才能连接到节点2上去(这里其实就是故障切换,默认FAILOVER的值ON,表示开启故障切换):
lhrdb01 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = lhrdb)
)
和客户端负载均衡相比,服务器端负载均衡才是真正基于工作负载进行的负载均衡。服务器端的负载均衡需要在服务器端进行配置(只需要设置参数LOCAL_LISTENER和REMOTE_LISTENER即可),而客户端需要通过SCAN监听器连接到数据库才能实现服务器端负载均衡。PMON会将本地实例能够提供的服务根据LOCAL_LISTENER和REMOTE_LISTENER参数的设置,注册到对应的监听程序上去,同时,PMON还会把本地节点的工作负载也同时注册到监听程序上去。通过这种方式,每个节点的监听程序就能够知道每个节点的工作负载状况,当监听程序收到客户端连接的消息时,就可以把连接分配给工作负载最小的节点。这种设计还能够保证客户端负载均衡和服务器端负载均衡互不冲突,也就是说,客户可以同时使用客户端和服务器端负载均衡。可以查询视图V$SERVICEMETRIC来获取服务的工作负载信息。
服务器端的负载均衡示例,其中“192.168.59.174”为SCAN的IP地址:
lhrrac102 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.174)(PORT = 1522))
)
(CONNECT_DATA =
(SERVICE_NAME = lhrrac1)
)
)
(一)故障切换
故障切换(Failover)也叫故障转移,是指当客户端所连接的节点出现问题时,客户端能够透明地切换到集群的其它节点。故障切换可以分为:连接时故障切换(Connect-Time Failover)和已存在连接的故障切换(Run-Time Failover)。
1、连接时故障切换
连接时故障切换是在客户端连接数据库时发生的。当客户端在连接一个地址出错时会自动尝试配置的其它地址,直到连接一个地址成功。连接时故障切换的配置很简单,只需要在客户端的tnsnames.ora别名中包含选项FAILOVER=ON就可以了。需要注意的是,FAILOVER的值默认为ON,即用户无需手动添加,该特性也会被默认使用。
连接时故障切换示例:
lhrrac104 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.172)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.173)(PORT = 1521))
(FAILOVER = ON)
)
(CONNECT_DATA =
(SERVICE_NAME = lhrrac1)
)
)
2、已存在连接的故障切换
已存在连接的故障切换是指对于已经连接到数据库的客户端连接,当前连接的数据库实例或服务出现问题时,把已经存在的数据库连接(会话)透明地迁移到其它数据库实例中。Oracle实现的方式主要有TAF(Transparent Application Failover,透明应用故障切换)和FCF(Fast Connection Failover,快速连接故障切换)。TAF是针对使用OCI(Oracle Call Interface)连接的特性,而FCF是针对使用非OCI连接的特性,例如jdbc thin client连接。
TAF可以在客户端或者服务器端进行配置,如果用户在两端都进行了配置,那么服务器端的TAF配置会覆盖客户端TNS连接串中的TAF配置,也就是说,服务器端的配置具有更高的优先级。
下面分别介绍客户端和服务器端的TAF配置方法。
客户端TAF配置(Client-Side TAF)是通过在tnsnames.ora文件中添加FAILOVER_MODE部分来实现的,例如:
tns_lhrdb =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.132)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.59.131)(PORT = 1521))
(LOAD_BALANCE = on)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = lhrdb)
(FAILOVER_MODE =
(TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5)
)
)
)
其中,
① TYPE:指定TAF的类型,包括SESSION、SELECT和NONE。
a. SESSION:表示在故障切换发生后,新的连接会被创建到正常实例,问题出现时正在运行的操作不会被继续执行。
b. SELECT:表示在故障切换发生后,新的连接会被创建到正常实例,问题出现时正在运行的SELECT语句会被继续执行,在新的节点上继续返回后续结果集,而已经返回的记录集则抛弃。
c. NONE:表示不会发生故障切换,即禁用TAF。
对于正在执行的操作,如果是SELECT语句,那么切换后会继续运行;但是对DML语句,若未提交则它们会被自动回滚,用户需要重新运行。如果用户运行了一些PL/SQL程序,那么和PL/SQL程序相关的信息(例如:一些变量的定义、包的状态等)在切换后也不会被保留。
例如,用户正在节点1上执行查询,整个结果集有1W条记录,现在已经从节点1上返回9000条记录,这时节点1宕机,用户连接被转移到节点2上。如果是SESSION模式,那么需要重新执行查询语句;如果是SELECT模式,那么会从节点2上继续返回剩下的1000条记录,而从节点1上返回的9000条记录不再重复返回给用户,对于用户而言,感受不到这种切换。为了实现SEELCT方式,Oracle必须为每个会话保存更多的内容,包括游标、用户上下文等,这是用资源换时间的方案。
② METHOD:指定TAF的方法,选项有BASIC和PRECONNECT。
a. BASIC表示数据库会在故障切换时在目标实例中创建会话。
b. PRECONNECT表示数据库会在最初建立连接时就同时建立到所有实例的连接,当发生故障时就可以立刻切换到其它链路上,这会对目标实例产生额外的工作负载。
需要注意的是,PRECONNECT选项只能用于客户端的TAF配置,不能用于服务端的TAF配置。如果TAF是在服务端设置,那么FALIOVER METHOD只能设置为BASIC。BASIC方式在Failover时会有延迟,PRECONNECT方式虽然没有时间延迟,但是会建立多个冗余连接会消耗更多资源,两者就是用时间换资源和用资源换时间的区别。
③ RETRIES:在失败之前尝试故障切换的次数。
④ DELAY:每次切换的时间间隔。
客户端的TAF的麻烦之处在于,所有客户端均需要配置,如果有大量客户端,那么需要在每一个客户端都配置一遍。而服务端的TAF可以只配置一次(只配置IP、端口、服务名,该服务可以切换)即可实现Failover。服务器端TAF(Server-Side TAF)配置是通过创建服务的方式来实现的,即通过srvctl add service命令来配置,创建服务的命令如下所示:
srvctl add service -d <db_unique_name> -s <service_name> -r <preferred_list> -a <available_list> -P <method> -e <Failover type> -w <Failover delay> -z <Failover retries>
其中,
l -d选项指定服务所运行的数据库唯一名称(db_unique name)。
l -s选项指定新创建的数据库服务名称。
l -r选项指定数据库服务默认运行的数据库实例列表。
l -a选项指定当运行数据库服务的默认实例出现问题时,故障切换的目标实例。
l -e选项指定TAF的类型。
l -w选项指定每次切换的时间间隔。
l -z选项指定切换的次数。
需要注意的是,执行该命令时需要以Oracle用户来添加。下面给出一个示例:
添加:srvctl add service -d orastrac -s lhrdb.haha -r 'orastrac1,orastrac2' -P basic -e SESSION -w 5 -z 3
启动:srvctl start service -d orastrac -s lhrdb.haha
查看配置:srvctl config service -d orastrac
查询:
col NAME format a10
col failover_method format a11 heading 'METHOD'
col failover_type format a10 heading 'TYPE'
col failover_retries format 9999999 heading 'RETRIES'
col goal format a10
col clb_goal format a8
col AQ_HA_NOTIFICATIONS format a5 heading 'AQNOT'
SELECT NAME, FAILOVER_METHOD, FAILOVER_TYPE, FAILOVER_RETRIES,GOAL, CLB_GOAL,AQ_HA_NOTIFICATIONS FROM DBA_SERVICES d WHERE d.NAME = 'lhrdb.haha';
在Oracle 11.2之前,需要通过DBMS_SERVICE包来添加RETRIES和DELAY等参数:
begin
DBMS_SERVICE.CREATE_SERVICE(service_name => 'dg_taf_lhr',
network_name => 'dg_taf_lhr',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type => 'SELECT',
failover_retries => 300,
failover_delay => 5);
end;
/
BEGIN
DBMS_SERVICE.MODIFY_SERVICE(service_name => 'dg_taf_lhr',
aq_ha_notifications => true,
failover_method => dbms_service.failover_method_basic,
failover_type => dbms_service.failover_type_select,
failover_retries => 180,
failover_delay => 5,
clb_goal => dbms_service.clb_goal_long);
END;
/
& 说明:
有关RAC中负载均衡和故障切换的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2142102/。
本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗