专题 · Deep Dive

全部专题

从 0 到 1 做一个企业级大数据平台

把散在 MySQL、MongoDB、HBase、Elasticsearch 里的多源数据,收成一层可复用的数据能力——底层技术统一、数据能力平台化、上层业务快速复用。

给要在多个业务系统之上做数据平台的工程同学:不止讲四层为什么这么分,每一层还写清楚用什么做——包括最容易守不住的那条线:让业务直连数据库。

先记住这三样

一句话

数据只接一次,业务只写自己的差异。

一条链
  1. 1每个业务各存各的
  2. 2同一份数据被一遍遍重接
  3. 3所以分三层收

一张导图

每个业务各存各的同一份数据被一遍遍重接所以分三层收背景怎么统一,怎么复用差异谁吸收,业务怎么扩说法和权限谁来管问题数据入口只留一个换存储不用改业务代码字段说法和权限有人统一管目标01 为什么做方案架构实现02 怎么做架构口径能力面与应用面个人职责结果分层的判据是「差异被谁吸收」复用是收口数据入口,而且必须比直连更快先统一,再复用,最后才谈扩展沉淀有几个数据源、谁负责对接,新业务平均要写多少取数代码同一实体在几个地方有副本、有没有业务在直连库权限和日志在哪一层强制反思03 做成什么从 0 到 1 做一个企业级大数据平台
01为什么做

背景

这个平台的起点不是「数据量大」,是同一件事被不同团队做了一遍又一遍。业务在长,数据源也在长,中间没人统一管。

  1. 1

    每个业务各存各的

    关系数据在 MySQL,结构多变的在 MongoDB,海量明细在 HBase,要检索的在 ES。谁都没错,合在一起就是孤岛。

  2. 2

    同一份数据被一遍遍重接

    新业务要用旧数据,就得自己写一遍对接:四个业务对接同一份数据,就是四套连接、四套字段映射、四套权限处理。做过的取数逻辑别人也用不上——智慧搜写过的,综合轨迹那边只能复制过来改改再用。业务还在一个个加,平台就永远在补旧账,新业务要等的时间也不会变短。

  3. 3

    所以分三层收

    底层技术只建一次 → 抽取、碰撞、合并、分析做成公共能力 → 上面的业务只写自己的业务,不再碰存储。

问题

「数据多、数据杂」只是现象,不是问题。真正要回答的是下面三件事,每一件都对应架构里的一层。

  1. 1

    怎么统一,怎么复用

    数据来源这么多、类型还不一样,逐业务对接只会越接越乱,必须有一层把「从哪取、怎么拼、按什么口径」收在一起。复用不是把代码抄给对面,是让对方调同一个能力、得到同一个口径。

  2. 2

    差异谁吸收,业务怎么扩

    四种存储的查询写法、事务能力、分页规则都不一样。这个差异总得有人吞:不在能力层吞掉,每个业务就得各吞一遍。业务还在持续增加,如果新业务要改平台才能接进来,平台就成了瓶颈——扩展的方向必须是业务侧只写差异。

  3. 3

    说法和权限谁来管

    同一个人在四个库里都有记录,两个应用查出来不一样,业务方立刻就不信这个平台了。谁能查、能查哪些、查过留不留记录,放在各个应用里自己写一遍等于没做;得有一层谁也绕不过去。

目标

三条:数据入口只留一个、新业务真的少写代码、字段说法和权限有人统一管。第二条最关键——平台这条路要是比直连还慢,业务一定绕过去。

  1. 1

    数据入口只留一个

    新业务要数据,不用再自己去对接数据源,改成在平台上配一下就行。这条路必须比直连更快,不然人家一定绕过去。

  2. 2

    换存储不用改业务代码

    换数据库、换组件的时候,业务代码一行都不用动。要是要动,说明这层是空的。

  3. 3

    字段说法和权限有人统一管

    同一个字段全公司只留一份说法;谁能看什么、谁查过什么,都在固定那一层管住,出了事查得出来。

02怎么做

方案

一条链:一次跨库轨迹查询,在平台里走了哪几步一次真实请求:查某个人的跨库轨迹

平台好不好,不看架构图,看一个新需求进来要写多少取数代码。以「查某人近三个月的轨迹并关联比对」为例。

第 1 / 7 步
统一接入请求从统一接入进来:Nginx 收口,Gateway 路由到综合轨迹应用,过滤器链顺手完成认证、租户识别与限流。应用还没醒,权限已经过了。

架构

统一接入

Nginx · Gateway · Netty接入
一句话

所有外部请求先过 Nginx 与 Gateway,实时通信另走 Netty 长连接;业务应用不自己对外开口子。

30 秒 · 为什么这么设计

入口收口,才有地方统一做鉴权、限流、审计和灰度。每个应用自己开入口,这四件事就会被做 N 遍,而且每一遍口径都不完全一样。

常见追问

Gateway 挂了是不是全站不可用?

是单点,所以要横向多实例 + Nginx 上游探活。收口的代价就是入口必须做得比任何应用都稳,这是设计约束不是可选项。

