我是怎么用7天时间给公司节约20万开支

11 阅读8分钟

背景介绍

我们公司有一个 BI 系统,用的是 FineBI。为了避免订阅费,用的是个人版——除了会限制并发和一些用不到的功能,其他还好。数据计算 / 清洗用的是腾讯云的 MapReduce,数据同步到clickhouse 中。

搭建系统的人早已离职,目前这个系统经常会出现问题,特别是腾讯云的 MapReduce,不知道为什么总是 OOM 爆内存,导致数据无法定时同步。

运营经常找我让我去修一下,搞得我很烦——因为我也不知道从哪里入手。但是看数据又是刚需:虽说是个小公司,但也是一个有相当多注册用户的 C 端 App,数据库里有几十亿条记录,直接用 SQL 统计,很可能就把线上服务搞崩了。

问题拆解

问题出在哪

MapReduce 内存泄露。我让 AI 读日志,分析结论就一句话:加内存

这就很尴尬了——本来每个月要专门给 MapReduce 支付 8000 多的费用,再加内存又是几千块支出。对本来财务紧张到要开除保洁阿姨的小公司来说,这可能就是压在骆驼身上的最后一根稻草。

第一步:重构数据仓库

与其继续给 MapReduce 续命,不如从根上把数据仓库重构了。经过一番 AI 互动,决定采用 Doris + Flink CDC 的方案。

相比原本沉重的 Hadoop 生态,组件精简到只有 2 个,还带来 2 个史诗级优势:

  1. 数据可以做到半实时同步:运营人员不用等到第二天才能看到销售情况和活跃数据,Flink CDC 可以实现相对准时的数据同步;
  2. Doris 的 JOIN 效率极高:原本留存的大量定时更新的 backfill 脚本,都可以不用管了。

第二步:BI 工具的去留

数据仓库定了,下一个问题是:还要不要继续用 FineBI?

  • 个人版走不下去:目前用的版本非常旧,而且 FineBI 个人版并非云原生,需要把所有组件都放在一个镜像中才能运行。如此沉重的镜像在集群中运行,本身就是严重的隐患——继续用,不过是又埋了一个坑。
  • 企业版用不起:去了解了一下,一年十万订阅费——告辞!
  • 开源也接不住:Metabase / Rill / Evidence 都看过,并真实部署调研过。但要把 FineBI 的图表迁移过去,首先需要一个非常懂之前这些看板是怎么搭建的人,梳理数据的因果关系,再熟练使用新平台重新搭建。 非常凑巧的是(并非凑巧),FineBI 上搭建看板的同事也离职了。这活让我干?我可不想干!

摆在桌面上的三个方案

  1. 升级 FineBI 企业版:支付一年十万订阅费,把数据底层从 ClickHouse 改成 Doris,再迁移数据源——工作量和重建看板没有区别。除非重建 Hadoop 体系,但这玩意我感觉我搞不定:十来个组件、各种自定义脚本在里面跑,Hadoop 生态本身也没有针对云原生设计,搭建起来不一定比重建看板简单(后面部署 doris和 flink-cdc 也证明了,hadoop生态云原生化坑挺多的)
  2. 用开源方案 Metabase:在调研的 3 个开源项目中算比较成熟的,但需要专门招聘一个数据处理的同事来研究怎么迁移。迁移时间和最终成本并不会少多少。
  3. 自己做一个 BI-Agent:让 AI 来完成数据迁移,同时让搭建看板的学习成本降低为 0。

方向确定

经过前面的问题拆解,对于我们这个小公司,唯一可行的解决方案就是 3。如果采用 1 / 2,基本就是往干倒闭的节奏。

而且选择方案 3,也是我经过深思熟虑后最简单的解决方案。在写本文的时候,我总共用了 7 天时间完成整个系统的实现并上线。虽说还不完美,但已经可以完全替代现有的 FineBI。又是把公司从存亡危急中拯救的一天(笑死)。

架构设计

前面数据仓库的设计已经明确了,采用 Doris 和 Flink CDC。

整个系统的实现代码采用 Rust——因为 Rust 编译之后就是一个小巧的二进制,镜像极小,内存泄露困难,计算效率极高。除了难写,针对目前的需求场景是完美的语言。难写也是 AI 写(哈哈哈)。

架构设计图如下:

image.png

