MaxCompute Bloomfilter index 在蚂蚁安全溯源场景大规模点查询的最佳实践
业务背景
应急溯源是数据安全的最后一道防线,当出现疑似数据泄露的事件时,必须第一时间展开全面准确的排查,并且快速的组织和同步排查的结果,才能为后续事件的妥善处置和报告争取最大空间。
针对疑似泄露的样本数据,和域内各种数据进行关联,确认样本数据是否为泄露的数据,分析泄露源(如生态商家等),及时进行处置并提供答复口径。 过程中的挑战在于溯源需要扫描数据(如:网关日志、流量数据等),数据规模在 PB 级别,查询时间分区往往也较多,超过 30+。
业务痛点
业务调研中发现,流量溯源明细表以及 OSS 日志表的查询是应急溯源常用场景,经常会出现慢 SQL,查询计算资源消耗大等痛点。现有的优化方案主要基于以下两个方式:
1、基于 Hash cluster/Range cluster 进行聚簇:在等值查询时,将查询 Key 分为 256~4096 个桶,利用桶裁剪的能力减少查询数据量;
2、基于二级索引表加速:针对一个表存在多种查询诉求(如 OSS 日志表既需要按照 Access_key 又需要按照 IP 查询),增加二级表将 IP 映射到 hash key 的方式,两层表均通过 Hash cluster/Range cluster 来查询加速。
两种方式各有其弊端,对于方式一,Cluster by 的一两个字段查询表现较好,但无法提效其他字段查询效率;而二级索引表会消耗大量额外的存储空间, 每个二级索引表会占用几十 TB 到几百 TB 之间,带来额外的存储成本。
MaxCompute Bloomfilter index 介绍
布隆过滤器(Bloomfilter)是一种高效的概率型数据结构,MaxCompute 在 11 月最新版本中全新上线了 Bloomfilter index 能力 文档链接,针对大规模数据点查场景,支持更细粒度的数据裁剪,减少查询过程中不必要的数据扫描,从而提高整体的查询效率和性能。
大规模点查场景
大规模点查是一种常见的数仓使用场景,通常会通过指定不定列的值对大量数据进行检索,得到条件匹配的结果。MaxCompute 是一个 EB 级的数据仓库解决方案,存储了集团内外的海量数据。在 MaxCompute 上不仅仅运行了大量的 ETL 作业,也运行了不少点查任务如:
查询某个用户最近一周的外卖记录
查询最近一周新注册的用户在母婴类的查询记录
查询手机号为 xxx 的用户信息
以下是一个点查的典型例子:
在这些情况下用户都会有这样一个疑惑:我查询的目标数据只有几条,但是为什么在 MaxCompute 中却需要大量的资源,并且需要相当长的计算时间才能得到结果?这是因为在这些情况下虽然会有谓词下推到存储层做过滤,但是由于以下原因仍可能读大量数据及消耗大量资源以便找出符合条件的数据:
过滤依赖于文件中保存的列的 min/max 值,数据分散的情况下,谓词下推后过滤效果不佳,甚至无法过滤任何数据
仍需按照表或者分区的全量数据申请资源
当前聚簇方式的痛点
在 MaxCompute 中支持 Hash Clustering 和 Range Clustering 两种聚簇索引(Clustered Index)。这两种索引会把数据按照指定的字段(称为 cluster key)分散到不同的桶里面,桶与桶之间没有数据重叠,并且桶内部也会根据指定的字段进行排序。在查询时,将 Clustering Key 作为过滤条件,这样可以快速排除掉不需要读取的分桶,在分桶内也可以过滤掉不需要读取的数据,加快查询速度。但是聚簇表在以下几方面仍有不足:
对于 Hash 聚簇表,只有当查询条件包含了所有的 Clustering Key 之后才能进行数据过滤;对于 Range 聚簇表,只有当查询条件中包含了 Clustering Key 的前缀过滤条件,并且按照 Clustering Key 的顺序从左到右进行匹配时,才能有较好的过滤效果,如果不包含前缀过滤条件则效果不佳。
如果查询条件不包含 Clustering Key 则没有过滤效果,因而对于查询无固定条件的表来说,聚簇表可能无效。
数据写入时需要按照指定的字段进行 Shuffle,会导致成本增加,如果遇到个别倾斜的 Key,会导致任务长尾。
MaxCompute Bloomfilter 能力优势
点查本质上是检索某一个元素是否存在于一个集合中。不同于数据库中的索引(如 BTree、RTree 等)用来具体定位到某一行记录,大数据下基于索引构建、维护代价的考虑,更多的是引入更轻量级的索引,而空间效率和查询效率都非常高的 Bloomfilter 很适合在点查场景进行文件的裁剪,在数据库以及数据湖技术中均广凡引入 Bloomfilter index,以便支持更细粒度的数据或文件裁剪。
Bloomfilter index 的本质就是对指定的列生成 bloomfilter,然后存储起来,供系统来判断值是否会在对应的集合里命中。相对聚簇表,Bloomfilter index 的优势如下:
高效,插入和查询操作的资源消耗都比普通索引低,能以极小的代价过滤无效数据;
在高基数、数据分布紧凑的场景下有很好的过滤效果;
扩展性高,可以对表的一列或者多列建立 BF 索引,且可以和聚簇索引配合使用,即可以对非 Clustering Key 建立 Bloomfilter 索引。
蚂蚁安全溯源最佳实践
测试环境
主要包含以下两张业务表:
1、大规模等值测试-流量溯源明细表:Tracing 表的 si_value 列存放的是用户敏感值,比如手机号、id。溯源场景中存在泄露风险的数据也是敏感信息,通过 Tracing 表的 si_value 字段,就可以查到该敏感值所有访问记录。
2、热点值查询-OSS 日志表:OSS 日志表的 Access_id 是应用的访问 key,一般 AK 泄露场景时会把某个 Access_id 的所有请求 OSS 的日志捞出来,然后分析 AK 是否被某个应用泄露。
使用示例
执行情况
在 Logview 中可以看到,inputs 部分 test_oss_backend_hi_1_bf 为 Bloomfilter 虚拟表,其中包含 4096 个记录数代表源表中包含 4096 个文件,3606471214 bytes 为 Bloomfilter 虚拟表大小。
Job1 M1 过程从 Bloomfilter 虚拟表的 4096 个记录中筛选出 891 条记录,即经过 Bloomfilter index 过滤后,源表中仅有 891 个文件符合条件;随后将其作为 Job2 M1 的输入,这 891 个过滤出来的文件对应源表 test_oss_backend_hi_1 中的 9500000 (13341193497 bytes)条记录,最终从这些记录中筛选出精准的 1024 条数据。
测试结果对比
方案 1:源表 + 二级索引方案
方案 2:源表 + Bloomfilter Index 方案
测试结果表明:Bloomfilter index 可以替代二级索引表,整体存储有 45%+下降,Bloomfilter index 在单热点值查询中计算耗时都是表现最佳的。
虽然 Bloomfilter Index 构建后会占用额外的存储空间,这部分计量按普通存储收费。从下表中可以看到改造到方案 2 后带来的整体存储和计算 CU 减少:
总结
MaxCompute 作为阿里自主研发的具有业界领先水平的分布式大数据处理平台, 尤其在集团内部得到广泛应用,支撑了多个 BU 的核心业务。 MaxCompute 在致力于提升 SQL 语言的用户体验和表达能力的同时,也在持续进行性能优化,并推出更多的功能提高广大 ODPS 客户的生产力和生产效率。
在蚂蚁安全溯源的大规模点查场景,基于传统聚簇方式与二级索引方式,均无法很好的解决业务查询效率与成本问题,通过 MaxCompute 全新引入的轻量级 Bloomfilter index 能力,提供了更高的空间效率和查询效率,不仅降低了业务的查询耗时,也避免了构建二级索引带来的大量存储消耗,为业务限制降低了成本。
更多 Bloomfilter Index 使用说明详见官网产品文档:文档链接
评论