技术落地架构、Redis 存储结构设计、数据流向以及 Agent 在其中扮演的 Checklist 自动化检测角色进行深度融合。
以下是关于 模块1(数据库迁移)、模块2(Redis缓存)、模块3(BQ 数据桥接) 的完整技术落地主方案:
🛠️ 数据架构集成总览
在大体量(1T 数据、300张表)的迁移与集成中,三大数据模块并不是孤立的,而是通过 GCP 骨干网络(Cloud Interconnect / VPC) 、数据流水线(Dataflow) 以及 高速缓存(Memorystore) 紧密交织在一起。
[ 线下 On-Premise ] [ Google Cloud Platform (GCP) VPC ]
+-------------------+ +-----------------------------------------------------------+
| | | |
| Oracle 数据库 | =======> | GCP DMS (Database Migration Service) |
| (1T数据/300张表) | (CDC) | - 负责 DDL/Schema/视图/Function 转换 |
| | | - 负责全量 + 实时增量同步 |
+-------------------+ +-----------------------------------------------------------+
|
v
+-------------------+ +-----------------------------------------------------------+
| BigQuery | | Cloud SQL for PostgreSQL (Enterprise Plus) |
| 数据源 | | - 存储主数据 |
| (仅有 Ext_ID) | | - 包含 Int_ID (主键) 与 Ext_ID (唯一索引) |
+-------------------+ +-----------------------------------------------------------+
| |
| (流式读取) | (异步/预加载)
v v
+-------------------------------------------------------------------------------------------+
| GCP Cloud Dataflow Pipeline (Apache Beam 引擎) |
| - 步骤 1: 从 Redis 批量查询 Ext_ID -> 快速置换出 Int_ID |
| - 步骤 2: 组装成包含完整双 ID 的规整记录 |
+-------------------------------------------------------------------------------------------+
| |
| (并发查表/高频读取) | (批量高并发写入)
v v
+-----------------------------------------------------------+-------------------------------+
| GCP Memorystore for Redis Cluster |
| - 充当 260 个微服务的分布式高速缓存 |
| - 预热存储整个系统的 Ext_ID -> Int_ID 映射字典 |
+-----------------------------------------------------------+
模块 1:Oracle \\rightarrow Cloud SQL for PostgreSQL 迁移落地
1. 技术选型与拓扑
-
目标: 300 张表、1T 数据、10 视图、数个 Function。
-
计算存储选型:
Cloud SQL for PostgreSQL Enterprise Plus(推荐 16+ vCPU,128GB RAM,启用 SSD 自动扩容与高级高可用 HA 跨可用区部署)。 -
迁移工具:
GCP Database Migration Service (DMS)结合Conversion Workspace。
2. 转换与同步策略
-
Schema 与对象转换: Agent 调用 DMS 接口,利用内置的 Gemini SQL 翻译引擎,将 Oracle 特有的存储过程和 Function(PL/SQL)自动转译为 Postgres 的
PL/pgSQL。将 10 个视图中的 Oracle 特异性语法(如DECODE、NVL、(+)外连接)重写为标准的 ANSI SQL(CASE WHEN、COALESCE、LEFT JOIN)。 -
数据抽取: 开启 DMS 的全量复制(Initial Load),随后自动无缝切入 CDC(基于 Oracle LogMiner 的增量数据抓取)。
3. Agent 自动化 Checklist 门禁(模块 1)
-
Schema 一致性校验: Agent 抽取两端元数据,运行表结构
MD5比对,确认 300 张表的主外键、索引、字段长度 100% 映射成功。 -
数据量对账(Volume Audit): Agent 定时触发行数和关键字段
SUM校验,确保全量阶段 1T 数据无丢失。 -
CDC 延迟达标门禁: 进入割接前,Agent 监控 GCP Monitoring 指标,要求 DMS 复制延迟(Replication Lag) \\le 1000 \\text{ ms} 且连续保持 15 分钟以上。
模块 2:GCP Memorystore for Redis 集成与表设计
为了承载 260 个微服务(特别是老旧 Jetty 集群和高并发 Spring Cloud)的吞吐压力,必须设计严密的 Redis 键值矩阵。
1. 高可用选型
- 选型:
GCP Memorystore for Redis Cluster(启用多专区复制,分片数根据 QPS 预估,初始建议 3-5 个分片)。
2. Redis 核心表结构/Key 规范设计
A. 基础行数据缓存(String 结构)
-
应用场景: 高频单表、单条记录查询(满足 Cache-Aside 旁路缓存模式)。
-
Key 设计:
app:table:pk:[Internal_ID](例如:crm:user:pk:1001239) -
Value 存储: 经过 GZIP 压缩的 JSON 字符串。
-
TTL(生存时间): 默认
86400(24小时),带 \\pm 10\\% 随机扰动以防止缓存雪崩。
B. 外部 ID 映射桥接字典(Hash 结构)
-
应用场景: 专门用于模块 3(BigQuery 数据替换)以及根据外部 ID 登录/查询的微服务。
-
Key 设计:
global:id_map:ext_to_int -
Sub-Field(字段):
[External_ID](如某个 UUID:ex_8f9a2b3c...) -
Value(值):
[Internal_ID](如自增数字:1001239) -
TTL: 永久生效(或设置为长期过期),由 Agent 监听 Postgres 的 WAL 日志进行实时增量更新。
C. 老旧 Jetty 集群 Session 共享与分布式锁(ZSet / String 结构)
-
应用场景: Jetty 巨石应用的水平扩展、互斥写操作流限流。
-
Key 设计:
jetty:session:[Session_ID](String,过期时间 30 分钟) -
分布式锁 Key:
lock:table:[Table_Name]:pk:[Internal_ID](String,使用SET NX PX命令确保原子性)。
3. Agent 自动化 Checklist 门禁(模块 2)
-
容量与淘汰策略审计: Agent 检查 Redis 的
maxmemory-policy,必须配置为volatile-lru或allkeys-lru,防止内存溢出(OOM)。 -
缓存预热率校验: 在应用割接前,Agent 启动脚本批量读取 Postgres,将高频热数据及双 ID 映射字典全量加载至 Redis,要求核心映射表预热率 = 100\\%。
-
穿透防御检测: 验证应用代码中是否包含对不存在的 ID 缓存空值(Null Value)的逻辑,严防缓存穿透。
模块 3:BigQuery 与 Postgres 数据无缝替换(ID 桥接)
1. 痛点场景
BigQuery 中存放着由第三方或海外系统同步过来的海量业务数据,该数据只有外部 ID(Ext_ID) 。而 PostgreSQL 内部表为了保证关联性能,使用的是内部专用 ID(Int_ID,主键) 。在将 BQ 数据批量注入/替换入 Postgres 时,必须实时高效地完成 Ext_ID $\rightarrow$ Int_ID 的转换。
2. Dataflow 管道级集成设计(桥接工作流)
[ BigQuery 每日增量表 ]
|
| (通过 GCP 内部网络流式/微批拉取:Extract)
v
[ GCP Cloud Dataflow Pipeline (Apache Beam 引擎) ]
|
+---> 核心转换算子:ID_Bridge_Transform
|
|--> 1. 算子并行发出 HGET 命令,批量请求:
| GCP Memorystore for Redis (global:id_map:ext_to_int)
|
|--> 2. 成功匹配到对应 Internal_ID
| (若 Redis 未命中,触发 Side-Input 从 Postgres 补查)
|
|--> 3. 动态重组内存对象,注入 Internal_ID 作为主键字段
v
[ PostgreSQL 批量更新算子 (Bulk Upsert Writer) ]
|
+---> 执行 INSERT INTO ... ON CONFLICT (internal_id) DO UPDATE ...
-
触发阶段: 每天定时或由消息(Pub/Sub)触发,GCP Cloud Dataflow 启动并读取 BigQuery 的增量/全量目标数据集。
-
内存高并发置换(Transform): Dataflow 管道内部部署并行计算算子。算子拿到 BQ 数据的
Ext_ID后,直接向同一 VPC 内的 GCP Memorystore for Redis 发起集群高并发HGET请求。- 注:由于 Redis 的吞吐可达数十万 QPS,数据置换可在毫秒级完成,完美解决了直接去查 Postgres 导致主库索引崩溃的问题。
-
降级兜底: 若某些极新数据的
Ext_ID在 Redis 中未命中,Dataflow 触发旁路缓存机制(Side-Input),小规模、低频次地去 Postgres 中检索新生成的Int_ID并同步回填到 Redis。 -
批量写入(Load): 组装好同时包含
Int_ID和Ext_ID的完整数据后,Dataflow 调用 PostgreSQL 连接池,执行批量Upsert语句(ON CONFLICT (internal_id) DO UPDATE),无缝替换目标数据。
3. Agent 自动化 Checklist 门禁(模块 3)
-
Dataflow 背压与吞吐监测: Agent 监控 Dataflow 的 System Lag 和 Wall Time,要求在置换过程中处理速度 \\ge 15,000 \\text{ 条/秒},单条记录转换延迟 \\le 10 \\text{ ms}。
-
脏数据/孤儿数据(Orphan Data)流捕获: Agent 强制要求 Dataflow 配置 Dead Letter Queue(死信队列,基于 GCP Pub/Sub) 。任何通过
Ext_ID在 Redis 和 Postgres 均找不到对应Int_ID的错数,自动流入死信队列,不得中断主管道。 -
最终数据对账(End-to-End Reconciliation): 替换完成后,Agent 触发抽样脚本,对比 BigQuery 的原始行数、Postgres 更新后的影响行数,要求对账通过率 = 100\\%。
接下来,我们将基于上述三大核心数据模块的设计,进一步推演应用层(260个微服务)的具体改造细节、分布式环境下的事务隔离方案、以及项目整体的灰度切换路线图。
四、 应用层架构改造:Spring Cloud 与 Jetty 的解耦与适配
260个应用跨越了现代的 Spring Cloud 体系和老旧的 Jetty 巨石架构,Agent 将采用不同的重构策略。
1. Spring Cloud 微服务集群改造
对于现代化的微服务,改造重心在于数据源切换的平滑性 以及 Cache-Aside 模式的标准化。
-
双数据源动态路由器(AbstractRoutingDataSource):
Agent 会在代码层注入一个动态数据源路由器。通过配置中心(如 Nacos 或 GCP Runtime Configurator)的开关,动态切换
dataSourceKey。- 读写分离配置: 在灰度读流量阶段,路由器将
@Transactional(readOnly = true)的方法执行指向 Cloud SQL (Postgres),而写操作依然指向 Oracle。
- 读写分离配置: 在灰度读流量阶段,路由器将
-
Redis 缓存切面(AOP Bean):
使用
spring-boot-starter-data-redis,构建统一的拦截切面。标准的数据读取逻辑被固化为:\\text{查询请求} \\rightarrow \\text{Redis String (app:table:pk)} \\rightarrow \\text{Miss} \\rightarrow \\text{Cloud SQL} \\rightarrow \\text{回写 Redis}
2. 老旧 Jetty 巨石应用改造
Jetty 应用大多缺乏动态配置刷新能力,且多使用硬编码的 SQL 或老旧的连接池(如 C3P0)。
-
连接池置换: Agent 将强制将 C3P0 替换为 HikariCP ,并引入 GCP Cloud SQL Auth Proxy 作为 Sidecar 部署。Jetty 只需要连接本地的
127.0.0.1:5432,安全认证和连接复用由 Proxy 托管。 -
SQL 语法兼容层: 针对 Jetty 中硬编码的 Oracle 特异性语法(如
rownum <= 10或select seq.nextval from dual),Agent 将利用 AST(抽象语法树)重写为 Postgres 兼容的LIMIT 10和nextval('seq')。
五、 过渡期分布式事务与双写隔离方案
在跨度长达 2.5 个月的迁移周期内,必然会出现"部分应用已切到 Postgres,部分应用仍在写 Oracle"的交织状态。为了防止数据回环冲突和脏读,必须设计严格的隔离机制。
1. 基于分布式锁的"并发红线"控制
当 Tier 3(高频写)应用进行割接时,两端数据库都在发生变更。
-
锁定策略: 无论哪个集群发起写操作,必须先在 GCP Memorystore for Redis 中通过
SET lock:table:[Name]:pk:[ID] NX PX 3000锁定该业务主体的 ID。 -
DMS 动态避让: 当 Agent 检测到某个 ID 正在被新集群写入时,会通过 API 向 GCP DMS 发送临时过滤指令,防止老库同步过来的旧数据覆盖新库的最新记录。
2. 最终一致性异步补偿
对于无法同步进行强一致性锁定的跨库事务,引入 GCP Pub/Sub 消息队列。
- 新集群写成功后,异步投递一条消息到队列,由专门的 Dataflow 或者是对账服务去核对 Oracle 和 Postgres 的两端状态,发现差异立即报警并触发 Agent 预设的自动修复脚本。
六、 整体割接演练与上线路线图(Timeline & Checklist)
根据前期的工期评估,整个割接上线窗口将压缩在 1 周内完成,实行"三阶段演练、分批次断后"的策略。
[第 1-2 天: 全链路影子演练] ---> [第 3-5 天: 灰度切流与 BQ 桥接启动] ---> [第 6-7 天: 断开 DMS 与全面解耦]
1. 割接前夜(D-Day - 1):全链路大考
-
数据静止测试: 模拟停机,检查 1T 数据在静止状态下 DMS 的追平速度。
-
反向链路联通性: 验证
PostgreSQL $\rightarrow$ Oracle的反向数据同步链路是否完好,确保一旦发生性能雪崩,可在 10 秒内安全回滚。
2. 割接正日(D-Day):流量倒换
-
凌晨 02:00: 触发 Gate 0 和 Gate 1,Agent 确认全量对账 100% 正确,DMS 延迟小于 1 秒。
-
凌晨 02:30: 接入 10% 读流量(触发 Gate 2),密切观察 Redis 缓存集群的 CPU 步进曲线。
-
凌晨 03:00: 接入 5% 写流量(触发 Gate 3),Dataflow 开始流式置换 BigQuery 中的外部 ID,检查有无死信数据流入 Pub/Sub。
-
凌晨 04:30: 人类总指挥下发指令,全面关闭 Oracle 写权限,DMS 位点对齐后彻底断开同步。API 网关切换 100% 流量至新集群(触发 Gate 4)。
3. 割接后观察期(D-Day + 3)
-
保持应用在 GCP 全栈运行 72 小时。Agent 持续监控 Cloud SQL 的慢查询日志(Slow Logs)和 Redis 的内存置换率(Evictions)。
-
观察期结束后,正式宣告原 IDC 的 Oracle 数据库下线,资产释放。
七、 总结:此方案为企业带来的核心价值
-
风险极低: 引入了基于 Redis 的分布式隔离与反向回滚链路,放弃了传统的"一刀切"高风险割接。
-
高度自动化: 260个应用的重构与 Checklist 指标检测由具有记忆演进能力的 Agent 主导,将原定 6-9 个月的人工工期缩短至 2.5 个月。
-
架构现代化: 成功将底层基础设施平滑过渡到 GCP 的 Cloud SQL、Memorystore 和 Dataflow 生态,彻底摆脱了老旧巨石架构的性能瓶颈。