海山数据库库内训推架构设计:三层架构与五项核心能力
摘要:HE3ML 是海山数据库的库内训推扩展,目标是让 ML 训练与推理在生产数据库内安全运行、与 TP 业务混合部署:支持增量快照降低存储成本,支持批量推理提升吞吐,保障小规格、大数据量、高并发场景下训推服务的稳定性。本文介绍其设计动机、五项核心能力与三层架构。
一、背景:库内训推面临的技术问题
库内 ML 的基本价值是数据不出库:一条 SQL 完成训练和推理,消除数据搬运、权限出域和独立 ML 平台的运维成本。但传统库内 ML 方案(在数据库进程内直接读堆表、全量物化到内存)在生产环境的大数据量、小规格、高并发场景下,存在五类系统性问题:
1. 内存占用与数据集大小强耦合。 传统方案通过内部接口把堆表全量读入内存:结果集物化一份、转换为 Vec<f32> 再拷贝一至两份、预处理再膨胀一轮,内存峰值约为全量数据的 3 倍。以 1000 万行 × 100 特征的训练表(编码后约 4.8GB)为例,训练内存峰值约 16–20GB;数据量达到 100GB 时,物理内存不足即触发 OOM。
2. 训练与在线业务争抢资源。 全表扫描的磁盘 I/O 与 TP 查询直接竞争:训练期间磁盘读 IOPS 从 100–500 升至 3000–15000,TP 查询 P99 延迟从不到 2ms 恶化到 5–30ms,Backend 进程内存从不足 100MB 涨到 10–30GB。
3. 训练任务阻塞连接。 同步执行的训练任务动辄几十分钟,期间持续占用用户连接与锁。
4. 模型与快照占用数据库存储,成本失控。 模型权重(数百 MB)存入库内,备份窗口被迫覆盖权重数据;每次实验全量复制一份数据,10 个快照即 10 倍存储。
5. 训练数据不可复现、训推口径漂移。 源表持续变更,模型训练时使用的数据无法回溯;训练时的归一化、编码逻辑需要在推理侧手工复刻,口径偏差直接影响结果正确性。
HE3ML 的设计目标即逐条解决上述五类问题。
二、设计目标与核心能力
HE3ML 以海山数据库扩展形态交付,纯扩展、零外部服务依赖。设计原则为:训推分离、模型外置、过程可观测,以及"薄 API 铁律"——海山数据库 Backend 只做极薄透传层(参数校验 → 信封构建 → IPC 提交 → 等待响应),零数据处理,全部 ML/LLM 计算下沉到独立 Worker 进程。
在该原则之上落地了五项核心能力。
2.1 小规格资源、大数据量训练不 OOM
目标:100GB 训练集、2GB 内存预算下训练不 OOM。
实现方式是将"全量视图"与"物理占用"解耦:训练数据先物化为裸 f32 矩阵文件(features.bin / labels.bin),训练时通过 mmap 映射到进程虚拟地址空间,算法以胖指针(ArrayView2<f32>)直接指向映射区读取,由 OS 内核按需换页、LRU 淘汰冷页。内存峰值受 Page Cache 约束而不是数据集大小——程序最多变慢,不会崩溃。配合流式导出(COPY 协议,内存峰值与表行数无关),小规格机器运行大数据量训练成为常态路径。
同样 1000 万行 × 100 特征的数据,内存峰值从传统方案的 16–20GB 降到 2GB 预算以内,其中数据加载部分只占约 128MB。
2.2 列存 + 压缩 + 增量快照,降低快照成本
训练数据从海山数据库堆表解耦到 Parquet 列存(Zstd level 3,压缩比 5–10×)。快照基于 Iceberg 表格式实现文件级增量:每次变更是"写一批新的不可变文件 + 发布一个新快照",追加成本与增量大小成正比、与表总大小无关——十亿行的表插入一行,也只多写几个小文件。增量快照仅消费自上次快照以来的 WAL 变更,I/O 量典型为全量导出的 1–5%。
效果:10 个实验快照的存储从"10 份全量复制"降为"1 份全量 + 9 份增量",存储成本约降低 9 倍。
2.3 模型与快照数据外置第三方存储
模型权重经 OpenDAL 统一存储抽象存到外部存储——local / nas / s3 / gcs / azureblob 同一套契约,海山数据库内只保留元数据(路径、SHA256、大小、格式)。元数据为 KB 级、权重为数百 MB 级:备份窗口只覆盖元数据(约 1MB / 100 个模型),不备份模型权重;多个海山数据库实例可共享同一模型存储。S3 凭证以 env:NAME / vault:path 引用持有、运行时解析,明文不落库、不进日志。
2.4 引入 DataFusion 向量化引擎提升预处理能力
列级统计和特征预处理统一采用 Apache DataFusion 向量化执行引擎:对 Parquet 列存直接计算 count/distinct/min/max/分位数等统计,利用向量化执行和 Parquet 内建 min/max/null_count 元数据跳块,较数据库堆表行式扫描快一个数量级(100 万行 × 50 列:2.5s → 0.15s,约 17 倍)。
另一关键设计是"一次特征化、多次训练":预处理参数(fitted)随快照一次拟合、持久化复用。1000 万行 × 100 特征、XGBoost 超参搜索 100 轮的场景,预处理耗时从 100 次 × 15s = 1500s 降为 1 次 × 15s + 加载时间 ≈ 65s——仅预处理部分即提升约 23 倍。fitted 同时是推理侧的特征变换事实源,训练/推理口径天然一致。
2.5 无锁化设计 + 合并同类请求,提升推理吞吐
同步推理的 IPC 走海山数据库共享内存(SHM):单次投递延迟约 500ns,通道级吞吐约 5M req/s,IPC 开销占整体推理延迟不到 0.01%。SHM 内部全链路 CAS 无锁——512 个 128B 缓存行对齐槽位、128 个按模型哈希的路由桶、双缓冲 Arena,无任何互斥锁。
在此之上进行批量合并:InferWorker 将同模型的推理请求在 200μs 合并窗口内攒成一批,一次 predict_batch 代替 N 次单条推理。树模型场景吞吐提升 5–10×(实测约 8×),Embedding 合并提升 10–50×。以 XGBoost 为例:单条 120μs/req,批量后均摊 15μs/req。
三、总体架构
HE3ML 采用三层水平分层 + 通信层纵向贯穿的架构:API 接入层 → Worker 执行层 → 引擎与基础设施层;通信层(SHM 统一 IPC 入口 + 数据库表队列)作为跨层基础设施连接各层。职责单向依赖,下层不感知上层。

