抖音集团离线数仓血缘基础能力的构建与应用

大数据关系型数据库NoSQL数据库

picture.image

本文将从底层视角来描述 血缘在离线数仓场景的具体应用 。主要内容包括以下几大部分: 背景介绍、 血缘基础能力介绍、 血缘能力在数据发现场景的应用、血缘能力在数据保护场景的应用。

picture.image

作者:朱江

火山引擎LAS大数据研发专家

01

背景介绍

picture.image

目前,企业数据建设面临着两大类问题:

第一类问题:聚焦于如何有效识别数据传输链路, 特别是在各公司离线数仓规模持续扩大的背景下。用户常遇到以下挑战:

● 首先,针对多业务线场景,需要明确某一Hive表中包含哪些业务线的数据,以及某个业务线的数据具体存储在哪些Hive表中。这要求企业具备标签识别能力,以清晰界定业务范围。

● 其次,随着离线ETL链路的延伸,敏感数据的范围也在不断扩大。因此,企业需要准确标注敏感数据的边界,并实施精确的管控措施。

● 再者,数据规模不断增多,存储成本也在持续攀升。企业需判断哪些Hive表甚至Hive列适合进行数据治理,以助力降本增效。

第二类问题:聚焦于数据保护领域。 随着安全合规要求的日益严格,保障敏感数据的安全成为每个企业都必须应对的挑战。这主要包括两方面:

● 一方面,随着ETL链路的扩展,不同业务归属的数据可能最终汇聚到同一个Hive表或列中。这时,企业需要实施更细致的权限管控,确保下游使用数据时满足权限最小化原则。

● 另一方面,对于高度敏感的场景,企业需要对查询结果进行脱敏处理。在确保隐私数据安全合规的前提下,尽可能降低用户的使用成本,使用户能够更便捷地利用这些数据。

/ 基于血缘的数据发现&保护方案

picture.image

针对上述问题,我们提出了一套 依托SQL血缘能力的数据发现与数据保护解决方案。

针对第一类数据发现问题, 首先利用表级和列级的血缘能力,构建一个涵盖所有Hive表的全局血缘关系图。

从全局血缘图谱的业务起点出发,逐层分析各节点间的SQL语义,以此传播标签信息。

最终,凭借全局标签信息,我们能够高效且精确地识别数据的使用情况和整体流动链路,进而对数据实施精细化的运营管理。

对于第二类数据保护场景, 同样依赖于表/列级别的血缘能力。

通过深入分析SQL的构成,确保在不影响计算语义的前提下,对计算结果进行精准脱敏,从而减轻对用户侧的干扰。

在权限控制层面,凭借血缘能力实现更精细的权限提取,达到行列级别的权限管控,进而完成权限最小化的操作。

02

血缘基础能力介绍

/ 什么是SQL血缘

picture.image

SQL血缘是一种用于跟踪和分析数据处理过程的技术,可以帮助我们清晰地了解数据是如何在计算链路中传递和演变的。

以上图中的SQL为例,假设有三张表:table1包含a1、a2、a3三列,table2包含b1、b2、b3三列,而table3则有c1、c2两列。

现在,我们基于这三张表构建了一个SQL查询,其中table1作为子查询t1,table2作为子查询t2,这两个子查询通过join操作连接,并将最终结果插入到table3中。

在这个查询中可以看到,table3的c1列的数据来源于table1的a2列,而c2列的数据则来源于table2的b2列。 这种列的流动关系就构成了上图所示的血缘关系图。

在这个关系图谱中,三张表通过列的流转相互关联,清晰地展示了数据是如何在这些表之间流动的。

/ 如何实现SQL血缘提取

picture.image

接下来从技术角度阐述如何从SQL中提取血缘信息。

首要步骤是对SQL进行解析和优化,这一流程会生成一个树状的执行计划结构。解析和优化的流程可以参考上图中右侧部分。

