B站作为国内领先的内容分享平台,其核心功能之一便是支持UP主们创作并分享各类视频内容。UP主稿件系统作为B站内容生产的关键环节,承担着从内容创作到发布的全过程管理。
为了满足不同创作者的需求,B站提供了多种投稿渠道,包括移动端的粉大加号、必剪APP,以及Web端和PC端的上传方式,确保创作者可以随时随地上传自己的作品。同时,B站的内容来源多样化,既有用户生成内容(UGC),也有专业生成内容(PGC),以及商业合作稿件等。这些内容通过分区品类、话题和标签等多维度进行分类,以满足不同用户的兴趣和需求。这就要求B站必须具备一套高效、稳定的稿件生产系统,以确保内容的顺利上传、处理和分发。
随着业务的快速发展,技术团队面临着组织变革、业务需求快速迭代以及系统劣化的挑战。在此过程中,技术债务逐渐累积。技术债务主要源于为了迅速适应市场变化而采取的临时解决方案,或者是已经过时的历史技术架构,这些问题若不及时解决,将会导致系统维护难度加大、系统复杂性提升和性能下降,进而影响用户体验和业务的持续发展。
作为负责稿件生产链路的业务团队,我们致力于优化系统服务,提高系统的稳定性和可用性。我们通过持续的技术改进和创新,努力减少技术债务,确保B站的稿件生产系统能够稳定、高效地服务于广大UP主和用户,支持B站内容生态的繁荣发展。本文会介绍下B站稿件生产的服务架构,并从系统可观测性和服务高可用优化两个角度分享技术实践上的经验和思考。
B站于2009年6月26日创建,B站的第一个稿件( https://www.bilibili.com/video/av2/)也是2009年6月26日创建提交的,稿件技术服务从09年以来已经有15年,历经多轮负责人的变更和多次技术架构迭代,演变为了如今较为复杂的微服务体系。如果将链路上所有模块系统统计在内,代码行数达到百万行规模。得益于业务的增速,稿件数量增长也非常快,在近两年多内增长了几倍,各类数据总和有千亿级别,分布在多个存储系统。
历史债只要迭代就会存在,甚至代码本身不迭代,外部环境组件随着时间前进,性能劣化也会产生技术债务需要治理。需要直面的现实是,很多技术优化都是线上问题驱动型,通过问题暴露“水面下的风险”。
Out of Maintance:
老旧的组件/平台/SDK已经不适用不维护不迭代,需要做迁移/重构/重新选型
No Owner:
维护人员离职或者转岗,导致老旧的业务逻辑无人认领熟悉,维护成本极高;No Owner + Out of Maintance的服务,需要更新组件版本更迭接口版本时,往往会遇到较大阻力
Dirty Code:
代码本身在历次迭代重构中“妥协”或者不充分的技术设计,导致的dirty code甚至dirty data
稿件生产在公司业务的定位,
创作业务入口 + 中台能力支持。
承接:粉版、Web、必剪、H5、OGV、课堂、开放平台、直播、地方电视台、动态、商业化等10多个业务方,技术稳定性意味着业务稳定性,投稿不可用、转码开放延迟、稿件数据同步失败导致不可观看,都会引起极大的社区舆情、客诉反馈、商业化行为的损失。
整个稿件生产从投稿到开放链路涉及环节众多,分四个大步骤:创作工具(剪辑/直传)、发布上传、稿件生产、数据开放。下图是一张简化版的端到端流程图。
涉及到的业务/团队有:
-
工具客户端、H5&Web端
-
稿件服务/内容生产系统
-
审核
-
AI工程与模型
-
转码调度/计算/存储
-
CDN,稿件媒体元信息刷新
-
C端服务
-
...
这些链路上一些
核心依赖的不可用就会导致稿件生产阻塞
,进而影响稿件开放的时长,比如假设:
-
生产工具App核心场景打开持续crash或白屏,将在生产源头阻塞用户,无法产生投稿行为
-
原片上传有问题,将阻塞视频上传,导致用户投稿失败
-
生产系统有问题,将无法驱动业务调度开展工作流,影响稿件开放时间
-
审核系统有问题,将在待审通道阻塞堆积大量稿件对象,影响稿件开放时间
-
转码系统有问题,将在转码队列中阻塞堆积大量视频对象,影响稿件开放时间
-
CDN刷新视频元数据有问题,将导致稿件状态已更新为开放但是视频无法观看,引起UP主和用户的客诉舆情
-
...
以上这些Case都会直接影响稿件生产的业务北极星指标,直接引起客诉,更甚会引发大规模舆情。简单的数学公式:SLA(Biz) = SLA(Core System1) * SLA(Core System2) * SLA(Core System3) * SLA(Core System4) * ...,因此整个链路上的强依赖模块都需要做到高可用。
先介绍一些技术名词解释和概念,后续再介绍系统架构时可以更方便理解。
archive
|
稿件
|
video
|
视频,一个稿件可以有多个视频,一个视频内部成为1P
|
aid
|
内部系统流转的稿件ID
|
bvid
|
用户可见的稿件ID
|
cid
|
视频ID
|
mid
|
用户ID
|
filename
|
用户上传媒体文件唯一编号
|
upfrom
|
投稿渠道,业务来源标识
|
UGC
|
指用户生产内容
|
PGC
|
指专业团队/机构生产内容
|
原片
|
原始上传的数字媒体
|
preupload
|
原片上传行为的代称,实际的上传行为更复杂,会有多种策略决定上传的Endpoint
|
upos
|
原片上传后的媒资文件存储服务
|
DAG
|
Directed Acyclic Graph,有向无环图,本文代指生产系统的流程图
|
转码
|
将原片进行编码格式转换,为了优化内容存储和传输效率,提高广泛用户群体的播放兼容体验,会有多路清晰度转码的环节
|
审核
|
对数字媒体内容进行审核,视生产渠道和稿件类型不同,审核环节也会有差异
|
多P稿件
|
包含多个视频的稿件,多P稿件生产流程比一般稿件复杂,需要等待所有P的视频内容完成审核与转码后才能开放
|
合集
|
多个稿件组成的集合
|
稿件是一个容器,呈现给用户的包括:视频,图文信息,互动信息等;幕后支撑系统运转的包括:状态,流量管控,多媒体相关信息等。
围绕着稿件大体上分为3类角色:UP、审核和用户,这三类角色通过各种各样的系统作用于稿件这个核心实体,并在各种行为中不断丰富稿件这个核心实体。
在这条复杂的业务路径中,多个团队在其中各司其职来确保稿件生产端到端的链路稳定性和系统的高可用。将上文介绍复杂性举例的业务流程图进行技术模块的逐层拆解,得到了如下这张架构分层图。图中只是简述了一些关键的服务模块,涉及到的微服务和模块太多,无法全部罗列在内。
分层解释:
1.前台,除了列举的常规业务入口之外,还包括了内部投稿渠道、运营审核人员使用的后台,一般会针对渠道进行网关入口隔离(服务部署级别 / 代码接口级别)。
2.网关,内部称之为BFF(Backend For Frontend),Client端的接入面,业务CRUD逻辑编排层,包含投稿视频上传、投稿接口、稿件列表、稿件编辑,是稿件产生的业务入口,更上游是创作工具(粉/必剪)和其他的投稿业务渠道(商单/OGV/直播/开放平台...)。
前台应用到网关之间的流量路径:Client -> WebCDN -> LB(四层/七层)-> API Gateway -> BFF,在源站SLB上有WAF,APIGW层有内嵌Gaia风控组件,做到统一转发/风控/限流/降级控制面。
3.业务应用,业务逻辑层Service,微服务部署形式,提供业务功能实现的标准接口;按照生产与消费职能可以分为B端业务域服务和C端业务域服务
外部服务依赖如稿件绑定tag/绑定topic/审核过机审模型等;通用域是基础服务,承担了全公司服务的流量调用,如账号/鉴权等。
4.内容生产平台,是一个基于DAG实现的调度系统,可以根据不同业务配置的执行调度作业串联起原子方法进行内容生产流程,支持业务注册接入并制定生产链路流程,审核系统、转码系统、版权系统、AI工程等作为能力方,暴露接口被DAG执行调度,节点之间通过同异步方式进行状态更迭通知与回调,确保节点状态更迭有序。
稿件系统基于CQRS职责拆分,B端稿件在生产侧完成后,内容生产服务会回调稿件服务的原子方法做开放通知Notify,通过Domain Message通知C端稿件服务,更新数据落库。C端稿件服务上游是稿件消费应用服务和网关,如搜索、推荐、空间、动态、收藏夹等等。
5.元数据存储,业务模块都有各自的数据实体对象,如稿件实体、视频实体等,这些元数据(包括媒资文件)存储在多个不同的存储介质中,有传统的关系型数据库,也有KV存储和分布式存储系统。
内容生产系统支持多业务场景注册、实现原子能力节点、自定义调度路径,具备基本的同异步调度、重试降级、failure callback、事件上报观测等能力,拥有面向研发人员的控制面,具备平台化能力与职责。
模块构成上,主要分为DAG管理,DAG调度服务(调度和指派),DAG状态服务,DAG监听服务和执行器。
-
DAG管理 ,管理DAG和处理单元(创建,编辑,配置)
-
DAG调度服务,分为调度和指派,调度是服务内部自动触发(资源变化和处理单元执行完成),指派是外部内容管理指定处理单元执行
-
DAG状态服务,主要是提供查询,更新和删除处理单元状态
-
DAG监听服务,利用Databus(一个基础组件,消息队列的封装)提供调度消息的缓存
-
执行器,具体执行处理单元,设置队列提供处理单元的入列出列操作,保障处理单元的有序操作
以稿件为例介绍业务是如何在内容生产系统中被执行的。
左侧B端稿件生产部分,从端侧上传原片进入服务端逻辑开始,生产系统调度过程中的审核域、流媒体域、版权域、AI模型域等不同系统模块,系统内部通过消息队列分发任务并等待任务完成的Callback Notify,进而转入下一层工作节点。有些节点虽然是并行调度,但是需要归并等待完成后才能进入下个节点,比如需要完成稿件、视频审核和视频的转码任务,才能进入开放节点。人群画像分类、转码效率优化、流程调度并行化、提升机审覆盖率、资源潮汐调度等等都是全局上可以使用帮助提效的技术手段。
进入开放节点后,右侧B->C的指向部分,体现的是稿件生产到开放的CQRS架构实现。CQRS拆分是稿件业务系统在多年前进行的操作,B端范畴的“稿件生产链路”,生产完成后基于领域事件消息驱动同步数据到C端稿件服务,由B到C的数据同步机制是经过CQRS思想架构拆分设计而成。技术架构依据组织架构边界,BC稿件也是两个团队在负责的。为了确保数据最终一致性,数据同步消费者有重试措施,并有数据同步对账脚本进行对比监控。
系统想要高可用,先要了解当前的可用性是什么状态,期望优化目标是什么,这些都是客观事实的技术指标来体现,这样技术优化才能有的放矢。
如果把稿件生产整体视为一个”大黑盒“,首先需要确定这个系统运行的指标是什么,例如:
接着将这个”大黑盒“拆解,分拆到不同环节模块下核心的服务、模块之间的协议、服务之间的数据流转链路,以上这个过程可以不断迭代演进,可观测性建设就是帮助感知到系统的运行状态,构建排查工具协助快速定位问题,更进一步能够做到业务异动分析。在对一个复杂系统进行拆解优化前,我们需要了解现状感知异常,因此可观测性比上来就做优化和重构优先级更高更有价值,这一章节会花一些笔墨来介绍下我们逐步建设的思路。
低头赶路找不到方向的时候,抬头看看北极星。
稿件生产的北极星指标是“
首次开放耗时M90/M95/M99
”,稿件可以多次编辑/打回重新提交进入生产流程,因此业务首先关注首次开放耗时。这是一个偏创作体验的指标,影响这个指标的客观因素有:原片时长、是否HDR、是否4K、长短视频占比、转码资源潮汐调度、人审耗时波动、黑灰产投稿量等。
这个指标的计算逻辑不复杂,统计每一天所有稿件T = (开放时间 - 投稿时间)的均值分位数,不过需要剔除一些如定时投稿的特殊业务场景。大数据平台每日任务处理,BI看板体现数据。
其他一些会关注的业务指标有:
业务北极星指标是T+1的,技术服务系统更关注实时的运行状态,先要知道负责的服务有无系统性风险,了解线上运行健康度,感知异常快速解决问题。
技术系统一般借助Log + Metrics + OpenTelemetry等手段建设系统观测体系,这三者的数据是以时序为基础、互为补充信息的参考系。
稿件生产链路目前已经整体覆盖【投稿】->【投稿-多P】->【转码】->【审核】->【开放】,做到了All Metrics In OnePage,方便一页可以总览各个环节的关键曲线变化。
技术关键指标基本都被囊括在了OnePage中,eg:
-
大盘量的走势:稿件量、视频量、创作者PV、创作者UV...
-
错误量趋势:客户端错误量、投稿核心接口错误率...
-
成功率趋势:整体/分渠道/分端投稿成功率、投稿QPS、送审成功数、转码完成数、稿件同步开放数...
-
容量大盘:DB、Cache等组件的容量水位线...
研发只要经常观察监控曲线、日志错误数曲线,自然会得到一些经验值来辅助判断当前系统的运行情况。不过线上监控抖动也不一定意味着系统发生了故障,我们肯定希望对于系统故障是“高召准”的,因此需要基于已有的、通过不同渠道上报的旁路数据,通过经验值来制定分层告警规则,并逐步对告警噪音降噪,找到比较合适的配置标准。现有多种故障召回渠道,包括:核心服务SLO下跌召回、监控告警召回、客诉反馈召回等,基本上一个线上问题产生,会按照时序依次在不同渠道体现(研发发现告警、SLO下跌,跟着用户有感客诉进线)。
我们期望比用户更早发现与定位问题,做到1-5-10是一个目标。当然实际操作下来也是有一些难度,有很多干扰因素导致无法达成1-5-10,比如第一分钟的异常发现延迟RT,应尽可能地小,从采集频率、计算频率、告警聚合、异常投递触达,都可以做优化。假如一些指标的采集窗口就在30s了,置信的告警需要观察N个窗口的走势,那么一般都会超过1min。5min定位问题和10min恢复,需要响应够快(1min感知是第一步) + 经验能力(业务熟悉程度、SRE能力、快速止预案、临场应急指挥调度能力等) + 平台工具好用(辅助观察类Trace/Log/Metrics、快速止损类APIGW、容量转发/降级/兜底等) + 运气成分(比如是否是半夜,懵逼情况下大家状态都不好)...
我们借助SLO大盘工具构建了核心业务场景,服务SLO下跌到一定阈值会有SRE Bot自动拉群触达;同时我们自己设置了多种档位的告警方式,包括企微Bot、短信、电话告警,根据核心与否和紧急程度逐级上升,业务告警规则List统一订阅到固定的告警组,规则已覆盖50+核心子场景,半年内通过这套机制主动发现Case 10+,早发现早解决,将Case升级成为事故的可能性扼杀在摇篮中。
有了业务大盘北极星指标,服务系统线上运行状态也可以做到监控了,下一步做什么呢?
如果将整个生产系统想象成一个内容供应链,已知每日的供应“货物”总数,每个“货物”又有大小轻重之分,大盘指标太笼统,下钻到供应链的子环节看下每个子环节的效率如何,是一个很自然的思考。
在服务系统稳定运行的前提下,我们开始下钻生产效率指标,首先需要将大盘指标转化为归一化的单位指标:
这个公式可以理解为:每一秒可以生产X秒的视频内容,我们希望通过各种技术手段优化这个效率越高越好(但是会有体验上的权衡),直至前资源能做到的边际效应边界。将以上公式做环节拆解(注意:下述公式最新有一些UPDATE,因为转码阶段做了优化转码措施,不再是串行加法关系,这里可以略加参考):
通过归一化公式可以统计每天的均值效率指标,再拆分到每个环节的均值效率,辅助判断每日的效率趋势,发现一些潜在问题,比如系统资源调度是否存在空转的问题进而导致效率降低。根据投稿分区、分端、UP主粉丝数圈层、稿件短中长视频、风险账户/高优UP等不同的参数进行数据聚类,再套用以上公式计算效率均值也是常用的观察业务异动的手段,eg:
以上几项措施,从北极星到大盘监控再到大盘数据下钻,是拿已经发生过的数据“以果推因”,我们还需要能够有一些别的手段,可以在这个“因”发生初期就感知到,串联起所有主要环节,精确到每一个Case的个例数据。为什么需要如此呢,考虑以下几个线上实际发生过的案例:
-
就算接口可用性达到了99.99%,损失的0.01%对谁的业务行为会有损,我们能定位到目标群体吗?
-
To B型业务就算只有一次失败,如果是【政务号】、【重要商单】、【S级活动演出】遇到了投稿上传失败,那么影响也是很大的
-
UGC创作业务复杂度不断提升,有一些失败行为发生在端上有一些则是在服务端,端到端的日常问题排查、用户行为回溯该怎么做?
一般的排查姿势是让用户在客户端尝试复现路径,然后点击本地日志上报 + 多个业务服务观察从SLB到Service的一连串日志和trace去定位原因,这个方式可以work但是不够高效,有些偶发性问题也不一定能够再复现,持续追查的资源投入比较高。
因此我们联合客户端和其他相关团队引入了业务全链路Trace能力,通过定义创作业务关键事件链路,并聚合串联客户端埋点,业务服务端 context trace传递,实现用户视角的全链路事件Trace。全链路Trace通过定义关键事件行为,做到
端到端可串联、定义尽可能详细、跨多个业务团队、上报尽可能实时、排查工具尽可能直观。
大致技术方案描述:
-
端到端的全链路业务追踪,客户端生成 origin_trace_id,和服务端trace_id打通(将客户端行为事件链接起来)
-
服务端复用 Open Trace 协议(框架层面已有能力),将客户端的 origin_trace_id 与 服务端的trace_id做映射上报
-
服务端的每个业务系统,通过lancer独立上报(如果上下游有origin_trace_id,就建立与服务端trace_id关系)到数据平台
-
建立准实时flink任务,通过查询数据平台ck,展现trace-tree
这个工具的好处是,正向的用户反馈点查(已知用户id、稿件id)可以快速定位整条链路,反向的根据已有上报事件数据,可以主动下钻排查,
让隐藏在技术指标之下的具体个例可以被感知
:
-
pending在某个事件状态的稿件集合,delay了多久
-
在关键事件节点fail的个例可筛查,发现水面下的个例问题,帮助排查代码中的边缘bug
-
关键事件耗时可视化,排序后可以知道每天耗时较多TOP N稿件是哪些等等
当前已经做到:
-
基于端到端的数据通道,落地业务全链路Trace工具,具备分析全链路问题的工具
-
可以下钻到技术层Trace查看调用,通道可以携带非常多的辅助数据,供技术排障使用
-
数据已经覆盖端上、投稿、视频上传、审核、版权、开放,40+ 事件定义 日2kw+事件上报
-
通过反向筛查每日输出报表,发现边界Case N例并fix
本节大致将技术和业务两个视角下的“可观测性”建设过程介绍了下,在使用观测系统的过程中,研发日常可以感知到系统的异常状态,发现了诸如合集异常、延迟稿件开发异常、稿件管理列表页偶发超时等业务Case;在技术改造是否值得投入执行需要决策时,也是结合了系统的当前指标来决定我们应该从哪些方向去进行优化和重构。下一个章节以几个案例介绍服务高可用的建设。
在一个已经存在了15年的服务系统中,历史债务一定是比较重的,要面对的不仅是代码质量劣化本身,还有诸如技术组件老化、技术选型过时、数据协议滥用、维护心智负担重、迭代效率低等多方面的问题。我们需要在治理债务的同时还需要保障好这个核心业务的稳定性不受损失,做到“边开飞机边换引擎”。
稿件服务中使用了多种存储来应对不同业务场景下的需求,在业务快速发展过程中,我们需要对现有的存储系统进行全面的风险评估和容量规划,制定合理的扩容计划和备份策略,确保存储系统的稳定性和可靠性。过去的一年多面对线上暴露出来的问题,我们决定先从存储切入,包括MySQL、TiDB、ES、泰山KV多个存储组件,涉及到稿件分库、ES索引分片拆分、TiDB IO尖刺优化、MySQL磁盘容量问题等技改项目。同时系统容量是业务不断发展带来的要求,以N年翻M倍的投稿量增长公式来计算,系统的负载吞吐是需要走在业务实际发生之前。除了上述提到技改项目之外,内容生产的性能吞吐优化、稿件ID INT32到INT64位升级、状态流转异常自动恢复机制、全链路自动化测试,都是必要合理的方式来达成系统稳定这一目标。
稿件分库
随着业务增长投稿量逐渐增多,现有的单Mysql的架构将会成为系统瓶颈,难以支持后续的业务增长,所以需要使用多数据库来扩大存储容量和IOPS能力。按照之前测算的数据进行分析,单库容量剩余50%可用空间,以当时稿件每日增速,到24年底该单库存储将到达极限。
为了提前应对将来的危机,对DB进行分库改造,跟随业务线性增长的10+表(每张表十亿级数据量)拆分到8个逻辑新库,其余表在老库不动,逻辑分库可以根据资源和业务需要部署在N个实际的物理节点上,只要考虑好流量均衡即可。技术复杂点:稿件作为最基础的底层数据服务,上游依赖服务众多,数据影响需要逐级扩散梳理,涉及到服务代码存储读写改动、发号器逻辑修改、历史数据迁移,同时在数据底层切换操作过程中,要确保核心功能需无损业务无感。项目管理上,整个项目关联了几乎公司所有主要技术团队,从立项之初到灰度放量时间跨度周期长,底层代码在变更周期内不能阻塞业务代码的迭代,代码管理难度大,因此需要有较多的心力放在整体项目风险把控上,要准备好完善的上线和回滚SOP,核心服务不容有失。
整体项目进行大约1年,截止到去年底DB切换基本完成,DB Proxy Service服务负责收敛所有稿件库表SQL,代理上游依赖服务对数据库的读写流量,老库保留双写读已全切新库,核心库表已无容量和QPS风险;8个逻辑库DB Binlog Topic聚合成一个消息Topic,与老库消息结构体保持一致,陆续推动100+依赖数据源下游切换Topic;大数据平台实时/离线50+任务全部完成改造。
实践下来还是不要将业务域内的核心DB Binlog暴露给其他业务,而是暴露重新定义的领域事件Topic,否则数据库字段增改牵扯下游众多,不敢轻易DDL,也直接拉长了分库切换的项目战线,算是早期系统设计过程中的一个设计缺失。
ES索引 & DTS优化
UP主稿件列表提供搜索过滤和展示用户名下稿件的能力,是用户编辑、查看管理自己稿件的重要业务入口,底层使用了ES存储聚合的宽字段数据。在优化前,稿件列表存在诸多问题:
-
10亿+数据单索引16分片,根据doc id分片,不具备业务routing语义,大部分请求需要全分片检索,查询超时长尾效果很明显
-
旧索引部署在混部集群上,出现过IO竞争导致的查询接口可用性抖动问题,导致过某一年年报活动,稿件生产完成同步到ES中数据写入夯住的线上问题
-
UP稿件排序需要观看、点赞、收藏等C端用户行为的数据,用户行为数据量级很大,此类数据刷入ES集群负担较重,且数据同步流程原先是非标的,走的全量scan DB同步数据,稳定性较差不是一个好的可扩展的方案
-
稿件分库改造,需要切换到新的分库数据源,新老分库切换涉及30+ ES索引,需在DTS链路上切换数据源
优化后独立集群部署,单索引120分片,根据mid分片,容器化部署ES on K8S,可低成本扩容。性能上根据压测支持到2000QPS,并可支持水平扩容,性能接近线性提升,PT99超时问题得到了较大缓解。下图为新旧索引对比监控,新索引60%流量旧索引40%流量,P50持平P80/P90/P99新索引均优于旧索引,其中P99新索引抖动尖刺显著减少,耗时降为旧索引1/3,P90耗时降为旧索引1/2。B端稿件列表需要互动数据进行粗排序,而全站用户对稿件互动QPS较高,B端ES集群无法承担上万QPS写入量,最终采用消费互动数据后聚合一段时间再刷新到ES的Delay Merge方案,因为业务上是根据互动指标粗排序,可以容忍数据的更新延迟,还有优化空间。
上文提到的DTS是公司内部的数据传输链路组件,平台上支持配置Data Source(比如DB Binlog Topic)、Data Destination(比如ES、KV、Cache等),可以比较方便且可靠地实现异构数据传输,链路稳定性有保障。DTS支持在数据源事件触发时,聚合一些其他的数据(Join Other DB/Table,比如商业订单 Join 稿件表Archive,属于跨业务域DB Table被Join),组装数据格式后传输到目的存储。
在处理跨DB/跨表Join数据时遇到了边界的数据不一致问题,假设A表binlog触发去Join B表时,B表主从同步还未完成导致聚合不到数据,异构数据落ES会缺失字段,数据完整性被破坏了;重试逻辑也很难做,因为DTS不具备业务属性,无法进入到业务逻辑中去判断是B表数据就是不存在还是因为某种原因延迟了。当时不得已采用了Delay Join来规避,即配置可延迟触发Join的时间。另外这种Join的弊端是,就算可以切换到主表Join解决主从一致延迟,DB层面仍然会被各种跨业务域的任务直连查库,主库不被保护得暴露会有系统性风险。因此与DTS团队沟通,平台迭代来支持从DB Join到API Call,业务提供的Data API中需要自行保障数据完整性,API协议通用化设计,DTS组件本身做好数据传输确保高可用一致性的原生职责。以下是一个稿件业务相关索引的DTS配置界面,左边的表是触发数据源,右边的是被Join DB Table,支持DB字段到ES字段的映射Mapping。