Abstract
Cache Fusion组件(内容融合技术)是Oracle RAC的基础组件,它实现了多个节点间的共享内容。在传统的基于shared-disk应用中,多节点间通过分布式锁和读写共享的盘来交互信息。Cache Fusion扩展了基于shared-disk架构的信息交互方式,允许不同节点间通过interconnect网络共享数据库内部的buffer。数据直接从一个节点的buffer传递到其他节点,避免了读写共享盘。Cache Fusion提高了基于shared-disk数据库的性能,同时又保留了shared-disk架构(存储计算分离)的优势。
1. Introduction
Oracle RAC名字的由来:Oracle RAC是基于shared-disk架构的分布式数据库,每个db节点可以直接访问disk,动态的扩展节点,任何应用可以不用做任何修改可以直接从传统的master/slave模式迁移到RAC模式。此外RAC通过扩展多个节点可以提高数据库服务的整体性能和可用性。只要有一个节点活着,数据库就是可用的。
在传统的shared-disk数据库中,共享盘是做为data交互的唯一手段。比如:node1读取的页面在node2上是脏页,node1必须等待node2刷脏后,node1才能读取到这个页面的最新内容。
最新硬件的发展(超大规模的SAN存储/Infiniband)给分布式数据库架构提供了新的可能性。
Cache Fusion的核心思想,就是充分发挥新网络硬件的大带宽低延迟,data的共享通过网络而不是共享存储,共享盘的IO代价比网络要高。不同的Oracle实例直接通过网络读取其他节点上页面的最新内容,避免了昂贵的IO。
因此,Orace RAC的架构演变为:shared-disk + shared-buffer。
2. Overview of Real Application Clusters
RAC中每个实例都有自己的redo文件和buffer内存。Global Cache Service(GCS)跟踪维护所有节点的local cache资源,组织成一个大的global cache。GCS同步对global cache的访问:同一时间只允许一个节点修改一个cache resource。
GCS是一个去中心化的分布式结构:每个节点维护global cache的一个子集。这样设计有2个优势:
1. 单点性能瓶颈:global cache资源的维护均摊到了每个节点上;
2. 单点故障:硬件或者软件故障不会影响其他节点,被这个节点维护的资源暂时不可访问(需要recover流程),其他资源仍然能够继续使用(比如上锁成功后可以写入);
全局资源的分配要考虑到这些资源的访问模式,比如:被某个节点高频次访问的资源,可以分配给这个节点来管理。
GCS知道所有页面的分布视图,因此可以把一个读或者写请求转发到一个最合适的节点来处理。比如:一个节点要修改一个block,GCS可以把这个请求直接转发给该页面当前的holder,这个holder再把修改之后的页面最新内容传给发起者,同时GCS标记该block的holder为这次请求的发起者。
3. Cache Fusion
Cache Fusion协议:通过网络来共享节点间的buffer cache。有2中共享模式:
1. Read-Sharing:查询操作时读取其他节点上的buffer;
2. Write-Sharing:更新操作访问其他节点的bufer;
3.1 Cache Fusion Read-Sharing
read-sharing机制是通过Oracle的Consistent Read机制来实现的。Oracle CR是基于多版本的的并发控制协议,使得事务不上任何锁能够读取到一致的数据集。Oracle中的每个事务都对应一个快照时间,也就是SCN,CR机制保证事务能够读取SCN时间点的一致的数据集。
CR的原理:当事务A修改block时,在回滚段存储undo日志。同时事务B读取这个block时,使用这个block的current和undo构造出这个block在事务B的SCN对应版本时的一个clone。clone副本仅仅在内存中不会持久化到盘上。事务B不需要等待事务A提交或者abort就能读取到它所需要的block的一个版本。
在RAC中,节点A读取的block在节点B的buffer cache中时,B读取undo创建一个一致性的CR clone版本,并发送给节点A。这个block的holder仍然是节点B,所以对B没有任何影响。
仅当读取的block不在任何的RAC集群节点中才发起磁盘的IO。
Read-Sharing协议保证一旦一个block被某个节点读取过,后续的读取再不需要从磁盘上读。
3.2 Cache Fusion Write-Sharing
Write-sharing需要GCS的介入。当节点A计划更新一个block时,GCS服务会执行cache-coherency的过程。
GCS发现这个block在节点B的buffer cache中:
1. 通知B需要释放这个block的ownership权利;
2. 节点B在自己的buffer cache中保存这个block的一个副本,以备后续的读使用,同时释放ownership,并发送这个block给节点A;
注意:节点B给节点A发送的block拷贝可以是dirty的,节点B上存储了redo日志,并没有来得及刷脏。允许共享脏页能够大大减少磁盘的读写操作。
仅当block不在任何节点的buffer cache中才发起磁盘读操作。
RAC的write-sharing协议还有一个重要的优势:一个block被写的过程中,拥有 current copy 的节点仍然能够继续读取这个block。因为对于当前这个事务来说,这个block的数据版本足够新了。比如上面例子中:节点B可以继续读取block,因为它有block的一个镜像,即使它已经把ownership交出去了,并且把block发送给了新的ownership。这个行为和传统的shared-disk是相反的:对一个block的写操作会invalid掉所有节点buffer cache的该block的拷贝(防止没有读取最新的版本),同时上锁阻止其他节点的读取,直到写操作完成。
RAC cache fusion的write-sharing和read-sharing机制,能够保证IO数量和单节点实例在相同workload相同总内存时IO相当(很好证明:一旦内存被某个节点读取过了,就不再发起IO操作。有一点不同是:一个block可能在多个节点上同时存储,只是为了加速本地读取的性能);
ownership作用:
1. 谁写谁就是ownership;
2. 只有ownership才会对该block刷脏(刷脏的唯一性,不会出现多个节点对一个block的刷脏);
3. 在write-sharing时,先上排他锁,从其他节点上接管该block的ownership;
3.3 Efficient inter-node messaging
Cache Fusion协议减少了IO,依赖节点间高性能的数据传输。3方面优化性能:
- 节点间低延迟的通信:cache fusion本质上一个大的状态机,使用定长固定格式的消息格式,这样可以高效的生成和解释。同时使用高速硬件来加速网络;
- 管理buffer的节点数是常量,一个buffer关联3个node,不会随着RAC集群的扩大而变多:
- reqiest请求方;
- dire目录管理;
- holder,当前持有者;
- 最小化节点间事件同步频率 ,动态目录迁移机制:高频词访问的页面所属的目录信息移交到local来管理,这样可以减少一次网络访问,甚至没有网络访问开销。
4. RAC support for DSS(OLAP) workloads
RAC的Cache Fusion sharing协议可以为OLTP很好的提供buffer共享。RAC的多节点并行执行也能加速OLAP大范围扫描数据的场景。
RAC的优化器是cost based的,同时能感知集群的状态:
1. 磁盘block和节点的亲和性(哪些节点上缓存了哪些block);
2. 表在存储上的最优并行度;
3. 节点数,cpu数等;
4. local execution vs parallel slaves execution的选择;
5. function shipping机制 vs data sharing机制(实现类似MPP的并行查询,节点间同步function,而不是Cache Fusion机制的同步data,这样能大量的减少数据交互);
在Oracle RAC中:
* OLTP单个查询需要共享的数据量少,通过Cache Fusion Data sharing协议共享不同写节点上最新的buffer。本质上还是一个单机DB的逻辑,只不过原先从shared-disk上读取的数据现在从邻居的buffer中读取,过程中需要处理一致性读;
* OLAP需要扫描大量的数据,通过function shipping机制 计算跟着数据走,减少数据传输。本质上是一个类似MPP的分布式计算架构,RAC是2-DFO局部流水的,不能完全的pipeline,中间结果落盘;
5. Recovery in a RAC environment
RAC集群中只要有一个节点或者,服务就不中断。recovery的时间和失败节点数成正比。
RAC能够加速recovery的关键点:
1. 只replay失败节点的redolog;
2. 在replay过程无需从共享存储上读取block了再应用了,通过data sharing协议从其他活着节点的buffer中读取;
只要扫描一遍redo并记录待恢复的页面集合,其他所有活着节点中的buffer cache组织成的Global Cache Resource就可以继续服务新的查询,RAC集群就可以立即进入可服务状态(遇到要读取待恢复的页面会等待),然后再真正开始redo的恢复。
多个节点并行的恢复,可以并发的读取共享盘,同时恢复过程中,或者的节点以及恢复中的节点中的buffer不断的被读取上来,后续对某个block的恢复也许就可以走Data Sharing协议,不断的减少存储IO,并行恢复会越来越快。
6. Conclusions
Oracle Cache Fusion是构建在shared-disk上的shared-cache机制。使得应用程序无需感知DB的分布式逻辑。核心思想是通过data sharing协议充分发挥网络IO,减少共享盘IO。
read-sharing协议:基于Consistent-Read机制(current page+undo)实现的多版本read-sharing协议允许直接从其他节点读取buffer,而无需节点间维护始终维护缓存一致性;
write-sharing协议:允许直接从其他节点上拉取buffer到本地,然后再更新,其他这个页面当前是脏页。
高效的节点间通信允许RAC支持更大规模的集群。
RAC的Parallel Execution能够时应用层对集群拓扑无感知就可以加速OLAP类的查询。
RAC在recovery时可以从其他节点上读取buffer,进而加速recovery的过程。
Oracle RAC内存相关的论文有3篇,本篇是最新的一篇,讲解RAC的内存融合技术。