合规风控系统是很多金融企业极其重要的业务系统,这里面既包含了金融监管的要求,也有企业内部管理的要求,而这类系统往往存在着上游系统较多、数据链路复杂、数据不同步等多种问题。本文将会以业务系统运维+DBA的视角,提供一个基于OceanBase改造的方案,旨在降低系统架构的复杂程度,减少ETL以及数据不同步带来的问题。
现有方案
如图所示,合规风控系统是基于Oracle数据库的系统,其中上游数据主要由如下几个部分组成:
- 实时交易数据。保存在上游的多个Oracle数据库中,为了尽可能降低业务时间对系统的负载,不会直接频繁读取,而是从Dataguard同步备库,再从备库同步到一个MySQL中间库。通过合规风控系统的调度任务,每分钟取数一次。实时性要求高,容错率低。主要用于实时的交易监控。
- 盘后交易数据。同样保存在上游的多个Oracle数据库中,每天盘后读取,直接从备库取数,无需中间库同步。与实时交易数据相比,对实时性要求较低,而且容错率较高。主要用于盘后的反洗钱、异常交易、风险控制等多个模块的计算。
- 外部文件。业务需要的数据文件,包含TA文件、估值文件、离线行情文件、黑名单文件、场外基金信息等等。这些既有行情文件这样实时读取的,也有每天定时读取的。特点是格式不统一、实时性要求不一,与其他数据存在着依赖关系。
- 实时行情数据。主要是交易所行情网管提供的流式行情数据,用于盘间的行情计算,在异常交易和风险控制两个模块有应用,其中数据的实时性要求很高。
- 资讯数据。包含了各类股票、基金、债券、市场公告、舆情等数据,通常以定时推送的方式由资讯供应商落盘方式写入到数据库中。这些资讯不仅仅是合规系统用,交易系统、财务都可能用到。
而数据接入都是依赖于应用系统的数据任务,每个具体的调度任务有自己的时间,并且各个调度任务有自己对应的依赖关系,比如反洗钱计算,需要获得最新的黑名单数据,结合客户数据交易数据来计算,风险控制,需要获得财务数据、持仓数据、行情数据共同计算。而到了月度、季度、年度时间节点,要对净资本、客户、交易多类数据做综合计算,生成报送数据上报监管。实际上不仅仅是一个系统,更加是一个特定主题的数仓。
当前方案呈现出如下几个问题:
- 数据库架构繁杂,上游数据中,数据库来源较多,交易柜台、财务系统、中间库、资讯数据等等,不同数据库之间版本管理、高可用、多副本、数据同步等等,关联复杂,维护起来成本较高。
- 存在单点风险,一旦中间库所在的服务器或者实例不可用,将会出现合规系统无法正常获取数据的情况。
- 数据不一致风险,Oracle与MySQL之间的跨平台数据交互,需额外处理兼容性问题,易引发数据一致性风险。
- 资源隔离问题:两个资讯数据库实际上是在同一个MySQL实例中,易出现资源争用,尤其是数据批量写入或采集时。
根据现有方案,我们来做一个替换方案,选用OceanBase分布式版本4.4。
替换方案
作为分布式多租户的数据库,在替换之前,我们要使用到如下的功能:
多租户机制:OceanBase通过租户实现资源隔离,每个租户类似于传统数据库的实例,可以创建自己的用户、数据库、表等所有客体对象,有自己独立的系统数据库和变量。这意味着你可以在一个OceanBase集群内为交易、财务、资讯等不同业务线创建独立租户,实现资源隔离与管理简化。
-
金融级高可用:OceanBase通过多副本(通常至少3个)架构保障高可用,数据以多副本方式存储在集群各个节点,保证RPO=0(恢复点目标),甚至支持异地多活。这对于合规系统至关重要。
-
高度兼容性:OceanBase高度兼容MySQL和Oracle数据库生态,与MySQL业务可无缝切换,并支持Oracle平滑迁移。这降低了从现有Oracle和MySQL迁移而来的复杂性。
-
HTAP混合负载:OceanBase的分布式并行计算引擎对OLTP和OLAP应用都进行了很好优化,支持跨数据库节点的DQL和DML并发执行,一套引擎即可同时支持混合负载。这使得合规系统既能处理交易类业务,也能进行实时分析。
-
多副本:无论是及金融监管还是合规角度,都需要多副本的模式,而OceanBase的多副本以及定向访问模式,可以帮助我们在不干扰业务正常进行的情况下,对只读副本取数。
整个改造方案可以按照如下进行:
- 创建4个Oracle租户,分别为交易系统1、交易系统2、财务系统、合规系统使用。不同的租户之间实现资源与权限的隔离,并且考虑到交易系统和财务系统需要同步数据到合规系统,因此这三个业务系统的租户各自至少2个副本。并且配置定向访问。
- 创建2个MySQL租户,分别为万得资讯、聚源资讯。而这两个MySQL租户没有多副本的需求,可以直接通过访问原表的方式来获取数据。但是多配置一个租户完成高可用,总是好的。
- 不同租户之间的数据获取,可以依赖DBLink与数据库自己的定时任务,也可以依赖应用程序本身的调度任务,考虑到如果改用DBLink与定时任务,会对应用程序造成较多的改动,因此本方案依旧使用内置的调度任务。
- 离线文件OceanBase可以直接读取,同样因为对应用程序的改造比较多,因此保留原有的配置。
那么,整个分布式多租户和Zone的配置如下
| 租户 | 租户类型 | 主副本 | 备副本 | 只读副本 |
|---|---|---|---|---|
| 交易系统1(T1) | Oracle | Zone1 | Zone2 | Zone3 |
| 交易系统2(T2) | Oracle | Zone1 | Zone2 | Zone3 |
| 财务系统(F) | Oracle | Zone1 | Zone2 | Zone3 |
| 合规系统(C) | Oracle | Zone3 | Zone2 | 无 |
| 万得资讯(W) | MySQL | Zone2 | Zone3 | Zone1 |
| 聚源资讯(J) | MySQL | Zone2 | Zone3 | Zone1 |
- 主副本(Leader):部署在租户的 “Primary Zone”(如交易 1 的 Zone1),处理所有写事务和未指定路由的读事务。
- 备用主副本(Follower):部署在 “Standby Zone”(如交易 1 的 Zone2),同步主副本日志,主副本故障时自动升为主副本。
- 只读副本(Read-Only Follower):部署在 “Read Zone”(如交易 1 的 Zone3),仅同步日志供读查询,不参与主备切换,专门供合规系统访问。
- 合规系统自身:仅需部署主 + 备用主副本(2 副本),无需只读副本(无被查询需求),主副本优先放在 Zone3(与业务租户只读副本分离)。
除此之外,我们还需要考虑配置定向访问的内容,确保合规系统访问的都是各自的备用副本,而不是直接访问读写副本。因此还需要使用到OBProxy组件,来实现这个特性。最终总结一下整个系统的架构:

Zone1,交易系统和财务系统的Primary Zone,日常所有的业务入口都在这里。
Zone2,资讯数据同步的Primary Zone,外部推送都写入这个Zone。
Zone3,合规系统的Primary Zone,可以直接读取本Zone内的只读副本。
在每个Zone内部,每个业务系统用不同的OBServer做隔离,确保资源不会出现争用。而考虑到合规系统不需要强读一致性,在Zone3中访问只读副本完全可以匹配业务需求。如果出现Zone1不可用,那么Zone2可以接管Zone1的业务系统,继续提供服务。如果Zone2不可用,那么Zone1可以接管Zone2的资讯数据写入。如果Zone3不可用,那么Zone2接管Zone3的合规系统生产环境,重新调整定向访问,将访问业务系统和资讯数据各自的备副本。
实操步骤
ALTER SYSTEM ADD ZONE zone1 IDC 'BJ1', REGION 'Beijing';
ALTER SYSTEM ADD ZONE zone2 IDC 'SH', REGION 'Shanghai';
ALTER SYSTEM ADD ZONE zone3 IDC 'BJ2', REGION 'Beijing';ALTER SYSTEM START ZONE zone1;ALTER SYSTEM START ZONE zone2;ALTER SYSTEM START ZONE zone3;然后我们查一下状态:
obclient [(none)]> SELECT * FROM oceanbase.DBA_OB_ZONES;
+-------+----------------------------+----------------------------+--------+-----+----------+-----------+
| ZONE | CREATE_TIME | MODIFY_TIME | STATUS | IDC | REGION | TYPE |
+-------+----------------------------+----------------------------+--------+-----+----------+-----------+
| zone1 | 2025-09-13 15:29:19.753281 | 2025-09-13 15:29:19.753281 | ACTIVE | BJ1 | Beijing | ReadWrite |
| zone2 | 2025-09-13 15:29:53.418605 | 2025-09-13 15:29:53.418605 | ACTIVE | SH | Shanghai | ReadWrite |
| zone3 | 2025-09-13 15:30:47.901368 | 2025-09-13 15:30:47.901368 | ACTIVE | BJ2 | Beijing | ReadWrite |
+-------+----------------------------+----------------------------+--------+-----+----------+-----------+添加OBServer
-- 1. 向zone1(192.168.1.0/24网段)添加节点
ALTER SYSTEM ADD SERVER '192.168.1.101:2882' TO ZONE 'zone1'; -- 交易系统1(T1)-zone1节点
ALTER SYSTEM ADD SERVER '192.168.1.102:2882' TO ZONE 'zone1'; -- 交易系统2(T2)-zone1节点
ALTER SYSTEM ADD SERVER '192.168.1.103:2882' TO ZONE 'zone1'; -- 财务系统(F)-zone1节点
ALTER SYSTEM ADD SERVER '192.168.1.104:2882' TO ZONE 'zone1'; -- 万得资讯(W)-zone1节点(只读)
ALTER SYSTEM ADD SERVER '192.168.1.105:2882' TO ZONE 'zone1'; -- 聚源资讯(J)-zone1节点(只读)
-- 2. 向zone2(10.0.2.0/24网段)添加节点
ALTER SYSTEM ADD SERVER '10.0.2.101:2882' TO ZONE 'zone2'; -- 交易系统1(T1)-zone2节点(备用)
ALTER SYSTEM ADD SERVER '10.0.2.102:2882' TO ZONE 'zone2'; -- 交易系统2(T2)-zone2节点(备用)
ALTER SYSTEM ADD SERVER '10.0.2.103:2882' TO ZONE 'zone2'; -- 财务系统(F)-zone2节点(备用)
ALTER SYSTEM ADD SERVER '10.0.2.104:2882' TO ZONE 'zone2'; -- 万得资讯(W)-zone2节点(主)
ALTER SYSTEM ADD SERVER '10.0.2.105:2882' TO ZONE 'zone2'; -- 聚源资讯(J)-zone2节点(主)
ALTER SYSTEM ADD SERVER '10.0.2.106:2882' TO ZONE 'zone2'; -- 合规系统(C)-zone2节点(备用)
-- 3. 向zone3(172.16.3.0/24网段)添加节点
ALTER SYSTEM ADD SERVER '172.16.3.101:2882' TO ZONE 'zone3'; -- 交易系统1(T1)-zone3节点(只读)
ALTER SYSTEM ADD SERVER '172.16.3.102:2882' TO ZONE 'zone3'; -- 交易系统2(T2)-zone3节点(只读)
ALTER SYSTEM ADD SERVER '172.16.3.103:2882' TO ZONE 'zone3'; -- 财务系统(F)-zone3节点(只读)
ALTER SYSTEM ADD SERVER '172.16.3.104:2882' TO ZONE 'zone3'; -- 万得资讯(W)-zone3节点(备用)
ALTER SYSTEM ADD SERVER '172.16.3.105:2882' TO ZONE 'zone3'; -- 聚源资讯(J)-zone3节点(备用)
ALTER SYSTEM ADD SERVER '172.16.3.106:2882' TO ZONE 'zone3'; -- 合规系统(C)-zone3节点(主)确认状态
obclient [(none)]> SELECT SVR_IP, ZONE, STATUS FROM oceanbase.DBA_OB_SERVERS;
+----------------+----------+--------+
| SVR_IP | ZONE | STATUS |
+----------------+----------+--------+
| 192.168.1.101 | zone1 | ACTIVE | -- 交易系统1(T1)-zone1节点
| 192.168.1.102 | zone1 | ACTIVE | -- 交易系统2(T2)-zone1节点
| 192.168.1.103 | zone1 | ACTIVE | -- 财务系统(F)-zone1节点
| 192.168.1.104 | zone1 | ACTIVE | -- 万得资讯(W)-zone1节点
| 192.168.1.105 | zone1 | ACTIVE | -- 聚源资讯(J)-zone1节点
| 10.0.2.101 | zone2 | ACTIVE | -- 交易系统1(T1)-zone2节点
| 10.0.2.102 | zone2 | ACTIVE | -- 交易系统2(T2)-zone2节点
| 10.0.2.103 | zone2 | ACTIVE | -- 财务系统(F)-zone2节点
| 10.0.2.104 | zone2 | ACTIVE | -- 万得资讯(W)-zone2节点
| 10.0.2.105 | zone2 | ACTIVE | -- 聚源资讯(J)-zone2节点
| 10.0.2.106 | zone2 | ACTIVE | -- 合规系统(C)-zone2节点
| 172.16.3.101 | zone3 | ACTIVE | -- 交易系统1(T1)-zone3节点
| 172.16.3.102 | zone3 | ACTIVE | -- 交易系统2(T2)-zone3节点
| 172.16.3.103 | zone3 | ACTIVE | -- 财务系统(F)-zone3节点
| 172.16.3.104 | zone3 | ACTIVE | -- 万得资讯(W)-zone3节点
| 172.16.3.105 | zone3 | ACTIVE | -- 聚源资讯(J)-zone3节点
| 172.16.3.106 | zone3 | ACTIVE | -- 合规系统(C)-zone3节点
+----------------+----------+--------+
2. 创建多租户
在sys租户下,先创建资源组
-- 1. 交易系统1(T1)资源单元(Oracle模式)
CREATE RESOURCE UNIT unit_1
MAX_CPU=24, MIN_CPU=24,
MEMORY_SIZE='64G', LOG_DISK_SIZE='500G';
-- 2. 交易系统2(T2)资源单元(同T1)
CREATE RESOURCE UNIT unit_2
MAX_CPU=16, MIN_CPU=16,
MEMORY_SIZE='32G', LOG_DISK_SIZE='500G';
-- 3. 财务系统(F)资源单元(同T1)
CREATE RESOURCE UNIT unit_3
MAX_CPU=24, MIN_CPU=24,
MEMORY_SIZE='64G', LOG_DISK_SIZE='500G';
-- 4. 合规系统(C)资源单元(仅主/备用,无只读)
CREATE RESOURCE UNIT unit_4
MAX_CPU=16, MIN_CPU=16,
MEMORY_SIZE='32G', LOG_DISK_SIZE='300G';
-- 5. 万得资讯(W)资源单元(MySQL模式)
CREATE RESOURCE UNIT unit_5
MAX_CPU=16, MIN_CPU=16,
MEMORY_SIZE='32G', LOG_DISK_SIZE='400G';
-- 6. 聚源资讯(J)资源单元(同W)
CREATE RESOURCE UNIT unit_6
MAX_CPU=16, MIN_CPU=16,
MEMORY_SIZE='32G', LOG_DISK_SIZE='400G';
创建资源池
-- 1. 交易系统1(T1)资源池
CREATE RESOURCE POOL pool_t1
UNIT='unit1', UNIT_NUM=1,
ZONE_LIST=('zone1', 'zone2', 'zone3');
-- 2. 交易系统2(T2)资源池
CREATE RESOURCE POOL pool_t2
UNIT='unit2', UNIT_NUM=1,
ZONE_LIST=('zone1', 'zone2', 'zone3');
-- 3. 财务系统(F)资源池
CREATE RESOURCE POOL pool_f
UNIT='unit3', UNIT_NUM=1,
ZONE_LIST=('zone1', 'zone2', 'zone3');
-- 4. 合规系统(C)资源池(无只读副本)
CREATE RESOURCE POOL pool_c
UNIT='unit4', UNIT_NUM=1,
ZONE_LIST=('zone3', 'zone2');
-- 5. 万得资讯(W)资源池
CREATE RESOURCE POOL pool_w
UNIT='unit5', UNIT_NUM=1,
ZONE_LIST=('zone2', 'zone3', 'zone1');
-- 6. 聚源资讯(J)资源池
CREATE RESOURCE POOL pool_j
UNIT='unit6', UNIT_NUM=1,
ZONE_LIST=('zone2', 'zone3', 'zone1');
创建租户
-- 1. 交易系统1(t1)- Oracle模式
CREATE TENANT IF NOT EXISTS tenant_t1
LOCALITY = 'F@zone1,F@zone2,R@zone3'
PRIMARY_ZONE = 'zone1'
RESOURCE_POOL_LIST = ('pool_t1')
SET
ob_compatibility_mode = 'oracle',
ob_tcp_invited_nodes = '%';
-- 2. 交易系统2(t2)- Oracle模式
CREATE TENANT IF NOT EXISTS tenant_t2
LOCALITY = 'F@zone1,F@zone2,R@zone3'
PRIMARY_ZONE = 'zone1'
RESOURCE_POOL_LIST = ('pool_t2')
SET
ob_compatibility_mode = 'oracle',
ob_tcp_invited_nodes = '%';
-- 3. 财务系统(f)- Oracle模式
CREATE TENANT IF NOT EXISTS tenant_f
LOCALITY = 'F@zone1,F@zone2,R@zone3'
PRIMARY_ZONE = 'zone1'
RESOURCE_POOL_LIST = ('pool_f')
SET
ob_compatibility_mode = 'oracle',
ob_tcp_invited_nodes = '%';
-- 4. 合规系统(c)- Oracle模式(主副本Zone为zone3)
CREATE TENANT IF NOT EXISTS tenant_c
LOCALITY = 'F@zone3,F@zone2'
PRIMARY_ZONE = 'zone3',
RESOURCE_POOL_LIST = ('pool_c'),
SET
OB_TCP_INVITED_NODES = '%',
ob_compatibility_mode = 'oracle';
-- 5. 万得资讯(w)- MySQL模式(兼容模式改为mysql)
CREATE TENANT IF NOT EXISTS tenant_w
LOCALITY = 'F@zone2,F@zone3,R@zone1'
PRIMARY_ZONE = 'zone2'
RESOURCE_POOL_LIST = ('pool_w')
SET
ob_tcp_invited_nodes = '%';
-- 6. 聚源资讯(j)- MySQL模式
CREATE TENANT IF NOT EXISTS tenant_j
LOCALITY = 'F@zone2,F@zone3,R@zone1'
PRIMARY_ZONE = 'zone2'
RESOURCE_POOL_LIST = ('pool_j')
SET
ob_tcp_invited_nodes = '%';
这样的话,所有资源分配和创建都完成了,还差一个重要步骤,部署OBProxy,并配置强读一致性,在每个租户执行
SET GLOBAL ob_read_consistency='STRONG';这样确保我们应用程序在OB Proxy中的请求都能够分到Primary Zone中,实现定向访问。
案例总结
1. 数据库实例与版本较多,管理难度提高的。
2. 异构数据库数据库可能存在的数据不一致。
3. 解决单点风险,提供高可用多副本,符合监管要求。
4. 多租户不同OBServer解决资源隔离。
而ETL部分,暂时没有动,如果未来OceanBase能够有新的特性,比如跨租户用DBLink创建物化视图刷新,那么ETL部分也可以优化。
当然,这个方案还有几个点可以进一步优化:
1. 合规系统中部分表由行存替换列存,比如月度季度报表的计算。
2. Proxy的配置以及灾备切换,这部分仍然有更多的事情可以做。
3. 离线文件的处理,可以利用OceanBase旁路导入的特性来继续优化。
4. 存储过程的改写。原架构基于Oracle开发了各种存储过程,迁移到OceanBase之后,存储过程要做调整,来做性能优化。
在写这篇文章的时候,还是有一些感慨,早期国产数据库多以 “替代国外产品” 为目标,侧重兼容性;而 OceanBase 这类方案已进入自主创新阶段,例如通过 Primary Zone灵活指定主副本位置、多租户资源精细化管控、分布式事务强一致性等特性,不仅实现了功能上的对等,更在架构设计上超越了传统集中式数据库的局限。这种技术突破印证了国产数据库正在逐步从能用到用得好的质变,也期待越来越多的国产数据库厂商有更多创新和优化。




