数据治理

Flink 实时写入 Iceberg 带来的问题

在实时数据源源不断经过 Flink 写入的 Iceberg 的过程中,Flink 通过定时的 Checkpoint 提交 snapshot commit 操作到 Iceberg,将已写入到 Iceberg 的数据文件通过 Snapshot 组织暴露出来。如果不对流实时写入 Iceberg 的文件进行治理,久而久之 Iceberg 下的小文件会越来越多,Snapshot 版本也越来越多,查询速度大打折扣。

数据治理方案

基于上述问题,我们需要对 Iceberg 的元数据和数据文件定期进行治理。治理方向主要有俩点:

  • 清理快照
  • 合并小文件

因为我们查询引擎用 Trino,于是我们选用 Trino 对 Iceberg 进行优化。

Trino-Iceberg Connetor 提供了优化方法:

-- 清理快照
ALTER TABLE test_table EXECUTE remove_orphan_files(retention_threshold => '7d') -- 合并小文件
ALTER TABLE test_table EXECUTE optimize(file_size_threshold => '10MB')

使用 Trino SQL 便可以对 Iceberg 表进行优化,很方便。我们基于 Trino SQL 上,做了一个自动自助的 Iceberg 表优化工具,实现了定时对某个 Catalog 下的表进行优化,省去了人工运维优化的成本。

除了快照清理和合并小文件外,Trino 提供了清理无效数据的方法,可以删掉一些已经不被 Iceberg 管理的无用的数据文件。我们是每周对 Iceberg 执行一次无效数据清理。

-- 清理无效文件
ALTER TABLE test_table EXECUTE remove_orphan_files(retention_threshold => '7d')

查询加速

我们都知道对 Iceberg Partition 列进行查询速度都很快,因为其过滤掉很多文件,只读取符合查询分区的数据文件。单读到底层的 ORC 数据文件时,Iceberg 提供了 min/max 等数据元信息,通过元信息可以快速得知所找的数据是否在此文件内。

Bloom Filter

在最新的 Iceberg 1.1.0 版本中,Iceberg 支持在 ORC 数据文件内设置 bloom filters。

而新版 Trino 也跟上 Iceberg 适配 bloom filter,我们需要在 trino-iceberg 的配置文件里配置,来开启 Trino 查询时使用 bloom filter 查询

hive.orc.bloom-filters.enabled = true

除此之外,我们还需要设置 Iceberg 表属性,对列配置上 bloom filter

CREATE TABLE iceberg_table (
token_address varchar,
from_address varchar,
to_address varchar,
block_timestamp timestamp(6) with time zone,
)
WITH (
orc_bloom_filter_columns = ARRAY['token_address','from_address','to_address'],
orc_bloom_filter_fpp = 0.05,
partitioning = ARRAY['day(block_timestamp)']
)

因为 bloom filter 是生效于 ORC 文件中,如果想要应用在旧表上,需要将旧表数据重写到新表上,这样底层的数据文件才带有 bloom filter。

举例:

假如我们有一张 token_transfer 表,表内大概有四个字段

  • from_address 买方地址
  • to_address 卖家地址
  • token_address 交易代币
  • block_timestamp 日期

我们对该表 from_address、to_address、token_address 应用 bloom filter,对 timestamp 进行分区。该表每天的数据量假设有 100w 条数据。

此时有俩类查询过来:

  • 查询热门 token 今天发生的交易
select * from token_transfer
where token_address = '热门token' and block_timestamp > today
  • 查询冷门 token 今天发生的交易
select * from token_transfer
where token_address = '冷门token' and block_timestamp > today

此时俩类查询的 bloom filter 产生的效果是不一样的,因为热门的 token 会存在大部分数据文件里,冷门的 token 大概率只存在于少部分数据文件内。对于热门 token,bloom filter 的加速效果不佳,但对于冷门 token,bloom filter 帮助其快速过滤掉了很多数据文件,快速找到有冷门 token 的数据文件,加速效果极佳。

所以得到的结论是,bloom filter 对一些 不重复,特征值很高的数据有比较好的加速效果。