当接收到用户的SQL后,首先会进入Parser阶段,对SQL进行词法分析和语法分析,从而生成一棵抽象语法树(SqlNode结构)。

其次,进入validate模块,对语义正确性和元数据进行校验。再次,基于新的抽象语法树进行convert和optimize操作,包括一些转换和优化步骤。经过这些步骤后,我们就能得到一个最终的树状执行计划结构,如上图下方所示。

需要强调的是,在血缘追踪的场景中,优化步骤是很有必要的。 因为优化阶段会执行诸如列裁剪、常量折叠等优化规则,这些规则对于提高血缘提取的准确率和正确率有着极大的帮助。

第一步: 得到一个树状的执行计划,并基于执行计划去追踪血缘。

第二步: 取执行计划最外层每一列对应的Index下标信息,并使用这个Index下标逐层的向下检索。

在离线数仓的场景中,大部分操作都是选择一张表,将结果插入到另一张表里,因此数据的底层来源通常是另一张Hive表。在执行计划中,该Hive表对应的节点就是TableScan节点。

基于Index信息递归向下寻找,直到找到最底层的TableScan节点,在TableScan节点Index下标对应位置的列信息,就是最外层列对应的列血缘。

以上图左下角的SQL为例,具体讲解这一过程的实现。

该SQL经过解析和优化后,会形成图示的执行计划。可以看到,SQL中的每一个片段都能对应到执行计划中的一个节点。

例如,SQL的第一行insert overwrite操作在执行计划中对应一个TableModify算子,第二行和第三行的select操作对应执行计划中的Project算子。再向下是两张表的join操作,该join操作对应HashJoin算子。

join之后,t1和t2两个子查询是平级关系,join的下一层有两个平级的Project。两个子查询内部在执行计划中f分别对应Project、Filter和TableScan算子。TableScan算子就对应查询的底表信息。

拿到执行计划后,按照前文实现原理中的第二步,基于index向下寻找。

以DQL部分为例:select a2和b2对应执行计划中的Project节点,它们最终插入的是table3,因此对应的列信息是table3的c1和c2。

通过找到这一列对应的index,逐层向下递归寻找。标黄的部分是基于index寻找链路的过程,逐层寻找,最终定位到最底层的TableScan节点。

经过寻找,我们发现c1底层列来源为 table1的a2这一列,即构成血缘关系。c2的血缘同理。

/ 基于策略的多样化血缘提取能力

picture.image

前面探讨了血缘能力在底层的实现机制,通过该能力可以完成基础的表和列级别的血缘提取,满足大多数场景的需求。

但为了满足更多多样化需求, 我们团队进一步开发了基于策略的多样化血缘能力,并将其封装成SDK,以便各业务方能够更便捷地使用。

以一些典型策略场景举例子。

第一种场景为业务方不满足于列级别的血缘追踪, 在离线数仓中,业务可能会遇到一些复杂类型的数据,如Json、Map、Struct等,这些复杂类型的数据可能包含更多的信息,需要复杂类型中column key级别的血缘追踪。

为此,我们特别设计了策略来支持复杂类型column key级别的血缘提取。例如,能够追踪到某个JSON字段的血缘来源于哪个column的哪个key。

第二种场景为支持弱引用血缘的提取。 在标准的列血缘追踪中,抖音集团主要通过select链路来追踪。但实际上,列不仅被用在select语句中,还可能被用在where、group by、order by等场景中。

为了满足这些场景的需求,血缘能力也支持提取以上场景的血缘,并将其统一归结为弱引用血缘,以便下游灵活使用。

第三种场景是UDF定制化血缘。 在一些特殊情况下,例如用户使用了if表达式,如果column1大于10,则返回column2的信息,否则返回column3的信息。

在标准的列血缘追踪中,最终结果列会依赖column1、column2和column3这三个列。但在某些特殊情况下,上游业务侧可能希望更精确地追踪数据来源。