介绍一下各组件的功能:

  1. portal:门户入口,整个系统对外提供服务的 Web 页面;
  2. bi-agent:用来创建 / 修改看板,内嵌一个 LLM 服务,在约束下进行看板的编辑和修改;
  3. bi-checker:检查 agent 产出的看板的代码质量,如果检查不合格,打回去让 AI 重写——因为看板就是 React 代码,可以用成熟的工具进行代码质量检查;
  4. dashboard-app:看板运行时,bi-agent 写的看板就在这上面运行,是一个独立的服务,可以被嵌入到任意的网页中;
  5. bi-data-layer:安全代理,审核访问人的权限,约束 SQL 格式避免注入攻击;
  6. bi-etl:并不负责数据抽取,就是做一些建表、物化之类的杂活。

开发日记

第一天

  • 纯调研和设计框架,明确技术难题和如何解决。

第二天

  • 先让 AI 搭建开发环境,可以自行测试调试;然后让 AI 根据框架设计开工,完成初稿。

第三天

  • 本地测试通过,修复各种 BUG。

第四天

  • Flink CDC 和 Doris 上线,进行数据抽取。
  • 众所周知,小公司的数据不会那么规范——什么中文字段名、复合字段等等,Flink CDC 连续宕机。
  • 特别搞笑的是,我司数据库的自增字段,flink cdc 居然无法同步,也不知道是不是经常直接用ID增加数据的原因(苦笑
  • AI 自己居然可以写 patch 注入来解决,只能说 AI 很牛逼。

第五天

  • 数据同步还有问题?
  • 我看着带了 5 个 patch 的 Flink CDC 陷入沉思,决定并行做 2 条路:
    • 一条是让 AI 自己用 Go 实现一个精简版的 Flink CDC;
    • 一条是让 AI 把 Flink CDC 源码改了,重新打包。
  • 最后,弱智的 AI 浪费了我大量 token,抄了一个满是 bug 的 Go 版本 Flink CDC;走改源码的那条正常工作了,问题终于得到解决。

第六天

  • 迁移 FineBI 看板:让 AI 根据 FineBI 的备份数据生成一个转换脚本,生成当前项目的看板代码。
  • 一整天都在解决 bug,把一些用不上的看板删了。这天最终可以正常展示了——虽然有点难看,但是数据是通的。
  • 其实到这一天已经可以交付了,运营可以看这边的数据了。

第七天

  • 开始调教 agent,增加一些工具。
  • 优化看板编写的准确性,精简提示词。
  • 优化 RAG 表格语义召回。
  • 继续修BUG

以上开发日志只记录了我觉得还比较重要的事情,实际上忽略了很多细节工作,比如权限管理、物化表管理、看板的版本管理。

而且项目我认为并不算开发完成,还有很多可以优化以及还没实现的地方。我做了可迭代的设计,让 AI 可以快速定位问题、梳理原因(应该会再写一篇博客)。

项目特点

  1. 没有任何数据库:整个项目的配置通过 GitOps 的方式部署,非常方便迁移 + 扩容,非常的云原生,对 AI 极其友好,不会让问题隐藏在不可见的地方。如果非要说有数据库,那就是 doris 数仓。
  2. 看板即代码:看板是 React 代码,自然保存在 Git 仓库中。bi-agent 会创建一个 worktree 来进行编辑,编辑完成后自动推送到 Git 仓库保存。你可以选择本地编辑看板文件并推送,也可以选择用当前项目的 agent 来编辑代码——最终上线只需要一个 PR 合并的步骤。
  3. 表格语义文件化管理:表格语义也是文件形式,被 Git 管理。这个我专门做了下,可以在界面中进行编辑,免得运营人员去拉代码。底层走的也是看板代码管理的逻辑,改完之后需要通过 PR 合并到主分支。

结语

后面我会再水一些章节,那些章节我会用 AI 把项目框架的细节描述一下。很多精彩的设计——比如看板的版本迭代、零配置等——都会在这些文章中具体呈现。

本文纯手写,中间一张架构图是我让 AI 根据代码画的,其他配图我也懒得配,因为具体数据打码太麻烦了。如果发现文本看得不舒服、想到哪写到哪、写得和流水账一样、还有很多错别字——你的感觉是对的。

声明式 BI 平台的 AI 编辑闭环与取数安全设计 —— 工程实现报告