Order & Z-Order

上文提到,ORC数据文件内有 min/max 值,查询引擎可以根据 min/max 值判断数据是否在此文件内。

可是日常在写入 Iceberg 的数据一般都是无序写入的,无序写入会导致每个数据文件也是无序的,不能发挥 min/max 过滤的效果。

Order

Spark 提供了一个压缩文件并排序的方法,可以将无序的文件按指定列排好序。排序策略不仅可以优化文件大小,还可以对数据进行排序以对数据进行聚类以获得更好的性能。将相似数据聚集在一起的好处是更少的文件可能具有与查询相关的数据,这意味着 min/max 的好处会更大(扫描的文件越少,速度越快)。

CALL catalog.system.rewrite_data_files(
table => 'db.teams',
strategy => 'sort',
sort_order => 'team ASC NULLS LAST, name DESC NULLS FIRST'
)

Z-Order

虽然 Order 排序可以同时对多列进行排序,但其列与列之间的排序是有先后顺序之分的,像是 MySQL 里的联合索引,先对 字段A 排序再对 字段B 排序。如果只是的查询的谓词只包含 字段B,则上述索引失效(先对 字段A 排序再对 字段B 排序)。

而 Z-Order 能解决上面的问题,使用 Z-Order 对多列排序,列与列之间的排序权重相同。所以使用 Z-Order 对多字段进行排序,查询中只要谓词命中了 Z-Order 中其中任何一字段,都能加速查询。

Spark 提供了使用 Z-Order 的方法

CALL catalog.system.rewrite_data_files(
table => 'db.people',
strategy => 'sort',
sort_order => 'zorder(height_in_cm, age)'
)

差异

我们测试过对 100G 的表分别进行 Order 和 Z-Order,命中 Order 最高能带来 10 倍的性能提升,命中 Z-Order 能带来 2 倍的性能提升。粗步得到的结论是,Order 比 Z-Order 大致快 2 倍。

所以在实践应用上不能盲目选择 Z-Order,得根据这张表的热门查询SQL、字段特征、数量来做:

  • 查询字段是数据连续且范围小的,选 Order
  • 查询字段具有高基数特征,选 Z-Order
  • 频繁查询此表多个字段的,选 Z-Order,否则 Order 的性能会更好

小结

Iceberg 做了很多功夫去加速查询,本文中提到的小文件合并、快照清理、Bloom Filter、Order、Z-Order 都是为了在查询时跳过无用的文件,通过减少磁盘 IO 操作来加速查询。Trino 和 Spark 提供许多便利的方法给开发者维护治理 Iceberg;数据治理这块成本比较低,可以写好自动化脚本每天执行数据治理;查询加速这里的维护成本比较高,都是需要重写元数据和数据文件的操作,一般每月做一次重写操作。

参考文章:

Iceberg 数据治理及查询加速实践的更多相关文章

  1. Data.gov.uk电子政务云,牛津大学NIE金融大数据实验室王宁:数据治理的现状和实践

    牛津大学NIE金融大数据实验室王宁:数据治理的现状和实践 我是牛津互联网研究院的研究员,是英国开放互联网的一个主要的研究机构和相关政策制订的一个机构.今天主要给大家介绍一下英国数据治理的一些现状和实践 ...

  2. 李呈祥:bilibili在湖仓一体查询加速上的实践与探索

    导读: 本文主要介绍哔哩哔哩在数据湖与数据仓库一体架构下,探索查询加速以及索引增强的一些实践.主要内容包括: 什么是湖仓一体架构 哔哩哔哩目前的湖仓一体架构 湖仓一体架构下,数据的排序组织优化 湖仓一 ...

  3. Nebula Graph 在微众银行数据治理业务的实践

    本文为微众银行大数据平台:周可在 nMeetup 深圳场的演讲这里文字稿,演讲视频参见:B站 自我介绍下,我是微众银行大数据平台的工程师:周可,今天给大家分享一下 Nebula Graph 在微众银行 ...

  4. 好未来数据中台 Node.js BFF实践(一):基础篇

    好未来数据中台 Node.js BFF实践系列文章列表: 基础篇 实战篇(TODO) 进阶篇(TODO) 好未来数据中台的Node.js中间层从7月份开始讨论可行性,截止到9月已经支持了4个平台,其中 ...

  5. 数据治理之元数据管理的利器——Atlas入门宝典

    随着数字化转型的工作推进,数据治理的工作已经被越来越多的公司提上了日程.作为Hadoop生态最紧密的元数据管理与发现工具,Atlas在其中扮演着重要的位置.但是其官方文档不是很丰富,也不够详细.所以整 ...

  6. 火山引擎 DataLeap:3 个关键步骤,复制字节跳动一站式数据治理经验

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理. ...

  7. MySQL大数据量分页查询

    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...

  8. 一文读懂 Spring Boot、微服务架构和大数据治理三者之间的故事

    微服务架构 微服务的诞生并非偶然,它是在互联网高速发展,技术日新月异的变化以及传统架构无法适应快速变化等多重因素的推动下诞生的产物.互联网时代的产品通常有两类特点:需求变化快和用户群体庞大,在这种情况 ...

  9. 【1】MySQL大数据量分页查询方法及其优化

    ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千 ...

  10. MySQL大数据量分页查询方法及其优化

    MySQL大数据量分页查询方法及其优化   ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适 ...

