RAC应用设计方面需要在底层做很有设计。虽然ORACLE的售前人员总是说RAC的扩展性是透明的,只要把应用分到不同的节点,就可以平滑的扩展系统能力了。而事实上,RAC的CACHE FUSION机制决定db cache,library cache等在RAC环境下都会由于CACHE FUSION而带来额外的开销。

在一个单实例环境中,如果我们要访问某个Cache buffer,我们只需要闩住相关的cache buffer chains,然后去读取这个buffer就行了,而在RAC环境中,首先我们要闩住cache buffer chains,查看该buffer的当前版本是否在这个实例的db cache中,如果没有找到,那么就要发出消息询问其他的节点,是否cache在其他节点中存在,如果存在,那么就要从其他节点通过网络将这个buffer传输过来。

在一个单实例的环境中,db cache的命中率96%和97%可能对系统影响不大,而在RAC环境中,db cache命中率下降一个百分点,对于系统性能造成的总体影响要大上数倍。因此在设计RAC应用的时候,如何减少CACHE FUSION带来的负面影响是十分关键的。在一个RAC环境中,没有任何数据共享是不可能的,或多或少都会有数据共享,因此如何在实例之间共享数据是解决RAC应用性能问题的关键。

在国内的应用设计方面,为了避免CACHE FUSION使用最广的方法是应用隔离,也就是在RAC的不同节点上跑不同的应用,从而最大幅度的减少数据的共享。应用隔离确实是一种很好的RAC应用优化方案,实施起来也比较简单,不需要十分专业的RAC优化技术。不过应用隔离虽然实施难度较小,也被使用比较广泛,但是应用隔离是RAC优化中最为低级的应用层次,在很多情况下,某个应用主要集中在某几张表的访问,这样想要做的应用隔离的难度较大,在这种情况下,需要对应用做更为细致的优化。就像老白处理的这个案例,在两个节点要跑完全相同的应用,这种情况下的优化,就需要从应用底层开始设计了。从总体上来说,减少CACHE FUSION带来的性能影响的方法有一下几个方面。

1、通过表分区来限制某个分区被某个实例使用。对于RAC应用来说,表分区是很好的减少热块争用的手段。首先通过表分区,使数据分散到数个segment中,其高水位推进,数据访问等都被分散了。因此在RAC环境中设计表分区的时候也要注意,表分区逐渐的选择确实能够起到分散数据分布的作用。如果我们有一张日志表,根据日志的日期进行分区,那么虽然我们做了分区,但是还是无法起到分散数据访问的作用,因为我们总是在最新的那个分区里插入和查询数据,其他分区很少会被访问到。

2、增加db cache的命中率。在一般的OLTP系统中,db cache命中率超过90%就不算太低了,如果超过95%那就说明db cache的命中率比较高了。但是在RAC环境中,db cache的命中率越低,CACHE FUSION带来的负面影响就越大,因此在RAC环境下,保持较高的db cache命中率对于系统总体性能大的影响十分巨大。

3、增加共享池的命中率。在RAC环境中,SQL的分析等操作要比单机环境昂贵的多,主要原因是分析等操作涉及大量的全局资源的协同。在RAC环境中减少硬分析、软分析等也有十分重要的意义。因此保持较为充足的共享池资源,使用好的编程习惯,合理使用绑定变量等都有助于提高RAC环境下的系统性能。

4、加大sequence的cache,并使用noorder选项。在RAC中经常会遇到SQ锁等待,这是因为在RAC环境下,sequence也成为全局性的了,不同节点要生成序列号,就会产生对sequence资源的争用。而目前大多数系统中,sequence大多数被作为主键发生器来使用,使用的频率十分高,在RAC环境中,需要设置较大的sequence cache,否则会造成较为严重的争用,从而影响业务。

另外在业务允许的情况下,sequence尽可能使用noorder选项,从而减少sequence产生器的负担。对于十分严重的sequence争用,甚至有用户使用UUID来替代sequence.UUID是一个37位字符串,通过生成机制来确保全局唯一性。这个特点也可以用来作为主键使用。在Oracle中,可以通过select sys_guid() from dual来生成一个UUID,这个UUID是不带“-”的,所以只有32位。

5、使用只读表空间。只读表空间在RAC中时十分有用的,在CACHE FUSION下,如果某个表空间是只读的,那么表空间中数据的访问只需要本地操作就可行了,不需要RAC间协同。实际上,很多数据库中的数据,在某个时间段里都会有大量的只读数据,这些数据如果访问十分频繁,那么在RAC下就会对GES和GCS产生很严重的影响。