3.1 第 1 层:API 接入层(海山数据库 Backend 进程内)
对外唯一入口,以 he3ml.* schema 暴露 36 个 SQL 函数(含重载共 45 个入口):项目管理、任务定义、快照与预处理、train、predict 族、evaluate、deploy、chat/embed/rerank、统计与可观测性。
这一层恪守薄 API 铁律,只做四件事:
- 参数校验与目录表读写:项目/任务/部署是否存在、权限检查;
- TraceInjector:在请求入口创建 W3C TraceContext 根 span,嵌入信封跨进程传播——TP 进程是唯一能确定"这是一次新用户请求"的位置;
- RequestEnvelope 构建:将 SQL 参数打包成统一信封(request_id、request_type、payload、reply_to、Trace 上下文);
- IPC 提交与等待:写 SHM 槽位 → eventfd 唤醒 Worker → 自旋等待结果(自旋预算 5000μs,耗尽转
sched_yield(),总超时 30s)。
特征工程、模型加载、算法执行、结果后处理全部不在这一层。
3.2 通信层:跨层基础设施
核心是双通道 IPC:
- 同步请求(推理/LLM)→ SHM:单一
InferenceShm区域,定长 256MB,内含七区域布局(512 槽位池、128 模型桶、类型队列、空闲槽位栈、Request/Response 双 64MB Arena、心跳与元数据区)。延迟敏感,全链路 CAS 无锁。 - 异步训练 → 数据库表队列:
he3ml.runs表是训练任务的唯一权威源(事务 + WAL 保证,重启/主备切换不丢任务),eventfd 仅作轻量唤醒信号。
通道划分原则:任何状态只有单一权威源,全模块无跨介质双写。同步推理走 SHM(延迟敏感),异步任务走数据库表(持久性优先)。
3.3 第 2 层:Worker 执行层(4 个后台工作进程,各 1 进程)
所有 ML/LLM 计算的执行主体,注册为数据库后台工作进程,随数据库主进程拉起、崩溃自动重启。每类 Worker 仅 1 个进程,并发度由进程内 tokio 协程池控制(GUC 可调,reload 生效)——单进程意味着模型缓存全实例一份、无路由复杂度,也是无锁设计的结构基础。
| Worker | 消费通道 | 职责 |
|---|---|---|
| InferWorker | SHM 模型桶就绪链 | 限流 → LRU 模型缓存 → BatchMerger 批量合并推理 → 结果写回槽位 |
| TrainWorker | he3ml.runs 表队列 |
FOR UPDATE SKIP LOCKED 原子领取 → 流式加载 → 训练 → 模型保存 |
| LLMWorker | SHM 三条类型队列 | Embed 合批(10–50×)/ Rerank / Chat,按注册配置路由远程或本地 Provider |
| CDCWorker | 快照请求表 + 逻辑复制流 | WAL 增量捕获、Iceberg commit、快照物化 |
每个 Worker 内置公共 RateLimiter(准入控制 + 令牌桶两层限流),确保训推负载不冲击 TP 服务。四类 Worker 在 SHM 心跳表各占固定下标,周期写时间戳;Backend 提交前预检,超过 15 秒未更新判死并拒绝提交——快速失败,不排队等死。
3.4 第 3 层:引擎与基础设施层
- ML 引擎子层:单实现统一引擎,覆盖 45 个算法规范名;运行时分派两路——Rust 绑定(linfa/xgboost/lightgbm,进程内执行)和嵌入式 PyO3(sklearn 族,进程内嵌入 CPython,无子进程桥)。训练与推理共用同一引擎封装,保证训推同源。
- LLM 引擎子层:
RemoteLlmEngine(HTTP 转发 OpenAI 兼容端点)+LocalLlmEngine(常驻 Python 子进程)+ HF 模型缓存与微调桥。 - Model Store:OpenDAL 统一存储抽象,SHA256 完整性校验,读路径可选 foyer 缓存。
- Data Pipeline:Parquet 列存写入、mmap 两件套物化、CDC 增量同步、DataFusion 统计加速。
- 可观测性子系统:W3C TraceContext(错误与慢请求 100% 采样)、Prometheus 文本指标、可选 OTLP 导出。
- 配置与密钥:42 项
he3ml.*GUC 统一管理;密钥一律*_ref引用化。
3.5 同步推理请求处理流程
以一条 SELECT he3ml.predict(...) 为例,完整同步链路如下:

全链路的关键路径只有三段:Backend 薄透传(参数校验 + 信封)、SHM 无锁投递(约 500ns)、Worker 内批量合并推理。数据处理全部发生在 Worker 进程内,Backend 内存与连接占用始终保持恒定。
四、关键指标汇总
| 问题 | 技术方案 | 效果 |
|---|---|---|
| 大数据量训练 OOM | mmap 两件套 + 流式导出 | 2GB 预算训练 100GB;内存峰值 16–20GB → 2GB 预算以内 |
| 快照存储成本 | Parquet 列存压缩(5–10×)+ Iceberg 文件级增量 | 10 个快照 ≈ 1 全量 + 9 增量,约 9 倍降低 |
| 模型/库存膨胀 | OpenDAL 外置 S3/NAS/local | 库内仅存 KB 级元数据,备份不覆盖权重 |
| 预处理慢、口径漂移 | DataFusion 向量化 + fitted 随快照复用 | 统计提速约 17×;预处理复用提升约 23× |
| 推理吞吐 | SHM 无锁 IPC + 200μs 批量合并 | 树模型约 8×,Embedding 10–50× |
五、总结
HE3ML 的架构可以概括为:以"薄 API 铁律"将数据库进程与 ML 计算彻底隔离,以双通道 IPC(无锁 SHM + 数据库表队列)连接接入层与执行层,以 mmap、列存增量快照、外置存储、向量化预处理四项技术分别解决内存、成本、存储、效率问题。
本系列的后续文章将分别深入三个模块:《IPC 模块》介绍共享内存的七区域布局、无锁协议与批量合并的实现细节;《快照模块》介绍增量快照、数据预处理与外置存储的完整链路;《稳定性设计》介绍大数据量、小规格、高并发场景下的隔离、限流与缓存体系。




