日均数百亿入库背后:从“人肉调度”到 K8s 弹性架构,度小满金融基于 OceanBase 重构入库架构实践
作者|潘丹,度小满金融在线存储统一项目负责人 本文所述这套基于 OceaBase 的海量数据入库服务,不仅仅是为了数据迁移,而是根据新存储引擎特点定制的一套高性能、高可用的架构方案。 背景源于我司海量稀疏型存储引擎正在从 Eggroll 迁移到 OceanBase。原架构下,海量数据入库依托 Hadoop 集群的 MapReduce 能力,通过提高离线资源可大幅提升入库吞吐。但迁移到 OceanBase 后,问题来了——OceanBase 原生提供的入库方式是一个本地脚本,没有分布式调度、没有弹性伸缩、没有高可用保障,显然扛不住日均数百亿级别的数据入库需求。 我们面临的核心挑战可以归结为一个问题:如何在 OceanBase 生态中重建一套海量数据入库能力? 答案不是在脚本上缝缝补补。我们选择了自研入库服务——基于 Kubernetes 构建一套具备分布式调度、弹性伸缩、高可用能力的入库引擎,彻底跨越从”能入库”到”高效稳定地入库”的鸿沟。 这里有个关键核心:不只是“换个数据库写入”,而是重建一条入库流水线。 我们迁移的目标不只是“把数据从 A 搬到 B”,还要在新的技术底座上重建入库能力栈,部分架构及核心流程如下图所示。 OceanBase 原生的数据入库 obloader 本质是一个”单机脚本”——输入是本地文件,输出是入库结果。该工具可应对小规模数据场景,一旦面对生产环境中较大数据规模的场景,三个致命短板暴露无遗。 一是远程文件”两段式”搬运。生产环境的数据通常存储在远程对象存储 DGS 上,而原生脚本只认本地文件。这意味着每次入库前必须先将文件下载到本地,再执行脚本导入——多了一次完整的 I/O 搬运。既浪费时间,又占用本地磁盘空间,大批量场景下甚至可能撑爆磁盘。 二是海量文件”各自为战”。当一次入库任务涉及几千个文件时,原生脚本毫无调度能力可言。脚本之间无法协调——谁先跑、谁后跑、并发跑多少、某个失败了怎么办?全靠人工盯着。想提高吞吐就多开几个脚本,想降低压力就手动关闭几个脚本,依赖“人肉调度”。 三是稳定性”裸奔”。纯脚本方式没有进程守护、没有故障恢复、没有重试机制。一旦脚本异常退出,入库任务就中断了,需要人工介入排查和重新执行。在 7×24 小时的生产环境中,这种脆弱性是不可接受的。 我们的策略很明确,不在脚本上缝缝补补,而是把入库能力从”脚本”升级为”服务”。具体从三个维度重构。 远程直读,消灭中转。入库服务直接对接对象存储,支持 DGS 协议远程读取文件,省去”先下载再导入”的中间环节。数据从对象存储到 OceanBase,一步到位。 统筹调度,收放自如。面对几千个文件的批量入库任务,通过平台统一调度——分批提交、并发控制、失败重试,一切自动化。需要加速时调高并发,需要降压时动态限流。吞吐量不再靠”多开脚本”,而是靠策略。 平台多实例,高可用。入库管理平台以多实例方式部署,天然具备高可用能力。单节点故障时自动切换,任务中断后自动恢复。稳定性从”听天由命”变成了工程保障。 下图展现了我们在并行执行多个入库任务时,其中一个任务从“脚本”到“服务”的可视化数据。除了任务完成状态外,还显示了执行耗时、任务配置等。 痛点一解决了平台层的问题,但一个能在生产环境中真正扛住压力的入库服务,远不止任务的平台管理。要达到生产可用的标准,至少还要跨过以下三道门槛。 分布式处理能力:海量数据入库不是单机能扛得住的,必须支持多节点协同并行处理。但分布式不是简单地”多起几个进程”一-任务怎么拆分、怎么分发、节点之间如何协调、进度如何汇总,都需要一套完整的调度机制。 资源弹性能力:入库任务的负载波动很大,日常不是每时每刻都需要执行入库任务,在不需要执行任务时,工作节点可以释放节点以节约资源;在出现紧急需求时需要通过增加并发能力提高入库吞吐。如果资源是静态分配的,要么平时浪费、要么高峰扛不住,“旱涝不均”始终是个问题。 任务高可用能力:在长时间运行的大批量入库过程中,节点故障是必然事件而非偶然事件。一旦某个节点挂掉,正在执行的任务不能就此丢失,必须有自动恢复和断点续行的能力,否则一次故障就可能让数小时的入库工作前功尽弃。 我们设计了一套 Master-Worker 分层架构(如下图所示),将”调度决策”和”任务执行”彻底解耦,再借助 Kubernetes 的平台能力补齐弹性和容错短板。 1.Master-Worker 分层架构。 Master 节点:常驻调度,统揽全局。Master 作为常驻节点,负责任务的拆分、分发和进度追踪。当一批入库任务到达时,Master 将其拆解为细粒度的子任务,按策略分配给各个 Worker 节点。它不干活,只”派活”和”盯活” 。 Worker 节点:按需启动,用完即走。Worker 节点并不常驻,只有在领取到任务后才启动并执行入库操作,处理完毕后释放资源。这种”按需创建、用完销毁”的模式,天然避免了资源空耗。 2.主节点高可用,Active-Standby 双活保障。 Master 节点采用 Active-Standby 模式部署。Active 节点负责实时调度,Standby 节点实时同步状态。一旦 Active 节点故障,Standby 立即接管,整个调度链路不中断。 3.弹性伸缩,Kubernetes 按需分配资源。 借助 Kubernetes 的资源调度能力,Worker 容器可以根据当前任务量动态扩缩。高峰时批量拉起数十个 Worker 并行处理,低谷时自动缩容,让资源跟着负载走,而不是负载迁就资源。 原 Eggroll 集群的入库架构,堪称”教科书级”的分治设计——整个流程被拆成两个阶段: CPU 密集型计算阶段。通过 Hadoop 集群的 MapReduce 分布式生成底层存储引擎格式的文件。这个阶段的瓶颈是 CPU 算力,而 MapReduce 天然支持水平扩展,理论上可以通过堆资源无限提速。 高吞吐写入阶段。将生成好的文件直接拷贝到存储引擎指定的目录。这个阶段不涉及任何计算,写入速度的上限就是磁盘硬件的物理带宽。 两阶段解耦,各自独立优化,因此原架构的入库效率极高。 但迁移到 OceanBase 后,游戏规则变了(见下图)。OceanBase 的旁路写入是一个不可拆分的整体过程——数据的格式转换、编码压缩、SSTable 文件生成、磁盘写入,全部在 OceanBase 引擎内部一气呵成。这意味着 CPU 计算和磁盘 I/O 被绑定在了一起,无法再通过”分阶段各个击破”的方式来分别优化。原来拆成两步能分别调优的事情,现在揉成了一步,性能调优的抓手一下子少了很多。 实测数据印证了这个挑战:原架构下 400 亿条数据入库约 2+小时完成,平均吞吐约 400 万条/秒。迁移后如果不做针对性优化,这个性能基线面临严重下滑的风险。 既然无法像原架构那样分阶段优化,我们转换思路——从并发模型、硬件适配、内核升级三个维度同时发力,把”一体化”流程的整体性能推到极致。 并发模型重构:从”单线程”到”多线程分块”,400 亿数据分布在上千个文件中,原方案是每个文件分配一个进程、且仅用单线程处理。优化后,每个文件仍然独立一个进程,但内部改为多线程分块并行处理。相当于从”一个人从头读到尾”变成”多人分段同时读”,单文件的处理速度大幅提升。 硬件选型重配:让资源比例”对症下药”,原机型的 CPU、内存、磁盘配比并不适合 OceanBase 旁路写入这种”计算+I/O 混合密集型”场景。我们调整为新机型,并针对性地改配 SSD 磁盘,同时提高入库计算所需的 CPU 和内存资源,让硬件配比真正匹配负载特征。 内核升级:释放调度红利,将操作系统内核升级到最新。新内核采用了更先进的任务调度器,能够更高效地分配 CPU 时间片, 在多核高并发场景下显著提升调度效率。这是一次”免费的午餐”——不改业务代码,仅靠内核升级就能吃到底层优化的红利。 三管齐下后,400 亿数据入库时间从 2 小时+压缩至 1 小时+,平均吞吐提升至约 800 万条/秒,峰值可达 1000 万条/秒。性能翻倍,不是靠堆机器,而是靠”把每一层都拧紧” 。 回头看这段从 Eggroll 迁移到 OceanBase 的⼊库服务建设历程,最深的感受是: 迁移从来不只是"换个数据库",⽽是在新的技术底座上重建⼯程能⼒。我们没有简单的加固脚本,⽽是选择了⼀条更难但更正确的路——⼊库服务⼯程化的⽅式解决问题。 从脚本到服务、从单机到分布式、从 Hadoop 到 Kubernetes,每⼀步都是在为系统注⼊确定性。 接下来,我们计划将这套⼊库服务进⼀步标准化和平台化,沉淀为基础设施的⼀部分,同时将业务⽆关的基础框架开源,回馈 OceanBase 社区。前言

破局之路:三个痛难点问题逐一击破
痛点一:原生入库脚本的”单兵作战”困局
解决思路:从“脚本”到“服务”的升级

痛点二:从"能跑"到"能打"——入库服务的生产级架构挑战
解决思路:Master-Worker 架构+Kubernetes 弹性底座


痛点三:架构重构后的"性能断崖"——400 亿数据入库的速度之战

解决思路:三管齐下,“既然拆不开,就整体拉满”

价值与收益

思考与展望