它拒绝什么、什么时候会出错

不接管数据所有权源系统仍是各自业务的真相源,平台负责统一使用,不负责替代录入与维护。把所有权抢过来,平台会瞬间变成所有业务的数据责任方。
不替业务写规则能力层只做取数、归一、比对、聚合。业务判定留在应用层,否则每加一种预警规则都要改平台,扩展性当场失效。
不承诺一种存储打天下事务、灵活结构、海量明细、相关性检索这四种需求天然冲突。平台的价值是让选型差异被吸收,不是证明某个库更好。
不做实时与离线的中间人秒级链路和重统计任务分开跑。混在一条链路上,两头都拿不到自己的延迟预期。
权限不是可选项数据可查的前提是「有权查且留痕」。这一条由接入层强制,不接受任何业务以进度为由绕过。

实现

技术选型

每一格都是实名组件与它的分工。口径是通用的:换掉「公安」两个字,任何多源数据平台都能照着这套分层判断。

底座与接入

微服务底座Spring Cloud Alibaba:注册、配置、服务调用统一,业务不再各自长一套
注册与配置Nacos:数据源开关、阈值调整变成运维动作而不是发版动作
限流熔断Sentinel:入口与能力层都要过,防止单个业务把平台拖死
入口Nginx 七层入口 + Spring Cloud Gateway 路由与统一过滤器链(鉴权、租户、限流埋点)
实时通道Netty 单独承接长连接推送,不与 HTTP 请求抢同一条链路

存储分工

MySQL配置与强事务数据:数据源登记、积木定义、权限模型
MongoDB结构多变的业务对象:字段随业务演进,不适合先改表再上线
HBase海量明细与轨迹类追加写:按行键取时序,不靠二级索引
Elasticsearch分词检索与相关性排序:智慧搜这类模糊查询的唯一入口
分工原则让每类数据待在最擅长的位置;差异由数据能力层吸收,绝不上浮到业务代码

数据积木

抽取把多源数据落到统一模型,是「数据怎么统一」的落点
碰撞两份及以上数据集关联比对,公安业务最高频的一块
合并同一实体跨源归一,直接决定两个应用查出来是否一致
分析聚合与统计,输出给行为预警、数据分析这类应用
契约对外配置化输入输出,对内吸收数据源差异;过程可追,不做黑盒

公共能力

认证与权限统一鉴权服务,接入层强制调用;细粒度裁剪在应用侧做
日志统一字段落 ES,可回查「谁在什么时候查了什么」
文件与消息各收一个通用服务,业务只调不建

复用的判据(新业务接进来时看这四条)

对接成本新业务需要自己对接几个数据源?正确答案是 0
直连检查有没有应用绕过能力层直连库?有就是平台设计缺陷,不是纪律问题
口径一致同一实体在两个应用里查出来必须一致,不一致先修合并积木
重复实现认证、权限、日志、文件、消息是否被某个业务又做了一遍

会踩的坑

这些坑跟行业无关,换任何一套多源数据平台都会原样遇到。顺序照着链路走:对接 → 分层 → 拼数据 → 统一说法 → 公共能力 → 底座 → 查一条完整链路。

  1. 1

    每个业务自己对接数据源

    最典型也最贵的一种浪费:同一份数据被四个业务各对接一遍,四套连接配置、四套字段映射、四套异常处理。改一次源表结构,要通知四个团队。

    怎么改的对接数据源这件事只允许出现在抽取积木里。业务侧只描述「要什么」,不描述「从哪取」。新业务如果还需要写对接代码,说明积木没建够。

  2. 2

    存储选型泄漏到业务层

    应用代码里出现「这个查 ES、那个查 HBase」,说明差异没被吸收。后果是换存储等于改所有业务,平台层形同虚设。

    怎么改的查询语义在能力层定义(按实体取、按时间取、按关键词取),存储只在能力层内部路由。评审时只看一条:业务代码里有没有存储名字。

  3. 3

    数据积木做成 SQL 包装器

    积木只把查询字符串挪了个位置,参数还是业务拼。看起来有平台,实际什么都没复用,业务换个数据源照样全改。

    怎么改的每块积木必须有配置化输入输出契约,并且能独立换掉底层实现而业务不感知。做不到就只是把 DAO 换了个目录。

  4. 4

    同一实体多源口径不一致

    智慧搜里这个人叫 A,综合轨迹里少了一段。用户不会理解为「数据源不同」,只会理解为「这个平台不准」,信任一旦丢了很难回。

    怎么改的实体归一放在合并积木里统一做,并且规定主源与优先级;两个应用必须调同一份归一结果,不允许各自拼。

  5. 5

    公共能力被绕过

    某个业务为了快,自己写了一套登录和权限。上线时没人拦,半年后它就成了全站唯一没有审计入口的地方。

    怎么改的认证与权限由接入层强制,绕过就没有路由;同时把接入成本做到足够低——多数绕过是因为规范比野路子麻烦。

  6. 6

    底座反过来要求业务适配自己

    底座团队把日志格式、发布流程、目录结构都做成硬性门槛,业务发现绕开平台更快,于是平台开始空心化:文档上全覆盖,实际没人走。

    怎么改的底座只统一「不做会各自长一套」的部分:注册、配置、限流。其余以省事吸引人,不以审批强制人,并定期看真实接入率。

  7. 7

    把实时和离线混在一条链路

    同一个接口既要秒级响应又要跑大范围统计,结果是两头都不达标:在线查询被慢任务拖住,统计任务又在等一个不可能快起来的接口。

    怎么改的实时通道与批量路径分开:Netty 与短查询走在线,重统计走独立的批处理入口并明确延迟预期。能力层可以共用定义,执行路径不要共用。