实际上,如果我们在设计应用系统的时候就充分考虑了RAC的问题,完全可以把可能只读访问或者在某个时间段内只读访问的数据放在相同的表空间中,这些数据可以根据业务需要设置为读写或者只读。比如,老白曾经给一个客户做过优化,他们系统中的历史数据访问十分频繁,老白建议他们把历史数据存放在单独的表空间中,平时设置为READ ONLY,只有做数据归档的时候才改回READ WRITE。通过这个简单的优化动作,减少了大量的全局访问,改善了RAC的性能。

6、减少大表的全表扫描。全表扫描特别是大表的全表扫描,对db cache的影响十分巨大,由于全表扫描会占用大量的db cache,这样就会把很多DATABLOCK从db cache中挤出去,而且大表的全表扫描会带来大量的物理读,在RAC环境中,物理读的开销远大于单机环境。

7、限制并行查询在实例范围内,不要再RAC实例之间做并行查询。实际上,绝大多数的并行查询并不需要跨实例运行,而Oracle缺省情况下并行查询是跨实例的,所以很多客户都吃过这个苦头,跨实例做并行查询主要是解决单机CPU能力不足的问题,但是跨实例并行查询会引起GCS方面的问题。目前国内用户系统的单机CPU能力一般都比较强,因此使用跨实例并行查询往往得不偿失。Oracle在RAC下的并行查询方面的配置十分灵活,通过设置instance_groups和parallel_instance_group参数就可以实现灵活的策略,通过配置这两个参数,可以轻松实现将并行查询限制在本机上。

8、通过应用隔离,在每个实例上跑不同的应用。RAC每个节点跑不同的应用是目前国内RAC系统中很常用的一种方法,通常被称为应用隔离。应用隔离室RAC应用优化中最为初级的形态,不过也是较为有效的形态。在这种模式下,多个应用共享非关键数据,核心业务数据的关联度较小,通过将不同应用分布在不同的实例上,确保RAC的各个实例间共享的数据较少,访问冲突限制在一个可控的范围内。

9、数据的横向隔离。应用隔离室较为初级的优化形态,虽然有效但是有很多限制,比如某个应用十分庞大,一个单节点无法承担,那样就无法通过应用隔离的方式来优化了。这种情况下,数据的横向隔离就十分有效了。以电信业务为例,其核心业务数据如果能够按照本地网进行分区,那么我们就可以设置部分本地网的应用连接在实例1上,部分本地网应用连接在实例2上。通过表分区来确保核心业务数据之间的冲突降到最小,从而避免由于RAC中数据块争用带来的问题。

最新文章

  1. javascript中值传递与值引用的研究
  2. CodeForce Round#49 untitled (Hdu 5339)
  3. 优秀技能经验及对java学习展望
  4. 关于InputStream.read()方法的阻塞原理的测试
  5. JavaScript Garden2
  6. ListFragment和ListActivity的setOnItemClickListener不起作用
  7. javascript:;”是什么意思
  8. C#获取当前时间详解
  9. Linux 命令练习
  10. Eclipse Maven构建WebApp项目资源目录显示不全的原因与解决方式
  11. Matplotlib画图详解
  12. 201901<<叶武滨时间管理100讲>>
  13. My Web Developer Roadmap
  14. EasyUI datagrid单元格文本超出显示省略号,鼠标移动到单元格显示文本
  15. python scrapy爬取知乎问题和收藏夹下所有答案的内容和图片
  16. HTTPS 之共享秘钥 公钥 及 私钥
  17. shiro 自定义过滤器,拦截过期session的请求,并且以ajax形式返回
  18. iOS - OC - 打印信息 - xcode 中文打印
  19. JS调用webservice的两种方式
  20. Eclipse 的SVN 的分支

热门文章

  1. 小程序UI设计(2)-符合视觉规范-字体规范
  2. cmd完成拷贝文件,并生成两个快捷脚本
  3. oracle删除临时表空间一直处于等待状态
  4. Java中如何判断两个对象是否相等(Java equals and ==)
  5. BZOJ1013 [JSOI2008]球形空间产生器sphere[高消]
  6. Oracle数据库查询优化方案
  7. Confluence 6 插入一个文件到你的页面
  8. TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集
  9. MongoDB下载以及安装
  10. GC详解