经过分析,我们发现column1在这个SQL中只作为判断条件存在,其数据并不会作为真正的结果数据存储到最终的数据表中。

因此,血缘能力配置了特定的规则,可以对此类UDF进行定制化逻辑处理,从而忽略作用在条件位置的列,实现更精准的数据来源追踪。

最后一种场景是支持统计列产出路径上的计算关系。 以上图的SQL为例:select column1, max(column2) from 一张表。

在该SQL中,column1没有经过任何计算,直接作为结果返回,因此计算关系是direct。而column2则经过了一些计算,因此计算关系是expression。通过描述这种列的计算关系,可以为下游提供更多的执行时信息。

综上所述, 我们团队开发了基于策略的多样化血缘能力能够满足不同业务的定制化需求, 为各业务方提供便捷化的使用方式。

03

血缘能力

在数据发现场景的应用

上一章节主要阐述了SQL血缘的概念、实现方式,以及在SQL血缘基础上所做的能力扩展。 接下来,将通过具体的业务场景,来展示这些能力扩展是如何在实际应用中落地的。

/ 基于血缘的标签传播能力

picture.image

前文曾提到,离线数仓中存在着海量的Hive表信息,且其存储规模还在持续扩大。为 了实现对数据的精细化运营,首先需要对每一张Hive表乃至每一个Hive列都有深入的了解, 并打上精确标签。

面对可能达到百万级、千万级的信息量,如何为这些信息打上清晰的标签成为了一个挑战。为此,我们构建了一个 全局标签传播系统。

该系统的整体思路分为以下三步:

● 第一步,提取所有的SQL任务。基于表/列级别的血缘能力,构建离线数仓的全局血缘关系图,提供数据流转的全局视角。

● 第二步,从一些信息明确的业务节点出发,这些节点包括用户已经对其有明确感知的表和列。以这些节点为根基,逐层向下扩展,通过分析每一层的SQL语义,利用SQL语义进行标签的传播,从而完成全局标签的扩展。

● 第三步,基于已经获取的全局标签信息,识别数据的使用情况及整体的流动链路。

综上所述,构建全局标签传播系统,能够有效地为海量Hive表及Hive列打上精确的标签,进而实现对数据的精细化运营与管控。

下面从技术层面详细阐述上述三步的具体实施方法。

/ 构造全局血缘图

picture.image

第一步,构建全局血缘图。 这一阶段的首要任务是收集离线数仓中所有的SQL任务。得益于之前提到的SQL血缘提取能力,能够对这些SQL任务进行血缘信息提取。

完成血缘信息的提取后,再将这些信息导入到一个图数据库中。在这个数据库中,无论是表还是列,都被视为一个顶点。

由于表和表之间、列和列之间,甚至表和列之间都存在依赖关系,因此它们之间会有边进行连接。这些顶点和边共同构成了一个全局的Hive资源血缘图。

以上图右侧给出的简单示例为例,可以清晰地看到,在图数据库中,各个表和列通过边相互连接,形成了一个完整的血缘关系网络。 这个全局血缘图提供了离线数仓中数据流转的直观视图,为后续的数据管理和运营奠定了坚实的基础。

/ 逐层分析SQL语意

picture.image

在已经获取全局血缘图信息的基础上,接下来依据业务的初始标记点进行逐层扩散,以实现标签的传播。

这一过程具体分为以下几个关键步骤。

首先,确定一个业务根节点,即业务上具有明确认知和清晰标签的节点。其次,利用全局血缘图,轻松获取到该根节点所有的一级下游信息。

其次,深入分析根节点与一级下游之间的SQL语义,从而确定一级下游的标签情况。以表的标签传播为例,假设TableA是业务根节点,带有APP和event两个标签。当TableA的数据流转到下游表时,根据SQL的语义来判断标签的变化情况。

