导读 本次分享的主题是数据开发的生产环境隔离,主要介绍小米在数据开发生产环境隔离方面的思考探索和落地应用。数据开发的生产环境隔离是:完善数据开发流程、保障数据安全和质量,提升数据应用效率的重要措施。
全文目录:
1. 数据开发生产环境隔离的背景
2. 技术思考及选型
3. 落地路径
4. 业务实践
5. Q&A
分享嘉宾|崔博雯,小米 高级研发工程师
编辑整理|天天 golden tech
内容校对|李瑶
出品社区|DataFun
01
数据开发生产环境隔离的背景
首先介绍小米数据平台的发展历程,小米的整个数据平台发展经历了如下图所示的三个阶段。
1. 多平台阶段
2019年处于多平台阶段,各平台的覆盖度各异并且账号和权限体系各不相同,用户如果想要完成完整的数据开发链路,需要操作多个平台。数据链路分散在各地,缺乏统一的业务管理视角。
2.统一数据平台阶段
2021年完成了统一数据平台的研发,主要包含统一元数据、统一权限和统一调度。支持多个计算和存储引擎,覆盖了离线和实时数据开发场景。虽然完成了数据平台的统一,但是挑战也是巨大的,尤其是安全、质量和效率这三大挑战,这三方面的挑战也是后续小米数据平台发展的新起点。
3.开发在线化建设阶段
2022年开始着手去做开发在线化的建设,其中包含了本次分享的开发生产的环境隔离、标准化开发流程以及正在建设中的WebIDE。
小米统一数据平台即小米数据工场,主要承担着为全公司各团队及小米的生态链企业,提供数据采集、计算、存储等基础能力,以及机器学习、挖掘的工具和方法的任务,下图是数据工场的架构图:
从上面的架构图可以看出,数据工场支持多种数据源例如终端设备、服务端数据、数据库以及物联网设备信息上报。支持多种数据存储,例如传统Hive存储、数据湖Iceberg存储以及文件存储HDFS。在计算层面同时支持Spark离线计算和Flink实时计算两种模型。数据查询也是一个非常重要的场景,在数据查询方面支持统一的查询入口以及统一的查询路由能力,在统一SQL代理Kyuubi的帮助下,我们也支持多种查询引擎,例如OLAP引擎Presto,用于支持大查询的Spark SQL,以及对于特定业务有低延迟需求的Doris查询引擎等。
在数据开发中主要会遇到安全和质量这两大挑战,首先是安全问题,在数据安全的要求之下,数据隔离的需求是越发强烈的。
由于小米是一家国际化的企业,为了满足全集团的数据开发需求,在进行数据隔离架构设计时,需要同时考虑国内和海外的政策规范,例如国内的数据安全法,个人信息保护法,海外的通用数据保护条例,这些相关的法律法规,不仅强调国家的数据主权,而且也强调对个人隐私数据的保护。对于整个数据平台的影响和挑战,主要包含三个方面,第一是区域隔离,禁止跨区域访问数据;第二是角色隔离,在部分场景下会区分开发和运维的角色;第三是隐私数据的隔离,开发人员只能访问脱敏后的数据。
另外一个问题就是质量方面的挑战,以小米集团统一数仓建设为例,集团数仓支撑研产供、销服、IoT、手机等多个业务线,业务复杂度较高,交付压力也比较大。与此同时也产生了一些数据质量的问题,例如起夜率居高不下,其中问题主要原因之一就是缺少生产与开发环境的隔离,这里面的问题主要包含两个方面,一是测试流程的缺失,例如代码测试不充分,Code Review环节缺失,二是测试流程不规范,例如测试流程污染线上数据,测试代码被误发布至线上。
其实上述这些问题的本质是缺乏生产环境隔离的统一产品化方案,不同的团队其实是有不同的隔离诉求的,例如有的团队不需要隔离,有的团队是直接基于线上分区进行隔离,还有基于表的隔离。整个生产环境隔离的产品化方案的目标是希望能够通过一套方案解决多场景的需求,同时满足用户的个性化以及高质量的需求。
接下来讲述一下关于数据开发生产环境隔离的技术思考和选型。
02
技术思考及选型
整个开发生产环境方面有三大目标,即数据隔离、规范流程和提升效率。数据隔离主要是指聚焦离线的数据开发场景,实现用户无感的一套隔离方案。规范流程主要是设计一套开发生产流程,提供一套产品化支撑,并且能够去覆盖整个集团的业务场景。提升效率主要是能够去完善在线化的开发调试流程,提供交互式开发体验,提升开发效率。
下面介绍数据隔离方案的对比,业内常见的两种隔离方案主要是物理隔离和逻辑隔离,具体如下图所示:
物理隔离的本质是底层存在两套不同的集群,分别是测试集群和生产集群,研发人员在测试集群上进行代码的开发以及数据的读写,经过上线以后才发布到生产集群,整个过程中开发人员无法接触到线上数据,如果要进行测试数据的构建,可能需要通过采样、脱敏、仿真等方式去生成数据。
逻辑隔离的核心是底层只有一套集群即整个生产环境的物理集群,只不过是进行了测试库和生产库的逻辑划分。这套方案对于开发人员而言其实是聚焦于写数据的隔离,不限制对线上数据的读操作,经过发布上线以后,所有的读写操作都在生产库上进行。
为了得到一套比较严格、比较完善的数据隔离方案,首先进行物理隔离方案的评估。
在评估中发现,物理隔离方案存在如下不足:
1.业务灵活性
物理隔离其实是屏蔽了所有对数据的访问,对于一些低资产、低安全的一些表数据来说,其实是没有必要的。
2.代码可复用性
前文已经提到小米的数据源种类繁多,多数据源其实对于集群的维护是比较困难的,对于多数据源的替换,难度也比较高,上线负担比较重,代码的可复用性其实是不够的。
3.测试数据可维护性
如果要做离线数据开发,一般来说业务会采取局部测试方案,也即需要按需去进行上游表的梳理,对于上游表的这些测试表的同步以及数据同步,其实工作是比较复杂的,由于这些数据是从线上同步过来的,对于这些数据在测试环境的权限管控也会带来新的问题。由于这些数据是线上数据,通常数据量都比较大,对于测试数据本身的生命周期管控也是比较繁琐的,综合来看,业务的维护意愿其实并不强,比较难以落地。
而对于逻辑隔离方案,业内通常是会采用库表来进行隔离,以下图上半部分所示的SQL脚本为例,通常在SQL脚本中会包含多个读表和一个写表,对于图中所示的这条SQL只是指定了表名,并没有去指定库名。库名可以通过整个SQL脚本的上下文来决定,例如通过连接信息去指定到底采用什么库名,通过上下文的替换,就可以完成一套代码开发生产环境的数据隔离,并不需要任何的产品化的支撑。
但是小米的实际应用场景是多存储引擎下的联邦查询,如下图所示,在存储引擎方面支持Hive、Iceberg以及Doris,同时在计算引擎上也支持了这样的联邦查询能力,即在SQL中或者元数据坐标上,采用了catalog.db.table的形式,所以业务如果要想去使用联邦查询,就需要使用完整的三级结构,无法通过上下文来去进行库表的切换。
下面看一个具体的示例,如果要将Hive数据写入Iceberg表,那么需要去定义完整的结构,解决方案是在SQL中引入命名环境变量,这个命名环境变量在不同的环境下会做不同的解析,例如在开发环境中会解析为生产库名加上dev,即phone_dev,如下图所示:
前文介绍了如何去实现数据隔离,下面进一步讲述如何去实现产品化方案。由于所有的操作其实都是在生产集群上运行的,用户如何能感知到哪些环境是属于开发环境,哪些环境是属于生产环境?这个问题其实有如下背景数据工场过去的定位是一个生产调度平台,其中的作业属性只有调度和未调度两个状态,很难区分什么场景下需要提交到开发或者生产环境,我们需要对作业的状态以及运行场景去做更精细化、更精准的定义,例如作业版本会细分为开发版本和上线版本,同时作业的运行场景也会做进一步细化,拆分成调试和调度运行以及回溯,那么这些场景分别对应开发环境以及生产环境。
有了基本的环境区分,还需要进一步完善流程的上设计。整个开发流程中引入了审核人角色,开发者需要完成数据开发与测试过程,审核人进行代码以及上线的审批。审批通过后,离线作业自动上线生效。
虽然关键技术方案和产品架构已经完善了,但我们也同样需要关注引入上线流程后的开发效率问题。开发效率细分的话,可以分为下图所示的开发效率、协作效率和代码审核的效率三个方面。
首先是开发效率:比如测试表的生成,如果业务想要去基于作业去做批量的测试表生成,支持按照血缘进行提取;并且也支持对于隐私数据的脱敏以及抽样。其次对于协作而言:由于支持上下线的概念,可以在下线时提供影响分析,从而降低用户下线的负担;还有一些业务的工作流非常庞大,协作比较困难,我们也提供了工作流草稿锁定的能力。最后是代码审核的效率:支持了常规的版本比对,还有智能检查的能力(例如SQL静态扫描,是否做过冒烟测试等,通过这些检查项对用户上线的过程进行阻断,来降低审核人的审批负担)。
接下来介绍产品的整个落地路径,相对技术架构而言,落地的挑战也是非常大的。
03
落地路径
前文讲到整个产品是从一个生产调度平台逐步演进为一个开发在线化平台,整个平台的产品体验以及代码流程、开发流程都有比较大的改造,为了保证产品开发过程中每个阶段都能及时获得用户反馈并取得阶段性成果,于是采用了MVP(最小化可行产品)的研发方式,具体分为下图所示的五期进行,每期都会完成最小可行的一个能力。
首先是版本比对,其中包括代码比对,还有一些不能抽象为代码的表单的比对。然后是最小化引入开发流程,即通过多版本工作流,基于最新版本实现草稿版本,基于启用版本实现上线版本。在数据隔离方面前文也已经介绍到,通过命名环境变量来实现对于不同环境的解析。上线流程方面主要是与审批流程的对接,以及审批环节进行Code Review。最后是智能检查,具体包括SQL静态扫描、血缘依赖检查以及自测流程检查等。在整个落地过程中,还有一个比较重要的点即引入新的开发流程时,应同时考虑提供相应的工具以及技术去支撑,以提高工作效率,避免数据研发对新流程产生抵触情绪。
接下来介绍一下整个产品的推广路径,实际中采取了灰度上线的方案。整个项目的灵感是来自于集团数仓,主要原因是很难在短时间内就开发流程和规范达成全集团统一,时间上也不允许,具体如下图所示:
为了解决上述问题,把这些功能分成了两个部分,第一个部分是针对一些增量功能,其并不影响流程,对于这些功能会去做全面的上线。另一部分是一些新增概念,其影响或者改变了业务流程,针对这些功能,会在集团数仓团队内去进行验证,当验证通过以后,逐步扩大灰度的范围。
数据安全方面,可分为下图所示的三步去逐步完善整个数据安全的能力。
前文介绍了开发和生产环境,针对开发和生产环境可以去做更细粒度的权限管控。例如在开发环境中完全可以使用个人账号,即权限控制到个人,而对于生产环境则使用空间账号,可以理解为组账号,这种情况下人员的任何变动不会影响整个生产可用性。生产和开发账号隔离,可以进一步去做高等级表读写权限限制到个人,依赖对数据高敏高密级别手动和自动打标的能力。由于高敏和高密级数据能够限制到个人,最终实现了人加场的权限控制。最后就是针对隐私数据,或者是对数据安全要求非常高的些场景,目前也支持对于高敏感的数据的脱敏。如何去实现高敏感的数据的脱敏,首先需要组织层面的支撑,例如数据开发和运维角色的分离,只有运维角色能够去接触并且申请到线上隐私数据的权限,并且构建脱敏的测试表,这样开发人员就完全与隐私数据产生了隔离。
下面介绍交互式开发的内容,前文提到整个数据平台,其定位是偏生产调度的平台,业务通常没有在数据平台上进行开发的习惯。
例如,一般用户可能会通过跳板机进行开发,高级用户可能会使用数据查询来进行一些开发。
随着开发流程逐渐转移到数据平台上之后,一些交互体验不佳的问题也开始浮出水面。最常见的问题是在开发试运行的阶段缺乏交互式反馈。导致这个问题的原因是调度器的工作机制,无论是调度执行还是手动触发,这些过程都是经过调度器的,调度器本身是异步触发的机制,并不具备交互式反馈的能力。另外调度器本身会经过多检查以及多执行环节,每个环节都会进行排队检查,去做调度的削峰填谷。整体延迟也会达到分钟级别,分钟级别在调度场景下可能用户还能接受,但在开发场景下其实就难以忍受了。解决上述问题相对也比较简单,最终解决方案是抽象出一个新的执行层,会将整个试运行阶段直接提交到执行层,这样延迟会更低。另外执行层本身也会发布一些像状态变更以及日志输出这样的事件,供数据平台去做一些订阅,从而去实现及时的交互反馈。
最后来看一下开发生产环境的能力全景图,为了进一步提升开发效率和用户体验,最终是以WebIDE为终态去做演进,具体如下图所示:
基于小米数据开发的现状,要从以下三个方面进行改进。
1.代码调试
首先最重要的,也是目前正在着力去改善的,就是代码调试的体验。前文已经介绍了作业试跑,除此之外,其实还有一些更细粒度的测试需求,例如SQL片段化执行,另外还有像Spark JAR、PySpark等一些作业,这些作业一般都会经过编译打包的过程,平台也会去支持这种多语言的解释运行去提供相对更细粒度的调试能力。最后是基于像数据探查以及数据质量的能力,去完善自动化测试的过程。
2.代码编辑器
代码编辑器方面,对于普通用户来讲,语法的校验和代码补全都是必备的能力,如果一个项目变得非常庞大以后,对于文件管理,全局搜索以及代码重构,都是需要去做进一步完善的。
3.团队协作
随着项目的变大,组织也会变得逐步庞大,除了版本管理之外,还要去逐步地完成协同编辑的能力。
接下来简单做一个整体产品落地的经验总结:
- 首先是与调度器解耦,如果考虑要完善数据平台的开发过程的话,应该尽早与调度器解耦,一方面平台本身的迭代受限于调度器自身的能力,另一方面调度器其实并不适合去做频繁的更新迭代。
- 其次逻辑隔离并不一定完全适用于实时开发,和离线数据开发不同,实时数据开发测试需要考虑资源的隔离,如果资源隔离的比重比较重,那么最佳实践是物理隔离。
- 最后是存量历史作业环境变量的替换,这个是比较依赖SQL解析以及改写的能力,目前是提供了一些脚本化工具,未来可以集成到自动化测试环节之中。
下面分析一下实时作业如何去做隔离,其实目前业务方面既有逻辑隔离又有物理隔离的实践。逻辑隔离是基于线上流式数据源的采样去构建测试链路的,例如用户行为日志和CDC数据源等,都是可以去做采样的。物理隔离其实比较依赖完备的测试数据源,可以通过测试或者仿真设备上报日志,从而去构建全链路的测试环境。未来规划是希望能够复用逻辑隔离的方案,大概的思路是像Flink SQL这样的无限流转换成有限流,这样整个测试过程都是离线的,实现了实时离线开发环境产品化方案统计。
04
业务实践
最后介绍一下小米业务的实践。
下图所示是开发生产环境的使用情况,首先是应用情况,大概90%的业务使用了生产环境隔离,有20%的业务使用了最强或者说最严格的数据隔离方案。整个流程上线也积累了差不多7万次的上线审批测试,测试表的总数量也超过了4500张。
通过相关数据反馈可以看出,在通过全面推广开发生产环境隔离以后,集团数仓因为流程不规范导致的起夜次数是大幅度降低的。如下图所示:
另外可配置化的开发生产环境中包含了比较多的配置项,为了满足不同团队的上线质量要求,例如对于生产表到底要不要去做严格的禁止写入,以及自身智能检查是否去做阻断,还有发布上线是否去做审批,具体如下图所示:
最后是业务的实践案例,小米集团中像集团数仓和国际业务等业务方都基于生产开发环境制定了各自的上线协作流程规范,如下图所示:
05
Q&A
Q1:贵司在协同开发和版本管理方面,有没有就Git能力去做打通或者管理?
A:这个问题其实是有一些权衡的。如果我们用Git的方式去做打通的话,其实还是会受限于Git本身的能力。例如Git本身还是倾向于对文件的版本的管理,但是对于开发平台而言,其中的作业类型多种多样,不仅仅包含了代码,还有更多的像一些可配置项甚至还有一些低代码的开发过程。那么对于这些过程,如果通过Git,将所有的作业类型转换成代码的形式再去做统一的版本管理,难度是非常大的。我们的版本管理实际上就是作业的快照,在版本比对环节,将所有的作业属性抽象为代码和表单两种类型,最后在前端实现这两类属性的比对。
Q2:今天分享讲到两种思路,即物理隔离和逻辑隔离,如果说确实是要求开发环境和生产环境去做物理隔离,而不是选择这种逻辑隔离的话,有没有什么思路?
A:这个问题其实还是基于整个公司的现状来决定的。首先需要考虑整个公司本身对于数据安全的敏感程度,例如金融行业。那么可能对于我们的开发人员其实不希望能直接接触到线上的数据,在这种情况下我们其实会舍弃一些开发的效率来去换取绝对的数据安全。对于另外一些场景,其实很多时候有大量的数据分析师、数据开发者,那么对于我们整个开发流程而言,是需要去对于很多的线上数据去做验证,这种过程其实是需要用到一些线上的真实数据,在这种情况下其实就不再适合于去使用生产环境的隔离,即物理的隔离。如果确定要实现这样的物理隔离的话,其实技术思路也比较容易,今天的分享中介绍到业内的一个方案,其实它本身对于平台化的诉求并不高,本质上说一套代码,通过上下文的切换去实现我们对于不同环境的这种切换,开发环境从数据源开始构建,完善整个测试数据的全链路。
分享嘉宾
INTRODUCTION
崔博雯
小米
高级研发工程师
10年研发经验,4年大数据平台研发经验,曾负责经营数据分析平台“XDATA”产品研发,广受业务好评;现负责集团一站式数据开发平台“数据工场”。
往期推荐
B站大数据开发治理平台的产品设计心得
如何建设一个良好的可观测性数据平台直击企业痛点?
在大型项目中,抖音集团如何“用活”数据?
【他山之石】360 多兴趣召回 Mind 实战优化
蚂蚁 TuGraph-DB 数据库查询引擎技术
如何将知识图谱与AIGC结合?京东是这么做的
如何使用 JIT 技术实现高效的数据库表达式求值
Alluxio 在网易大数据的应用与优化实践
数据集成产品的技术演进与实际应用-FastData DCT
点个在看你最好看