Oracle RAC的坑应用分离
RAC最大的坑就是内存融合,也不能说它是坑,只是在使用过程中,或者传统数据库升级到RAC上会带来巨大的性能下降。RAC从8时代的并行技术发展过来的,到了11G正式成熟稳定,一路走来都是解决高可用的问题,达到双机热备,不仅仅是热备而是双活,同时工作,同时对外服务,一个挂了,另外一个接过活来干。
那么要达到几个需求,
1 双活必须共享存储设备,如何解决双活写块的操作;
2 如何知道对方挂了;
3 如何接受被挂掉一方的活过来;
4 如何解决负载均衡问题;
在10G或者9I时代,通过客户端TNSNAME的配置
RAC =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))
(LOAD_BALANCE=YES)
(FAILOVER=ON)
(
CONNECT_DATA=
(SERVER=DEDICATED)
(SERVICE_NAME=RAC)
)
)
启用这种Failover的方法就是在客户端的tnsnames.ora中添加FAILOVER=ON 条目,
这个参数默认就是ON,所以即使不添加这个条目,客户端也会获得这种Failover能力。
这里完成了3和4的需求
而1的需求 在11G以前是写磁盘的,也就是说你要读别人手中的数据块,那发条消息给对方,请他把数据库写回磁盘,然后你从磁盘再读取。
这样就解决写块操作顺序和争用,不过显然是速度慢得可以。后来进一步改善,那如果对方没有对块进行修改过,那就直接通过网络传过来。一般应用系统写少读多,这样显然读操作就可以避免从磁盘读取了。性能也就上了一个档次。到了10G还有11G就考虑解决块修改后,也通过网络传给对方,避免写回磁盘。这就是内存融合技术解决的方法。具体怎么解决,这里不讨论。
第2个需求以前靠第3方软件提供,现在自己写了一套,那就是CRS!
我们回来谈内存融合的坑,因为内存融合把DML的块也通过网络传给对方,外加上负载均衡坑爹的技术。导致两个实例同时对1个数据块发起写的请求。你写一下,然后传给我写一下,然后传回给你再写!假如就是简单的几个块也还过得去,可应用可不那么客气,修改的块可多着呢!做个AWR报表看看一个正常有几年的业务量的系统,高峰期每秒块修改量。不是一般的多。这个量要占用大量的私网的带宽,网络延迟,外加锁等待。你的压力瞬间爆表!
到这里大家应该清楚,这个坑表面上是内存融合技术,实际上是负载均衡惹得祸!
ORACLE 哪里提供了负载均衡的地方,你赶紧关了。
比如 上面的客户端配置 LOAD_BALANCE=YES。
还有11G以来的SCAN IP 也有负载均衡的功能。关于SCAN IP的链接可以看
也就是本地监听通过数据库参数 REMOTE_LISTENER
比如: rac-scan:1521 向SCAN LISTENR 注册。找了下好像没有参数关闭SCAN LISTENR的负载均衡的功能。
那怎么办呢?
1 退回10G的方式 采用VIP+服务名(是同一个服务名)或者是实例名,不记得实例名是否也漂移;
2 VIP+不同的用户名 这个需要应用做好分离;
3 11G方式 SCAN IP+不同的服务名。
第三个方式11G带来的,主要是在服务器端完成负载均衡和FAILOVER。
创建TAFService
./srvctl add service -d orcl -s server_taf -r "orcl1,orcl2" -P BASIC -e session
-d --这里的orcl是database name,
-s 表示服务名
-r 表示主实例 orcl1和orcl2 是instance name。
-a 表示备用实例
1. METHOD: 用户定义何时创建到其实例的连接,有BASIC 和 PRECONNECT 两种可选值。
BASIC: 是指在感知到节点故障时才创建到其他实例的连接。
PRECONNECT: 是在最初建立连接时就同时建立到所有实例的连接,当发生故障时,立刻就可以切换到其他链路上。
两种方法比较: BASIC方式在Failover时会有时间延迟,PRECONNECT方式虽然没有时间延迟,但是建立多个冗余连接会消耗更多资源,两者就是是用时间换资源和用资源换时间的区别。
在服务端使用 -P 指明
2. TYPE: 用于定义发生故障时对完成的SQL 语句如何处理,其中有2种类型:session 和select.
这2种方式对于未提交的事务都会自动回滚,区别在于对select 语句的处理,对于select,用户正在执行的select语句会被转移到新的实例上,在新的节点上继续返回后续结果集,而已经返回的记录集则抛弃。
假设用户正在节点1上执行查询,整个结果集共有100条记录,现在已从节点1上返回10条记录,这时节点1宕机,用户连接被转移到节点2上,如果是session模式,则需要重新执行查询语句;如果是select方式,会从节点2上继续返回剩下的90天记录,而已经从节点1返回的10条记录不会重复返回给用户,对于用户而言,感受不到这种切换。
显然为了实现select 方式,Oracle 必须为每个session保存更多的内容,包括游标,用户上下文等,需要更多的资源也是用资源换时间的方案。
在服务端使用 -e 指明
注意只有一个参数是大写的。
如果-r后面跟两个实例 就会启动负载均衡的功能,到底要不要启动你要做个评估下。如果贵公司有钱,一口气搭建了8个实例。而且私有网络都是万兆光纤网。应用程序也做了微服务化,或者是每个子业务单独部署,或者单独使用不同的JDBC接口。子业务的数据块修改量是网络带宽承受之内,并且子业务的连接量大,并发量大超过单实例的能力,是可以把部分负载过另外个实例上。
1 添加服务操作
srvctl add service -d POSDB -s posc -r 'posdb1' -a 'posdb2' -P basic -e session
srvctl add service -d POSDB -s posweb -r 'posdb2' -a 'posdb1' -P basic -e session
这里添加两个服务,分别是posc和posweb posc使用posdb1作为主实例,posdb2作为备用实例;posweb则相反!
2.启动服务
srvctl start service -d POSDB -s posweb
3.删除服务
[oracle@posdb04 ~]srvctl stop service -d posdb -s posweb
[oracle@posdb04 ~]srvctl disable service -d posdb -s posweb
[oracle@posdb04 ~]srvctl remove service -d posdb -s posweb
4.查看配置
srvctl config service -d posdb -s posweb -a
5 重新定位到首选实例
srvctl relocate service -d posdb -s posweb -i posdb2 -t posdb1
Oracle RAC的坑应用分离 - 墨天轮 (modb.pro)