比如,如果TableA到TableB的流转过程中进行了裁剪和filter操作,即可基于该操作对标签信息进行筛选和裁剪。因此,TableB可能会继承TableA的部分标签,并且这些标签的值可能会有所变化。

TableC和TableD标签也同理。

在传播过程中,需要根据每个SQL语句的具体操作来更新标签的值。比如,TableC可能只做了APP的过滤,所以APP标签会有所变化,而event标签则保持不变。而TableD如果是一个简单的数据转存操作,那么可能会继承上游的全部标签。

这样的逐层分析和标签传播可以完成从业务根节点到其下游所有表的标签传播过程。 这一方法不仅确保了标签的准确性和一致性,还为后续的数据管理和运营提供了有力的支持。

/

逐层传递标签信息

picture.image

继续沿用之前的传播规则,逐层地进行标签传播。这一传播过程将持续进行,直到新一轮的传播不再产生任何新的标记节点,这意味着已经到达了叶子节点,即下方已没有更多的Hive表可以进一步标记。

当这一时刻到来时,所有标签传播工作便宣告完成。 此时,全局中的所有Hive表都已被赋予了合适的标签语义。

这些标签的用途广泛,不仅可以用于追踪敏感资源的扩散情况,还可以作为元数据或注释传播的手段。 使用标签能够更高效地管理和运营数据资源,确保数据的准确性和合规性。

/

基于血缘的数据治理能力

picture.image

接下来,将探讨如何利用血缘关系来进行数据治理。

这一思路与之前的标签传播有相似之处,而标签传播能力在数据治理领域同样也能发挥巨大作用。

在传统的数据治理场景中,离线侧通常依赖于HDFS的访问日志来实现数据治理。由于Hive表的数据最终存储在HDFS上,通过分析HDFS的访问日志来判断哪些数据在一段时间内未被访问,并据此进行表级别或分区级别的TTL(Time To Live)治理,以降低存储压力。

然而,在实际开发过程中,我们发现即使某个分区正在被使用,也并非该分区的所有列都在被使用。

Hive表上的不同列,其生命周期可能是不同的。这就引发了一个新问题:如何为不同的列设置专属的TTL,从而减少列级的存储成本?这成为了业务侧的一个新痛点。

为了解决这个问题, 抖音集团数据引擎研发团队基于Parquet底层能力构建了一个名为“列级TTL”的功能。 这一功能可以为Hive表上的不同列配置专属的TTL,更精细地管理数据的生命周期,进一步降低存储成本,并提高数据治理的效率。

picture.image

在解决了不同列生命周期不同、需要配置列级TTL的技术难题后,依然面临着一个新的产品问题: 如何让Hive表的owner能够合理地设置每个列的生命周期,以降低使用成本。

为了解决该问题,我们引入了基于血缘的数据治理方案。该方案与之前的标签传播类似,依靠全局血缘图来实施,但关注点从表层面转移到了列层面,主要关注列的一级下游。

做法是采集每个列一级下游所有列级的最长分区使用范围

例如,如果ColumnA有四个下游使用场景,分别是ColumnB、ColumnC、ColumnD和ColumnE,我们会分析这些场景中使用的SQL语句,以确定ColumnA的最长分区使用范围。

以ColumnA和ColumnB的链路为例,如果SQL语句每次都使用最近20天的数据来计算平均值,那么ColumnA到ColumnB的最长分区使用范围就是20天。同样地,ColumnA的其它下游列也会计算出最长分区使用范围。

以上信息收集起来后,可以为ColumnA提供一个合理的TTL推荐值。

当然,这个推荐值只是基于数据使用情况的建议,用户还可以根据自己的业务场景进行调整。

总之,以上方案是帮助用户推荐一个合理的列级别TTL阈值, 以降低用户使用成本,降低存储压力。

04

血缘能力

在数据保护场景的应用

前文介绍了血缘能力在数据发现以及数据治理等场景中的应用,接下来将探讨 血缘能力在数据保护这一场景下的应用。

