首页 > 数据库 > Oracle > Oracle RAC 环境下的连接管理
是指不从连接池中取得已有连接,而是直接连接 Oracle 数据库时的 Failover。在 Oracle RAC 11gR2 之前,Connect Time Connection Failover 是非常容易实现的,只需要在相关的 tnsnames.ora 中指定多个 vip,同时指定 FAILOVER=ON 就好了。如下所示:
(DESCRIPTION=
(FAILOVER=ON)
(ADDRESS_LIST=
(LOAD_BALANCE=OFF)
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-vip)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=RAC10g))
)
这里客户端进程首先会尝试连接 RAC1-vip,如果连不上,则会尝试RAC2-vip,再连不上,则会继续往下尝试,直到所有出现在 ADDRESS_LIST 中的 vip 地址全部顺序尝试完为止。这种客户端在连接 Oracle 数据库时的 Failover,不仅适用于 RAC 环境,也适用于 Data Guard 环境。
Oracle RAC 11gR2 引入了 SCAN(Single Client Access Name),并且客户端缺省是通过 SCAN 负载均衡地连接整个 RAC 环境的,如下是 SCAN 的架构图:
如上图所示,如果使用了 DNS 或者 GNS (Grid Naming Service),那么最多可以有 3 个 SCAN VIP 和 3 个 SCAN Listener;如果没有使用 DNS 或者 GNS,而是选择使用 hosts 文件,则只会有 1 个 SCAN VIP 和 1 个 SCAN Listener。
这里假设在 tnsnames.ora 中这样配置:
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))
严格意义上说,只有在 RAC 环境有 1 个以上 SCAN VIP 的时候,上述 FAILOVER=ON 才有意义——它表示的是客户端在连接 SCAN VIP 的时候,如果其中的一个 SCAN VIP 连不上,则马上会尝试另外一个 SCAN VIP。
当使用了 hosts 文件来指定 SCAN VIP 的时候,即在整个 RAC 环境只有 1 个 SCAN VIP 的情况下,Failover 其实也存在,只不过这种情况下 Failover 的速度会慢一些。因为当 SCAN VIP 所在的节点宕掉后,SCAN VIP 会和相关的 SCAN Listener 一起整体 Failover 到其他节点,只不过这个 Failover 需要时间,而客户端需要等待这个 Failover 过程完毕后才能重新连上 RAC。
是指连接已经存在的情况下的 Failover。这个已存在的连接,可能是连接池中正在用的连接,也可能是不通过连接池、直接通过 OCI 客户端(如 sqlplus)连上 Oracle 数据库后的连接。此时Oracle 数据库端出现了异常的情况(比如 Service 宕了、Instance 崩溃了、Session 断了)而导致已有连接中断,怎样 Failover 的问题。
两种实现方式:TAF(Transparent Application Failover)和 FCF(Fast Connection Failover)
首先来介绍 TAF。
1、它可以在 client 端的 tnsnames.ora 中的连接串里定义,也可以在 server 端的 service 中定义,只不过 service 端的设置会取代(override)客户端 tnsnames.ora 中的设置:
客户端可以这样设置 TAF:
(DESCRIPTION =
(FAILOVER=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = Email)
(FAILOVER_MODE= (TYPE=select)(METHOD=basic)(RETRIES=180)(DELAY=5)))
Server 端可以这样设置 TAF:
srvctl modify service -d RAC11g -s Email -q TRUE -P BASIC -e SELECT -z 180 -w 5 -j LONG
具体各个参数的含义可参见如下注释:
2、当 TAF 的TYPE 设置为 select 的时候,单纯 select 操作(不包括 select … for update)可以做到“断点续传”,即单纯的 select 操作在利用 TAF 实现 Failover 后是可以从中断的地方继续往下执行的;
3、TAF 对 DML 操作不能做到“断点续传”,即如果一个 transaction 在使用 TAF 实现 Failover 后,该 transaction 不能从中断的地方继续执行,需要再次从头开始执行;
4、TAF 仅对使用 OCI 连接的客户端和连接池有效,这里的 OCI 连接可以是在 OCI 连接上的封装,比如 JDBC-OCI driver 就支持 TAF,但 JDBC thin driver 就不支持 TAF(因为 JDBC thin driver 不是基于 OCI 的)。
接下来,在介绍 FCF(Fast Connection Failover)之前,我们必须要先介绍 FAN(Fast Application Notification)。
FAN 是 Oracle RAC 里的一种消息主动通知机制。当 RAC 里出现 service down/up,instance down/up,节点负载变化时,Oracle 数据库都能通过 FAN events 将这些信息发布出去,订阅这些 FAN events 的客户端在第一时间收到这些 FAN events 后就能做出相应的动作来响应这些 FAN events。
FAN events 分为两种,第一种是 FAN HA events,第二种是 LBA events,这里的 LBA 是指 Load Balancing Advisory。
当 RAC 里出现 service down/up、instance down/up 时就会触发 FAN HA events。FAN HA events 的示例如下所示:
Event 1: FAN event type: instance
Properties: version=1.0 service=PROD database=PROD instance=PROD1 host=node1 status=down
Event 2: FAN event type: service_member
Properties: version=1.0 service=ERP database=PROD instance=PROD1 host=node1 status=down
Event 3: FAN event type: service_member
Properties: version=1.0 service=ERP database=PROD instance=PROD3 host=node3 status=up
RAC 里节点的负载变化后也会产生 LBA events,LBA events 的示例如下所示:
Event 4: FAN-event type: service_metrics
Properties: version=2.0 service=ERP database=PROD instance=PROD1 percent=70
service_quality=GOOD instance=PROD2 percent=30 service_quality=GOOD
Event 5 :FAN-event type: service_metrics
Properties: version=2.0 service=CRM database=PROD instance=PROD2 percent=30
service_quality=GOOD instance=PROD3 percent=70 service_quality=GOOD
上述 FAN events 可能会通过多种渠道传播出去,这些渠道包括 ONS(Oracle Notification Service),AQ(Advanced Queue),PMON 等。下面是关于 FAN events 架构和传播途径的两张图,它们就直观的说明了 FAN events 的传播途径:
Connect Time Load Balancing 就是指不从连接池中取得已有连接,而是直接连接 Oracle 数据库时的 Load Balance。Connect Time Load Balancing 又细分为两种,分别是客户端的 Connect Time Load Balancing 和 Server 端的 Connect Time Load Balancing。
在 Oracle RAC 11gR2 之前,客户端的 Connect Time Load Balancing 非常容易实现,只需要在相关的 tnsnames.ora 中指定多个 vip,同时指定 LOAD_BALANCE=ON 就好了。如下所示:
(DESCRIPTION=
(ADDRESS_LIST=
(LOAD_BALANCE=ON)
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC1-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC2-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC3-vip)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=RAC4-vip)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=RAC10g))
)
这样客户端在连接的时候,会随机地从上述 4 个 VIP 地址中选一个来连接 Oracle 数据库以达到 Load Balance 的目的。
之前已经提到,Oracle RAC 11gR2 中引入了 SCAN(Single Client Access Name),并且客户端缺省是通过 SCAN 来连接整个 RAC 环境的,如果使用了 DNS 或者 GNS (Grid Naming Service),那么最多可以有 3 个 SCAN VIP 和 3 个 SCAN Listener;如果没有使用 DNS 或者 GNS,而是选择使用 hosts 文件,则只会有 1 个 SCAN VIP 和 1 个 SCAN Listener。
这里假设你在 tnsnames.ora 中这样配置:
(DESCRIPTION =
(LOAD_BALANCE=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))
当使用了 hosts 文件来指定 SCAN VIP 的时候,客户端 Connect Time Load Balancing 实际上是不存在的,因为现在整个 RAC 环境只有 1 个 SCAN VIP。
现在再来介绍一下 Server 端的 Connect Time Load Balancing。Server 端的 Connect Time Load Balancing 相对来说要复杂一些,下面针对 Oracle 数据库不同的版本来分别加以说明。
首先要说明的是:无论是 Oracle RAC 9iR2/10gR2,还是 Oracle RAC 11gR2,它们的 Server 端 Connect Time Load Balancing 都是通过联合使用 local_listener 和 remote_listener 来实现的。
先来介绍 Oracle RAC 9iR2 下的 Server 端 Connect Time Load Balancing:
这里假设是一个 4 节点的 Oracle RAC 9iR2,tnsnames.ora 中的连接串是如下这样:
Oracle 10g 引入了 Service,所以在 Oracle 10g 里,判断负载的依据就跟 Service 绑定在了一起。Oracle RAC 10gR2 里 Server 端 Connect Time Load Balancing 判断负载的依据是由相关 service 的参数 CLB_GOAL 和 GOAL 联合来决定的。
Oracle RAC 10gR2 里的负载可以通过 v$servicemetric 来查看:
SQL> desc v$servicemetric;
Name Type Nullable Default Comments
----------------- ------------ -------- ------- --------
BEGIN_TIME DATE Y
END_TIME DATE Y
INTSIZE_CSEC NUMBER Y
GROUP_ID NUMBER Y
SERVICE_NAME_HASH NUMBER Y
SERVICE_NAME VARCHAR2(64) Y
CTMHASH NUMBER Y
ELAPSEDPERCALL NUMBER Y
CPUPERCALL NUMBER Y
DBTIMEPERCALL NUMBER Y
CALLSPERSEC NUMBER Y
DBTIMEPERSEC NUMBER Y
GOODNESS NUMBER Y
DELTA NUMBER Y
FLAGS NUMBER Y
其中每个 service 在 v$servicemetric 里会对应两条记录,一条记录每5秒采样一次,另外一条记录每 60 秒采样一次。
接下来再看一下 Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing:
Oracle RAC 11gR2 下的 Server 端 Connect Time Load Balancing 和 Oracle RAC 10gR2 下的 Server 端 Connect Time Load Balancing 类似,只不过因为 Oracle RAC 11gR2 里引入了 SCAN,所以 Oracle RAC 11gR2 环境下 remote_listener 应设置为 SCAN:port。
这里假设是一个 4 节点的 Oracle RAC 11gR2 环境,tnsnames.ora 中的连接串是如下这样:
(DESCRIPTION =
(FAILOVER=ON)(LOAD_BALANCE=ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = MySCAN)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME =RAC11g)))
再在各个节点的 tnsnames.ora 中加入如下设置(注意这里监听的是各个节点的 VIP):
LISTENER_RAC1 =
(ADDRESS = (PROTOCOL = TCP)(HOST = RAC1-vip)(PORT = 1521))
LISTENER_RAC2 =
(ADDRESS = (PROTOCOL = TCP)(HOST = RAC2-vip)(PORT = 1521))
LISTENER_RAC3 =
(ADDRESS = (PROTOCOL = TCP)(HOST = RAC3-vip)(PORT = 1521))
LISTENER_RAC4 =
(ADDRESS = (PROTOCOL = TCP)(HOST = RAC4-vip)(PORT = 1521))
然后只需要在初始化参数文件里加入如下设置就能实现 Server 端 Connect Time Load Balancing 了:
RAC1.local_listener=LISTENER_RAC1
RAC2.local_listener=LISTENER_RAC2
RAC3.local_listener=LISTENER_RAC3
RAC4.local_listener=LISTENER_RAC4
*.remote_listener= MySCAN:1521
当做了上述设置后,Oracle 11gR2 RAC 的 Server 端 Connect Time Load Balancing 也就配好了。此时所有的 SCAN Listener 实际上是都知道所有RAC节点的负载情况的。当先经过一层客户端的 Connect Time Load Balancing,比如这里随机的连到了第二个 SCAN VIP 所对应的 SCAN Listener 上后,这时候这个 SCAN Listener 会选择一个实际负载较低的 RAC 节点,然后把连接请求转移(redirect)到这个负载较低的 RAC 节点的 Local Listener 上——这就是 Oracle RAC 11gR2 的 server 端的 Connect Time Load Balancing。
实际上,local_listener 和 remote_listener 支持复杂的连接串的写法。所以,可以在初始化参数里面直接设置 local_listener 和 remote_listener,而不需要在 $ORACLE_HOME/network/admin 下的 tnsnames.ora 中做上述设置。
RAC1:
local_listene=(DESCRIPTION=(ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST= rac1-vip)(PORT=1522))))
remote_listener=nbsdev-scan:1522
RAC2:
local_listene=(DESCRIPTION=(ADDRESS_LIST= (ADDRESS=(PROTOCOL=TCP)(HOST= rac2-vip)(PORT=1522))))
remote_listener=nbsdev-scan:1522
是指从连接池中取得已有连接时的 Connection Load Balancing。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/807718/viewspace-2141585/ ,如需转载,请注明出处,否则将追究法律责任。