03做成什么

结果

这一期能确定的是结构口径,不是实测数字。平台规模类指标源材料里没有记录,全部留成回填位。

不编数字。数据源数量、日增量、总数据量、查询 P95、任务成功率、接入业务数、重复开发下降幅度,都要拿真实运维数据补上——补上之前,任何「支撑了 N 个业务、日均 X 亿条」的说法都不作数。

架构口径四层:统一接入 → 业务应用 → 数据能力 → 基础平台,业务应用不直连存储;外部请求统一收口 Nginx + Gateway,实时推送由 Netty 单独承接
能力面与应用面抽取 · 碰撞 · 合并 · 分析四类积木(碰撞是公安业务最高频的一块),支撑智慧搜、综合轨迹、行为预警、数据分析四类应用;四类存储各管一段:强事务配置 / 灵活结构对象 / 海量明细轨迹 / 分词相关性检索
个人职责平台架构与核心模块建设,参与最深的是公共能力与数据积木两块

及格线

业务不许绕过平台新业务对接数据源数 = 0,应用直连库数 = 0。还要自己写对接代码,说明抽取积木没覆盖住,问题在平台不在业务;出现一条直连即视为架构失守,处理优先级高于新需求交付。有例外通道就必须登记并限期回收。
同一实体跨应用口径一致两个应用查同一个人结果不同,先修合并积木,不要在应用侧打补丁。
权限与审计无绕过任何查询都要能回答「谁在什么时候查了谁」。查不出这条记录,说明有旁路。

沉淀

这个项目最后带得走的不是「用过哪几个库」,是下面这三条判断——下次再建平台,它们会先起作用。

  1. 1

    分层的判据是「差异被谁吸收」

    换存储要不要改业务代码,是检验中间层真伪的唯一标准。要改,那层就是虚的;数据能力层的意义就是把选型差异关在自己身上。

  2. 2

    复用是收口数据入口,而且必须比直连更快

    重复开发真正发生在「各自对接数据源」这一步,而不是代码层面;积木只是把这一步变成配置,省下的成本比代码复用大一个量级。业务绕过平台直连库,多数不是意识问题而是平台那条路更慢更麻烦——所以治理靠降低合规成本,不靠宣讲:统一注册、配置、限流就够,把规范做成硬性门槛,业务会绕着走,平台空心化。

  3. 3

    先统一,再复用,最后才谈扩展

    来源统一 → 能力复用 → 业务扩展,这个顺序不能换。跳过第一步直接建扩展机制,等于在散沙上盖楼,越扩展越乱。

反思

以后再设计数据平台,我先问这三个问题。

  1. 1

    有几个数据源、谁负责对接,新业务平均要写多少取数代码

    决定要不要能力层,也衡量复用是不是真的。

  2. 2

    同一实体在几个地方有副本、有没有业务在直连库

    决定合并逻辑放哪,直连是平台设计缺陷的信号,不是纪律问题。

  3. 3

    权限和日志在哪一层强制

    决定能不能审计。

你大概率会问

为什么不直接让业务查 ES,快得多?

单次需求确实快,代价是查询语义散落在各应用里。半年后同一个人在不同应用口径不一致、换索引要改所有业务、审计无从下手——这三件事比省下的两天贵得多。

数据积木和普通的接口封装有什么区别?

接口封装吸收的是调用复杂度,积木吸收的是数据源差异。判据只有一条:底层换存储,业务要不要改代码。要改,就还只是封装。

多源数据口径不一致具体怎么解?

先定主源与优先级,再在合并积木里做实体归一,最后规定所有应用只能调归一结果。技术上不难,难的是让业务方接受自己那份不是权威版本。

为什么是四种存储,不上全套大数据组件?

平台主要服务在线查询与数据服务,四类存储已经覆盖事务、灵活结构、海量明细和相关性检索。引入用不上的组件只会多出运维面,所以按数据特点分工。

新业务接进来大概要多久?

取决于它需要几种新积木,而不是对接几个数据源。数据源对接已经收口在抽取里,新业务只做业务语义——这也是判断平台是否真的在发挥作用的指标。

这套架构换个行业还成立吗?

成立。四层里只有积木的具体种类是行业相关的(碰撞在公安业务高频),底座、能力收口、多模存储分工、公共能力复用这套判断跟行业无关。