/

精细化提取SQL权限

一、业务背景&整体思路

picture.image

目前各公司在安全合规方面面临巨大压力,需要遵循数据权限最小化的原则来确保数据使用的规范性。

SQL作为大数据分析场景中最简单、最通用的语言之一,在离线场景中有广泛应用。为了确保SQL场景中的权限使用规范和最小化,我们必须解决SQL权限精细化管控问题。

解决方案分为两个层面:SQL解析和权限管理。

在SQL解析层面,基于血缘能力能定义了一套新的权限点提取规则,这套规则能够完成细粒度的行列级别权限点提取。

而在权限管理层面,我们支持了行列混合的权限管控,通过横向和纵向权限点的捆绑组合,将用户实际查询的资源定位到行列重叠的资源单元格上,从而实现更细粒度的资源级别权限管控。

以抖音集团为例,用户提交的SQL会首先被发送到统一的SQL处理引擎ByteQuer y上。

ByteQuery是一个统一的SQL解析和优化引擎,它基于血缘能力能够完成精准的SQL权限点提取逻辑。提取到的权限点信息会被发送到统一的权限管理服务进行鉴权。

如果用户有权限,SQL会经过优化后发送到具体的执行引擎(如Presto、Spark等)执行;如果用户没有权限,则会返回给用户提示缺少相应权限,并建议其完成对应的申请。

以具体的SQL查询为例,如果用户查询的是“select name from db.table where ID=3”,从SQL视角来看,行业普遍的权限提取可能只涉及到表级别或列级别的权限。

然而,通过深入分析用户实际数据查询的范围,我们可以发现用户实际查询的是name列和ID=3的行所构成的资源方块。

因此,无论是表级别还是列级别的管控都显得过于粗略, 资源方块级别的管控才是更优的方案。

为了实现这一目标, 抖音集团的血缘能力在权限提取侧支持了行列混合的权限提取,并在权限管控侧支持了对资源方块级别的权限管控。

通过这种方法,能够更精细地控制用户对数据的访问权限,确保数据的安全和合规性。

二、权限提取方案

picture.image

首先看看业界是如何处理权限提取问题的。

以Apache Hive为例,在SQL解析的过程中会收集解析阶段各阶段的输入(input)和输出(output)信息。通过这些信息,Hive能够提取出SQL所使用的所有库表信息,并将这些信息作为库表的权限点。

若需要更细致的控制,Hive在优化过程中会在对应的TableScan节点上维护一个关联列(reference column),这个关联列记录了SQL查询所涉及的列信息。最终,这些信息被提取出来作为列权限使用。通过这种方法,能够完成表权限或列权限的提取。

在我们的解决方案中, 接收到用户提交的SQL语句后,首先通过ByteQuery引擎进行解析和优化,将SQL转化为执行计划, 这个过程在之前的介绍中已经提及,并展示在右侧的图中。

接下来,我们根据特定的规则从该执行计划中提取关注的特定节点。在获取这些节点后,再利用表列级别的SQL血缘能力,确定节点在底层查询中实际使用的行列信息,完成库表行列级别的权限提取。

在上述权限点提取完成后,会进行权限点的组合与匹配,以确定最终的权限验证范围。这是一个总体的概念,接下来将从库权限、库表权限、列权限和行权限这三个层面,通过更复杂的SQL语句,来详细介绍如何执行该过程。

本次举例的SQL语句包含了一个子查询T1,由两部分组成:table1和table2的数据进行了union操作,之后将union的结果与另一个子查询T2进行了join操作,最终生成了三个列。

三、库表权限提取思路

picture.image

在第一部分中,主要任务是提取SQL中所有的库表权限。

处理流程如下:首先,对SQL进行解析和优化。SQL中对表的查询操作会被映射成一个或多个TableScan节点。其次,遍历执行计划,完成所有TableScan节点的提取,由此轻松地获取到所有被查询的表的信息。

