在Oracle RAC集群结合ASM(Automatic Storage Management)的架构里,当存储跨多个站点分布时,每个实例读取数据默认可能访问任意故障组中的镜像副本。如果业务节点与数据副本不在同一物理位置,网络往返会显著增加IO延迟。ASM的preferred read机制就是为解决这类问题而设计的,它让特定实例优先从指定的故障组读取数据,从而减少跨站点访问。

preferred read的底层原理与故障组关系
ASM将磁盘划分为多个故障组(failure group),正常冗余或高冗余模式下,数据的每个Extent会在不同故障组存放副本。在没有preferred read时,实例读取某个Extent可能随机选择任一可用副本,这由ASM的读取算法和缓存情况决定。当配置了preferred read后,实例在初始化阶段通过初始化参数asm_preferred_read_failure_groups绑定一个或多个故障组,之后在读取Extent的元数据中若发现本地偏好故障组含有该Extent副本,就会优先发起本地读请求。
这种机制并不会改变数据写入路径,写操作依然同步到所有故障组以保证冗余,仅影响读路径。从内部看,ASM实例会将偏好故障组信息广播给数据库实例,数据库层的直接路径读(direct path read)在构造IO调用时会参考该映射。需要注意的是,preferred read只适用于ASM磁盘组,并且要求磁盘组属性compatible.asm达到11.2及以上版本,否则参数无法生效。
如果故障组划分不合理,例如将所有磁盘放在同一个交换机下却划分为不同故障组,或者偏好故障组在远程站点,那么preferred read不仅无法提速,反而会因偏好失效造成额外判断开销。因此在规划RAC扩展或容灾架构时,必须让故障组与物理位置、存储控制器对应,才能让本地读真正落在近侧存储上。
参数配置与视图验证的具体操作
配置preferred read最直接的方式是在数据库实例的初始化参数文件中设置asm_preferred_read_failure_groups,格式为磁盘组名.故障组名,多个值用逗号分隔。例如磁盘组名为DATA,本地节点对应故障组FG_SITE1,则写入asm_preferred_read_failure_groups='DATA.FG_SITE1'。每个实例可以设置不同的故障组以匹配各自站点,这也是扩展集群(Extended RAC)的常见做法。
修改后需要重启或动态修改该参数(若使用了scope=both且参数支持动态),随后可通过视图gv$asm_preferred_read_failure_groups确认设置是否生效。该视图会列出每个实例偏好的故障组及状态。同时可查询gv$asm_disk中preferred_read列,看具体磁盘是否被标记为偏好读。下面是一段检查配置的SQL示例:
SELECT inst_id,
disk_group_name,
failure_group_name,
preferred_read
FROM gv$asm_preferred_read_failure_groups
WHERE disk_group_name = 'DATA'
ORDER BY inst_id;
除了静态参数,还可以在磁盘组层面用ALTER DISKGROUP调整某些属性,但偏好故障组主要依赖实例参数。运维中建议将参数纳入集群管理工具的统一配置,避免节点重启后丢失。验证时若发现某实例preferred_read列为NO,应检查故障组名拼写、磁盘组兼容性以及ASM实例与数据库实例的连通性。
性能收益对比与常见误区
在双站点RAC测试中,关闭preferred read时,站点A的实例读取站点B存放的Extent需经过光纤或IP网络,单次读延迟可能在数毫秒;开启后本地读延迟通常降至亚毫秒级。对于OLTP系统大量小IO场景,整体DB文件顺序读等待事件显著下降,AWR报告中远程IO占比减少。以下模拟一个简单的性能统计对比:
| 配置状态 | 平均读延迟(ms) | 跨站点流量(MB/s) |
|---|---|---|
| 关闭preferred read | 3.2 | 180 |
| 开启preferred read | 0.4 | 25 |
常见误区之一是认为preferred read能替代存储双活或数据近距离部署。实际上它只是读路径优化,写仍同步远程,若远程链路断掉,冗余副本写入失败会导致磁盘组脱离。另一误区是给所有实例配相同故障组,这在扩展集群中会让部分节点读远程,失去意义。正确做法应基于节点物理位置一对一映射故障组。
还有人误以为视图v$asm_attribute里能直接看到偏好读效果,其实该视图多展示磁盘组属性,实例级偏好必须通过前面提到的gv$asm_preferred_read_failure_groups确认。遇到性能未提升时,优先核对故障组与机架、存储阵列的对应关系,而不是盲目调大内存或并行度。
结合实践给出部署建议
在规划阶段,应将每个站点的存储划分为独立故障组,命名上体现地理位置,如FG_BJ、FG_SH。部署RAC时,北京节点设置asm_preferred_read_failure_groups='DATA.FG_BJ',上海节点对应FG_SH。这样即使磁盘组跨城,日常读也能本地化。如下为参数文件片段示例:
# 节点1初始化参数 asm_preferred_read_failure_groups='DATA.FG_BJ' # 节点2初始化参数 asm_preferred_read_failure_groups='DATA.FG_SH'
上线后利用AWR和gv$asm_preferred_read_failure_groups做周期巡检,观察偏好读命中率。若发现命中率低,可能是磁盘组重平衡后Extent分布偏移,可手动触发局部重平衡或检查rebalance power。对于读多写少的分析业务,preferred read带来的收益比核心交易系统更明显,因为交易系统写同步无法避免,但报表查询几乎全是读。
最后提醒,在滚动升级或节点临时接管时,若某站点实例起到对端,需确认其偏好参数是否随角色切换更新,否则会出现反向读。可借助集群软件的事件脚本在切换后重设参数,保障preferred read始终贴合实际拓扑。只有这样,ASM磁盘组的preferred read才能长期稳定地支撑RAC集群的跨站点高效运行。
Oracle_RACASMpreferred_read修改时间:2026-08-14 07:39:32