在当今企业降本增效、去肥增瘦的大环境下,大数据平台研发效能度量成为了重要的提升企业研发效率和产品质量的关键。本文介绍字节研发效能度量平台从 0 到 1 的完整演进过程,通过深入浅出工程实现过程中遇到的各类矛盾问题,帮助读者更好地应用技术解决方案,加深该领域的深入思考。
什么是 DevMind?
DevMind 是字节跳动的研发数字化产品与解决方案,目标是让研发各个层面的现状 & 问题可视、可评价、可诊断,辅助决策和改进,实现“数据驱动研发效能提升”。其中,包含 3 个核心能力:
度量,量化现状:整 合所有研发大数据,并由领域专家将经验转化为研发指标、分析模型。
洞察,诊断问题:对研发指标进行自动数据洞察,形成客观、准确的分析结论。
决策,驱动问题解决:辅助业务负责人、TL、一线研发了解客观情况、问题、解法,在各个工作场景中科学决策(场景主要包括:研发改进、团队管理、研发过程风险识别等等)。
详细了解 DevMind 体系:构建效能提升的“导航仪”和“发动机”,实现从数据到价值的跃迁
DevMind 的技术架构,如下图所示:
本文将从业务工程、数据工程中的各自 3 大“矛盾”展开,详解一下,如何在面向万人规模的效能度量平台中,在“既要、又要、还要”的不可能需求下,进行工程能力的设计与实施,从而达成有限时间、有限人力条件下的业务目标。
业务工程详解
在业务工程领域有三大矛盾:
矛盾 1:数据领域、角色多样化与用户协作效率的矛盾。
矛盾 2:平台领域专业性与用户非专业性的矛盾。
矛盾 3:场景复杂性(数据规模,数据结构、算法复杂度,变更频率)与系统稳定性、性能的矛盾。
因此我们需要有 3 套方案逐一击破。
2.1 激发生产力
矛盾 1——数据领域、角色多样化与用户协作效率的矛盾。
研发效能链路漫长,涉及到多个领域。而每一个领域都有自身独特的领域知识门槛。为了更好的将这些门槛在数据可视化分析方式磨平,需要构建完备的数据体系,并且 Involve 这个数据链路中关键角色。在执行过程中其难点主要体现在 3 个方面:
1. 数据领域多:
2. 用户角色多:
3. 用户角色能力不同,协作存在障碍:
造成这个矛盾的直接原因是数据分析的专业化门槛,导致数据工程师和分析师供给不足,而未受专业培训的业务同学却有心无力。
其本质原因是数据产品专业性的僭妄,没有真正用同理心去感受普通用户的需求场景。
2.1.1 解决目标
降低用户使用门槛,使得产品、运营、QA 等全角色都可以顺利使用。
2.1.2 解决方案
2.1.2.1 重塑流程
DevMind 重新设计了数据可视化分析的交互方式,将传统的“以选择数据源为起点”改为“以指标为核心”。让富有经验的数据分析师和领域专家专注于核心指标及数据分析模型的设计。让更多的业务参与者围绕指标完成数据探查,或是进行衍生指标的再生产。
这一交互形式的改变不仅释放了领域专家的生产力,更重要的是,以指标为核心的交互大幅降低了非专业用户的理解和使用门槛。此外,生产形态的改变,令 DevMind 指标中台不再是旁路的元信息管理工具,而可以深度地参与到整个生产链路之中。因此,这一改变有效避免了在指标中台中初次沉淀的数据资产因脱离后续业务活动而逐渐腐败过期的问题。
2.1.2.2 抽象生产资料——元指标模型
核心思路:以“元指标 + 度量对象”二元形式对基础数据层进行高度封装,使其拥有完备业务含义且可独立执行。
元指标模型:从物质世界到数学的转换。将数据可视化配置中分解为设计业务查询逻辑和配置可视化表达。
复合元指标模型:带有丰富业务含义的代数矩阵。辅以算术运算符和逻辑运算符进而获得更高层次的业务表达。
2.2 提升生产力
矛盾 2——平台领域专业性与用户非专业性的矛盾。
即使作为官方效能度量平台,DevMind 也无法通过有限的人力应对近乎无限的业务需求。要想在将效能提升理念在全公司研发团队中推广,就需要让每一位业务线相关同学参与进来。由最理解业务的同学进行分析,更容易找到贴合业务实际的洞见。这里引入公民数据科学家的概念。公民数据科学家 (Citizen Data Scientist),是指未受过高级数学和统计学正式培训的知识工作者,他们能够通过适配的应用产品从数据中提取高价值见解。
DevMind 所致力于的工作,就是不断降低数据分析的门槛,辅助公民数据科学家们更好的产出分析报告。
2.2.1 解决目标
丰富自动洞察算法工具库,优化用户分析效率,知其然知其所以然。
2.2.2 解决方案
2.2.2.1 Why——波动分析(比率指标)
比率指标难点:
数学层面:比率指标具有不可加性,无法直接进行维度分解,因此无法套用贡献度等经典分析方法。
业务层面: 比率指标的分子分母的维度并不严格对应,需要考虑至少三种场景,这也增加了分析复杂性。
2.2.2.2 How——潜力分析
需求背景:
基于波动分析可以有效定位造成异常波动的根因维度项,但有时这并非就是业务业务可以直接采纳的优化方向。因此需要有更好的算法,告诉业务方哪个方向有最大的优化潜力。
核心思路:
均值回归:假设维度分项数值都将围绕维度均值波动,波动趋近于均值的概率要高于背离均值的概率。
高占比项优先:指定维度的各维度项变化同一固定比率,则高占比维度项对大盘的影响更大。
维度稀疏度:基于稀疏度处理防止拥有较少维度分项的维度对大盘干扰,从而解决维度项数目对大盘。
2.3 量化生产力
矛盾 3——场景复杂性(数据规模,数据结构、算法复杂度,变更频率)与系统稳定性、性能的矛盾。
DevMind 作为数据类产品,算力情况是研发侧最为重要的要素。因此希望构建一套综合性算力评估体系,能够对 DevMind 现状进行准确的定量刻画。该算力评估体系后续将应用于运维治理、新需求准入评审、技术改造定量考核等多个场景。
2.3.1 解决目标
打破黑盒 ,通过构建综合全面的算力评估体系,实现对平台整体现状进行准确的定量刻画。当前我们对算力情况完全黑盒,甚至对“算力”没有一个准确定义。
一个具体业务场景:每半年的绩效季。绩效季是用户访问 DevMind 高峰期,基于历史数据,我们可以知道用户访问量和渗透率。但是这个访问量背后会新增多少“算力”需求,当前数据库能够承载多少“算力”需求?这些问题都是未知的。
我们一直以来在做的,只能是尽可能做准备,然后祈祷不要出问题。You can’t manage what you don’t measure. 我们真正要做的就是对现状准确刻画,定量的描述“算力”的需求和库存。
2.3.2 解决方案
2.3.2.1 明确应用场景
稳定性运维:基于全场景算力消耗监控,指导日常运维工作。并为运营活动等场景的资源申请提供数据支撑。
新需求准入评审:
计算方法:{算力成本} = {功能点单次访问算力成本} × {功能点用户渗透率}
业务约束:{平台总算力} ≥ {存量算力开销} + {新需求算力成本}
技改收益定量评估:构建平台算力基准水位,为此后技术性能优化后的定量收益提供公允的依据。
2.3.2.2 建立算力评估模型
对“算力”度量来源于两个方面。第一个是生产者也就是数据库,算力对于数据库意思是在单位时间内能够完成的最大查询量。第二个是消费者也就是 DevMind 平台。消费者消耗的算力是每个功能点产生的数据查询量 乘以 每个功能点的单位时间 PV。当数据库生产的算力大于等于 DevMind 平台消费的算力时,我们就可以认为整体营收是合理的。
而在上述讨论中“算力”是一个抽象的概念,因此我们首先需要将“算力”实体化。
2.3.2.2.1 算力评估分类
2.3.2.2.2 简化算力换算模型
算力定义:对于数据产品,算力是其完成业务目标所需要的物理成本开销。
算力换算:通过「基准查询」作为生产端和消费端链接的媒介和基本单位,将“算力”这一抽象概念实体化。
基准查询:选用产品形态中最通用且易于泛化的 Case,既可以在各业务场景中等价换算,也可由计算单元压测获得。
消费端算力建模:
模型分析对象是用户在指定时间窗口内对产品功能使用过程中产生的查询请求。
用户侧,需要考虑不同类型用户的规模,以及访问频率和访问深度。
产品侧,则考虑的是产品各个功能点对于算力消耗情况,以及产品不同用户空间的深度与规模。
2.3.2.2.3 生产端算力建模
定义:算力总量由服务架构计算层自身的物理特性和工程实现共同决定。算力总量的策略标准借鉴数据库 TPM(transactions per minute) 的概念,采用:「1 分钟最大可执行基准查询数」。
物理特性:CPU、I/O、Memory、磁盘容量、机房 etc。
工程特性:数据库类型及版本,索引选择、优化器实现、算法调优 etc。
2.3.2.2.4 算力工程优化思路
基于 MECE 原则的算力优化分析:
算力增加:
查询引擎替换:OLAP HSAP
查询模式升级:自建 SQL 优化器
算力利用率提升:
应用层利用率:精细化缓存、查询请求消重
计算层利用率:基于时分复用前后台任务切换
算力分配优化:
数据生产阶段:预处理 && 预计算
数据消费阶段:集群间动态调度
数据链路:离在线一体存算体系
2.3.2.2.5 动态算力调整:背压模式
在数据调用系统中存在三方:生产者 (Producer) 产生请求,通过管道 (Pipeline) 传输给消费者 (Consumer)。面对生产者生产速率超过消费者承载力时,可以衍生出三种策略:
缓存 Buffer:将多余的流量临时存储在管道内,再由消费者逐个执行。
丢弃 Discard:当上游流量已经超过下游承载力,也超过缓存队列长度时,需要将超出部分的流量丢弃。
控制 Control:降低消费者生产速度,直接从源头减少流量。
上述三种策略在工程实践中实际并不是孤立的,DevMind 通过自适应背压系统,实现了整体数据环路的动态控制。
背压(BackPressure):通过负载探针检测消费者负载压力。当负载超过阈值后,将压力反向通知上游,使上游的生产者及管道可基于背压感知执行相应策略,从而实现自适应调节流量的目标。
动态限流器:通过背压感知动态调节限流总量。触发限流时,基于在线配置按优先级放行请求。
分布式队列:通过同步调用异步化,即可实现削峰,也可对队列窗口内请求执行精细化控制。
数据工程详解
在数据工程领域也有三大矛盾:
矛盾 1:不同业务数据的差异化和标准化度量之间的矛盾(数据管理)。
矛盾 2:查询规模、时效性和引擎物理性能极限的矛盾(数据应用)。
矛盾 3:数据源的多样性、零散性和平台统一管理的矛盾(数据存储)。
因此我们仍用 3 套方案逐一击破。
3.1 数据管理
矛盾 1——不同业务数据的差异化和标准化度量之间的矛盾(数据管理)。
小到一个团队,大到一个部门,不同研发工具亦或是同一研发工具的不同使用方式都造成了数据的千差万别。
3.1.1 解决目标
打破传统 BI 平台空间隔离的固有属性,提供灵活的数据管理方式,最大化挖掘和复用数据价值。
我们可以带入如下的实际应用场景思考一下这些问题的解。对于场景一,首先是先找数据源,和需求平台沟通要数据,然后需要找 BI 平台去做落地。对于场景二,需要重复问题一的步骤,然后又会碰到新的问题,各业务数据标准不同,各自“小管”使用无问题,但是作为“大管”如何全局看整体?对于场景三,度量场景和范围不断被放大,又该如何解决这些类似的问题?
3.1.2 关键挑战
跨业务复用能力,简化“沟通成本”,这一块往往代价是最大的。
数据准确性刻画,“准”一般和“通用”是个悖论,需要权衡为了“准”所需要付出的成本和代价。
层级关系表达,这一点尤其重要,而且传统的 BI 工具平台不会带有这个功能概念,常规做法是下沉到数据本身上,靠数据关系去实现。
带着场景输入,我们从工程角度看下以前和现在的区别。
过去:
数据接入:寻找需求数据源,依赖平台数据开放能力,复杂的 ETL 工作
指标定义:从 0-1 讨论指标口径,定义计算逻辑
绘制图表:传统可视化绘图工作,经过自定义格式,排版等琐碎重复工作,最后输出仪表盘,汇总报告,基于图表拼接出风格迥异的报告
现在:
总结为一句话:“站在巨人的肩膀上”。我们只需要挑选指标故事生成属于自己的洞察报告即可,其他什么都不用做。甚至,指标故事都不用挑选,随意切换度量对象,就可动态实时查看属于该对象的洞察报告。
数据接入:不需要去理解“OpenAPI”,“数仓”,不需要考虑工程化能力,做一些基础的映射配置,仅此而已
指标定义:引入“专家”角色,“专家”可以是数据分析专家角色,可以是来自别人的经验沉淀
绘制报告:指标故事、洞察报告的最佳形态平台已经自动化固化好了
达到这样的效果,如何做?归根结底就是建立合适的“映射关系”。
答案:数据管理地图 + 度量对象映射树
3.1.3 解决方案
3.1.3.1 建立数据管理地图
生产者角度建立数据和业务的第一层 Mapping。
实现方式:同一个核心数据模型,共享底表,两个要求,解决业务共性和差异性。
通用字段:并不意味着同样叫“状态”的字段,所有业务方起的名字都一样,半自定义,字段业务含义通用。
自定义字段:全自定义,字段业务含义完全自定义。
效果:从数据生产上,尽可能把不同业务在同一场景下的数据集中到一个数据模型里。
3.1.3.2 建立度量对象映射树
使用者角度建立数据和业务的第二层 Mapping。
通过一段自定义“SQL”片段,在同一个数据集上去解决单业务、多业务、父子业务之间的映射关系。通俗易懂点,就是需要个过滤规则去筛选数据。这里面涉及 SQL、数据集、组织三者之间的相互依赖关系:
单数据集与度量对象之间的关系
业务特化 SQL 定义与度量对象之间的关系
度量对象间的关系
3.2 数据应用
矛盾 2——查询规模、时效性和引擎物理性能极限的矛盾(数据应用)。
大家见过的最长最复杂 SQL 长度有多夸张,比如在我们的项目中,单条 SQL 长度也就是字符数可以达到 1000W+,如果在这个复杂度的基础上再加上高 QPS 的要求呢。这样复杂的查询场景是如何形成的,从产品功能上归于组成洞察报告的三大要素:指标故事 + 洞察报告 + 度量对象,我们从三个维度看下复杂场景的来源:
定义:举个例子,复杂的聚合函数 + 复杂的逻辑表达式
机制:对于接近顶层节点的“上卷”机制带来的豪华 SQL
产品形态:单个格子,基线功能(全局基线、历史基线);整体,支持层级树展开的产品形态
3.2.1 解决目标——“超跑理论”
对于当前顶层业务节点的复杂查询,毫不夸张的说,单独拿一个指标出来都是个离线任务级别的计算。做个比喻:咱现有查询引擎现在是辆大巴车,载客多,但是不快,能到目的地;接下来比如我们用上了豪华查询引擎,就是超跑,速度贼快,但是载客少,一辆超跑拉一百个人基本翻车了。有一种方式是我们可以多搞几辆超跑同时运输,那我们还需要解决这样的问题,得告诉乘客们,你们这一波一万个人想都三秒同时到站,是不太现实的,当前技术下还没这种交通工具。
理想:我们希望找到一个完美的引擎,能够满足当前平台查询所有特点和要求。
现实:很遗憾,没有绝对完美的引擎,不同的引擎一定在某一方面是做增强的。
结果:
3.2.2 解决方案
曾经我们也尝试过,希望找到一颗银弹去解决燃眉之急,现实是仅仅靠一辆超跑“发动机”还不能够帮助我们将成千上万的用户又快又稳送达目的地。通过深度调研了业界流行的计算引擎以及技术选型的逻辑,基本概括为三大思路:
MPP 技术,大规模并行处理,分布式、并行化技术成熟,预期达到“亿级秒开”
内存计算,数据量大无法加载
预处理,Qube 化,存储换时间
引擎对比分析:
引擎选择逻辑:
历史原因:我们以关系型 MySQL 作为主要引擎,辅助 ClickHouse 解决大数据单表场景。引入新引擎面临的代价:语法适配和迁移改造成本,平台场景定位是 AD-Hoc 查询,自定义指标维度有几十万,由于 MySQL 太过强大和自由,导致切换任何另外一种查询引擎的成本非常昂贵,甚至都不可行。
3.2.2.1 换发动机(硬件能力)
寻求符合查询场景下的万能查询引擎
没有万能发动机,我们就尝试组合出一个万能发动机。这个时候不得不提字节的明星 HSAP 架构下的实时计算引擎 Krypton,OLAP 引擎比 MySQL 快百倍以上很正常,但是要应付我们如此复杂 SQL 的场景几乎没有,仅仅是一个语法兼容性就已经打败了很多组件。而恰好,MySQL 的语法兼容性正是 Krypton 的亮点之一:
云原生:存算分离架构,弹性扩展
易用性:语法兼容性
高性能:行列存储、向量化引擎、MPP、实时物化视图、异步执行
基于这些考虑,我们最终通过 MySQL + ClickHouse + Krypton 拼出了一个像样的“万能引擎”。
3.2.2.2 换策略(软件能力)
寻求有限硬件条件下的最佳策略组合
可以这么说,但凡和数据查询性能提升沾点边的优化策略方式,我们平台都有。在引擎上:不同的数据模型(明细表、笛卡尔表、Cube 表的合理性)、针对性的索引机制(比如查询特点优化联合索引顺序)、分库分表操作;在策略上:将大请求拆分、走异步限流削峰、数据预处理思路;在缓存上:分场景分功能模块下的长短缓存组合;在功能上:通过预刷(模拟人触发)、封板(提前算好存结果)等操作极限榨干引擎算力。
3.2.2.3 加约束给预期(管理能力)
约束不合理行为(滥用、滥配置)+ 纠正错误预期(秒变秒出)
有时候,优化再多都赶不上用户“造”的能力,所以必须加强准入准出能力。
报告约束
举个写代码的例子,很多人一个方法写上千行,很典型的一个 bad case。类比到报告中,有些业务同学恨不得把所有的指标都塞到一个面板中,先不说引发查询性能问题,比如你是老板或者用户,看到满屏的包含各种主题的五花八门的数字,内心估计是崩溃的。还有一些特殊场景,比如复合指标故事,一个复合指标是几十个元指标的组合体,相当于指数级膨胀。
数据嵌套
部分用户养成了缺字段就是 Join 的习惯,引发底层数据模型 Join 的层级增多。或者是像是一些日志型数据集,本身数据量极其庞大,一旦查询周期过长,就会引起数据库扫行过多。
SQL 规范
在长度控制可以做控制,点击保存按钮那一刻给出一些建议提示,比如可以走其他更合适的机制解决。在语法上进行优化和检测,提示错误语法,甚至是给出缩减合并的建议,并能做一些基础的 SQL 漏洞注入检测等规则注入。
在预期上,通过用户交流和访谈后发现个有意思的问题,用户并不是不能接受慢,而是需要给个心理暗示或者明示。比如进度条,转圈圈,或者更加直接粗暴“预计查询耗时”。因为不给任何预期,用户视角默认就觉的所有信息都是“秒级返回”,结果等了 10min,那肯定是要崩溃的。
3.3 数据存储
矛盾 3——数据源的多样性、零散性和平台统一管理的矛盾(数据存储)。
我们不产数据,我们只是数据的搬运工。这个问题估计做数据建设相关的工作同学都有共鸣,工作本身不难但是做好标准化管理很难。
3.3.1 解决目标
业务现状:业务数据开放能力参差不齐,每个业务或多或少做过一些数据建设。
技术现状:成熟的数仓建模理论且一般公司配备完善的数据中台能力。
对数据生产方来说,经营意识比较差,加上频繁被打扰,用户之间信息不共享,边际效益非常小;对数据消费者来说,沟通对接成本高昂。所以,不得不面临数据管理方式差、缺乏共建共享能力、对接成本高昂这些共性难题。
3.3.2 解决方案
3.3.2.1 建立数仓门户
从找人过渡到找系统
数据门户定义:利用前端自助建站平台,把杂乱的功能网址、文档秩序化的管理起来呈现给用户一个统一的入口。
生产侧:规范化标准建设,通过纯傻瓜式教学(数仓规范、命名、权限、质量、用户文档),然后将生产出来的资产表校验上架,汇总到一个大的数仓主题中。
消费侧:有门户、有用户群、有清晰的用户文档、有分发答疑机制,用户消费数据无需再到处找不同的平台方,而是直接统一的入口。
这套玩转起来后,会呈现一个滚雪球效应,消费者用的舒服了一是会驱动工具平台方按照这个标准实践,二是自己也可以变为生产者,把聚合后的表分享出来给其他消费者。
3.3.2.2 建设数据链路
标准化数据表到可用的数据模型。
整体概括为数据“ETL”,经过批流集成、批流开发变成 DevMind 平台真正的数据资产表。数据集成核心就是不同存储类型之间的转换。数据开发核心就是写聚合逻辑,把数据加工成目标宽表。
工具能力本身,成熟的数据中台都会覆盖,在我们自己的项目中,更多的是聚焦在应用过程的管理和机制上,把数据中台能力用好才是难点。只有做好如下这些点,才能称之为“数据变为可用模型”的转换。
版本号:解决数据一致性以及快照问题
调度时间:理想情况是满足 T+1,我们有成百上千个数据集,需要考虑队列优先级、任务优先级因素
蓝绿部署:解决任务同步的“开天窗”问题,比如清除式写入任务带来的数据不准窗口期
资源协调:资源不是无限的,同样需要考虑队列优先级、任务优先级因素
任务依赖:合理的拓扑图和链路设置
中长期演进方向
4.1 更开放、更智能
开放性:类似 HiveUDF 生态
流程化:DBT,解决 ETL 中的 T 场景
智能化:当前火热的 AIGC 潮流,在具体的场景上能否做些实际落地
可观测:数据全生命周期可视化管理,数据运维和排查上作用非常大
4.2 隐私安全有保障
扩展阅读
DevMind 体系:构建效能提升的“导航仪”和“发动机”,实现从数据到价值的跃迁
DevMind 技术:覆盖数万研发人员,字节跳动首次公开效能度量核心技术!
评论 1 条评论