以右侧的这个SQL为例,当它被转化为执行计划后,如图所示,可以看到它包含了3个TableScan节点。通过采集这三个TableScan节点的具体信息,可以拿到库表级别的权限需求,用于后续的权限验证和授权过程。

四、列权限提取思路

picture.image

在列权限的提取过程中,首先需要定义明确的规则来确定哪些列需要进行权限验证。 目前,规则定义主要分为两类:

返回列鉴权: 对于SQL最终返回结果中的列信息,进行权限验证。以右侧的SQL为例,其最终返回结果包含三列数据,数据将直接展示给用户,必须进行权限验证。

过滤条件列鉴权: 当过滤条件为两个列相等时,可能存在通过特殊语法传递数据的情况,也需进行权限检查。

基于上述规则,整体处理流程分为三步:

获取返回列信息: 从执行计划的最外层算子中获取所有列信息,这些信息代表SQL返回结果对应的列。

提取过滤条件: 从执行计划中提取所有的Filter条件,特别是那些表示两个列相等的条件。以右侧SQL为例,倒数第二行中的“T1.column1 = T2.C2”就符合这一条件,并提取出来。

利用血缘能力确定底表列信息: 上一步提取出的列信息(如“T1.column1”)在语义上并不明确,我们无法直接知道具体代表哪个表、哪个列。基于血缘关系逐一处理上述提取的规则,就能确定每个列信息对应的底表列信息,并最终鉴别这些底表列的权限。

以右侧SQL为例,首先,查看最外层算子持有列,如“T1.column1”,并确定它需要进行权限验证。

其次,基于血缘关系查看“T1.column1”的具体数据来源,最终定位到“T1.column1”的数据来源实际上是“table1.A1”和“table2.B1”。

因此,针对“T1.column1”进行鉴别的权限应该是“table1.A1”和“table2.B1”的权限。同理,对其它列也采取相同的逻辑进行处理,最终完成所有列的权限提取。

五、行权限提取思路

picture.image

行权限的提取过程的思路与之前的列权限提取类似,主要的提取规则是关注过滤条件中列与常量相等的情况。

处理流程的前几个阶段与之前类似:

遍历执行计划: 获取执行计划中所有的过滤条件信息。

获取并分类过滤条件: 在获取到Filter条件后,并分类,特别关注那些列与常量相等的条件。以右侧的SQL为例,其最下面一行的“T1.column2 = 张三”就是一个列与常量相等的条件,满足提取规则。

靠血缘信息确定底表列: 通过血缘关系,确定“T1.column2”实际上对应的底表列信息,并针对此列进行行权限的鉴别。

对于其它类型的过滤条件,也有相应的处理策略:

两个列相等: 这种情况在列权限提取规则中已经覆盖,会按照列权限的规则进行处理。

常量和常量相等: 这种情况不涉及到任何权限校验,因为在SQL优化阶段,这种无意义的比较通常会被优化掉。

以右侧的SQL为例,提取其所有的Filter信息,并追踪列的血缘关系,最终提取到的行权限信息如图所示。

picture.image

接下来对以上提取的权限信息进行整合与组合,以便更清晰地了解每个查询所涉及的具体资源。

以右侧这个SQL为例,在table1上,它实际查询的列是A1和A2,而查询的行则满足“dt = 20230101”和“A2=zhangsan”这两个条件。同理,对于table2和table3,我们也会基于上述信息完成横向和纵向的权限信息提取。

将这些信息映射到右侧的表里(假设第一张表是table1,第二张表是table2,第三张表是table3,且它们分别有A1、A2、A3、A4、A5等列),通过横向和纵向的组合划分,可以将检索的资源精确地定位到行列交错的标注黄色的资源方块上。

通过上述操作, 我们在权限提取侧完成了最细粒度的权限提取,即资源方块级别的权限提取。 这为后续的权限管控奠定了坚实的基础。