随机推荐

  1. 写一个flutter程序

    这一部分我们写一个简单应用 功能是,为一个创业公司生成建议的公司名称. 用户可以选择和取消选择的名称,保存喜欢的名称. 该代码一次生成十个名称 用户滚动时,生成新一批名称. 着重体验以下几点 Flut ...

  2. 4.6:HBase操作实验

    〇.概述 1.拓扑结构 2.目标 进行Hbase实验来熟悉Hbase的基本操作. 一.基本操作 1.启动进程 16610 2.连接集群 3.常见操作

  3. Django查看内部sql语句的方式

    一:查看内部sql语句的方式 方式1(queryset对象才能够点击query查看内部的sql语句) res = models.User.objects.values_list('name', 'ag ...

  4. Jmeter 函数助手之__time

    接口中需要传入time时,可使用Jmeter 函数助手中的__time函数传入当前时间 格式和参数名称两个字段非必填,当都不填时直接点击生成按钮,得到13位时间戳:按图填写后,得到10位时间戳,获取当 ...

  5. sha1_b64_scrape

    过无限debugger:https://www.cnblogs.com/hkwJsxl/p/16702143.html 网站 aHR0cHM6Ly9hbnRpc3BpZGVyOC5zY3JhcGUuY ...

  6. 2022NewStarCTF新生赛一些比较有意思的题目wp

    Misc_蚁剑流量分析 Pcap的文件可以直接使用工具 编辑器打开目录,一个一个看,可以找到eval危险函数 看到n3wst4r,直接使用linux正则匹配,找出相关内容 Url解码,了解一下蚁剑流量 ...

  7. C语言两结构体之间的成员互换

    今天在写一个通讯录实现程序的时候,遇到个让我突然卡壳的问题,不知道怎么进行两个结构体之间的成员互换......结构体成员有"姓名","性别","年龄& ...

  8. LibreOJ 144. DFS 序 1

    题面 给一棵有根树,这棵树由编号为 \(1\dots N\) 的 \(N\) 个结点组成.根结点的编号为 \(R\).每个结点都有一个权值,结点 \(i\) 的权值为 \(v_i\). 接下来有 \( ...

  9. 使用Lighthouse更好推动项目性能优化,性能指标详解,优化方法,需要关注指标分析

    Lighthouse是什么---一种工具 Lighthouse 是一个开源的自动化工具,用来测试页面性能. 为什么要用Lighthouse----提升用户体验 Web性能可以直接影响业务指标,例如转化 ...

  10. flutter 底部滑动导航,页面滑动同时让底部导航跟着变动,除了点击还可以滑动哦~~

    实现点击以及滑动都可以切换导航的效果 核心代码 完整代码 // 输入 imrm 快速生成下面 import 'package:flutter/material.dart'; import 'Home. ...