然而,权限提取只是权限管控的一部分,只有与权限管控策略相结合,才能确保数据的安全性和合规性。

/

血缘在动态脱敏场景下的应用

picture.image

动态脱敏是保障数据安全的重要手段,它能在数据展示或传输过程中,对数据进行实时的脱敏处理,以保护隐私数据的安全。

这种能力主要有两种实现时机:计算前脱敏和计算后脱敏。

计算前脱敏: 当计算引擎读取到敏感数据时,会立即对其进行脱敏处理。这种方式相对简单,但它更接近于存储层加密。

因为一旦数据被脱敏,它就已经变成了密文,这可能会影响后续的SQL查询逻辑,如Join、Filter或UDF计算等。因此,计算前脱敏可能会对用户的SQL使用产生较大影响。

计算后脱敏: 与此相反,计算后脱敏是在计算引擎读取到敏感数据后,优先执行后续计算,而在最终返回结果前再进行脱敏处理。

这种方式实现起来更复杂,因为它需要对最终结果进行脱敏,而最终结果已经没有直接的数据来源信息。

为了实现这一点,我们需要基于SQL分析数据走向,追踪数据来源,才能做出是否需要脱敏的判断。

计算后脱敏的优点在于它对用户的影响较小,因为它并没有打破用户对SQL的语义理解,仍然完成了合理的计算后才对结果做脱敏处理。

在技术实现上,无论采用哪种脱敏时机,都需要首先解析和优化用户的SQL,将其转化为执行计划信息,再读取用户查询的表,检查表中是否配置了脱敏规则。基于脱敏配置信息来动态地改写执行计划,并在适当的位置插入脱敏算子。

picture.image

接下来,将详细介绍动态脱敏在两个具体场景中的实现方式。

计算前脱敏场景:

在计算前脱敏的场景中,脱敏操作被直接插入到TableScan节点之前。由于能够直接获取到Hive表的信息,我们可以轻易地判断哪些列需要进行脱敏处理。

以上图执行计划为例,如果我们在读取table1的A2列时,发现其被标记为敏感数据,需要脱敏处理,那么我们可以在A2列对应的TableScan算子之上,对应下标位置插入一个Masking脱敏算子。

这样,后续的Filter、Join等计算操作都会基于脱敏后的数据进行处理,从而轻松实现动态脱敏。

● 计算后脱敏场景:

与计算前脱敏不同,计算后脱敏需要将脱敏操作放置在查询的最外层算子处。此时,脱敏操作已经远离了标识Hive表信息的TableScan节点。

以某个包含C1、C2两列的SQL查询为例,我们可能无法直接判断这两列是否需要脱敏。为了解决这个问题,我们需要基于血缘信 息来追踪每一层的计算链路,并根据计算链路来判断哪些列需要脱敏处理。

这个追踪过程与前面提到的血缘追踪类似,如果我们基于血缘判断链路发现某列需要脱敏,就会在最外层对应的位置插入一个脱敏算子;如果不需要脱敏,则直接返回原始列。

如果DB.table1中的某列(标绿色)是敏感数据,操作步骤为拿到最外层算子,逐层追踪该列的血缘信息。绿色的框表示追踪范围,最终发现C1的来源是A2,且该链路上需要脱敏。

因此,在C1之上插入一个masking脱敏算子。而对于C2列,如果在追踪过程中发现其底表的依赖是非敏感资源,则不需要进行任何脱敏处理,直接返回原始列即可。

通过这种方式,我们可以在对用户SQL语义影响更小的场景下,同时完成对敏感数据的保护。这种动态脱敏的实现方式既灵活又有效,能够根据不同的业务场景和需求进行适应性调整。

往期推荐   

picture.image

picture.image

picture.image

picture.image

picture.image 点击阅读原文,了解更多

0
0
0
0
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论