湖仓一体(data lakehouse)融合了数据仓库的高性能、实时性以及数据湖的低成本、灵活性等优势,帮助用户更加便捷地满足各种数据处理分析的需求。在过去多个版本中,apache doris 持续加深与数据湖的融合,已演进出一套成熟的湖仓一体解决方案。
为便于用户快速入门,我们将通过系列文章介绍 apache doris 与各类主流数据湖格式及存储系统的湖仓一体架构搭建指南,包括 hudi、iceberg、paimon、oss、delta lake、kudu、bigquery 等。目前,我们已经发布了 apache doris + apache hudi 快速搭建指南|lakehouse 使用手册(一),通过此文你可了解到在 docker 环境下,如何快速搭建 apache doris + apache hudi 的测试及演示环境。
本文我们将再续前言,为大家介绍 lakehouse 使用手册(二)之 apache doris + apache paimon 搭建指南。
apache doris + apache paimon
apache paimon 是一种数据湖格式,并创新性地将数据湖格式和 lsm 结构的优势相结合,成功将高效的实时流更新能力引入数据湖架构中,这使得 paimon 能够实现数据的高效管理和实时分析,为构建实时湖仓架构提供了强大的支撑。
为了充分发挥 paimon 的能力,提高对 paimon 数据的查询效率,apache doris 对 paimon 的多项最新特性提供了原生支持:
- 支持 hive metastore、filesystem 等多种类型的 paimon catalog。
- 原生支持 paimon 0.6 版本发布的 primary key table read optimized 功能。
- 原生支持 paimon 0.8 版本发布的 primary key table deletion vector 功能。
基于 apache doris 的高性能查询引擎和 apache paimon 高效的实时流更新能力,用户可以实现:
- 数据实时入湖: 借助 paimon 的 lsm-tree 模型,数据入湖的时效性可以降低到分钟级;同时,paimon 支持包括聚合、去重、部分列更新在内的多种数据更新能力,使得数据流动更加灵活高效。
- 高性能数据处理分析: paimon 所提供的 append only table、read optimized、deletion vector 等技术,可与 doris 强大的查询引擎对接,实现湖上数据的快速查询及分析响应。
未来 apache doris 将会逐步支持包括 time travel、增量数据读取在内的 apache paimon 更多高级特性,共同构建统一、高性能、实时的湖仓平台。
本文将会再 docker 环境中,为读者讲解如何快速搭建 apache doris + apache paimon 测试 & 演示环境,并展示各功能的使用操作。
使用指南
本文涉及脚本&代码从该地址获取:https://github.com/apache/doris/tree/master/samples/datalake/iceberg_and_paimon
01 环境准备
本文示例采用 docker compose 部署,组件及版本号如下:
02 环境部署
1. 启动所有组件
bash ./start_all.sh
2. 启动后,可以使用如下脚本,登陆 flink 命令行或 doris 命令行:
bash ./start_flink_client.sh
bash ./start_doris_client.sh
03 数据准备
首先登陆 flink 命令行后,可以看到一张预构建的表。表中已经包含一些数据,我们可以通过 flink sql 进行查看。
flink sql> use paimon.db_paimon;
[info] execute statement succeed.
flink sql> show tables;
+------------+
| table name |
+------------+
| customer |
+------------+
1 row in set
flink sql> show create table customer;
+------------------------------------------------------------------------+
| result |
+------------------------------------------------------------------------+
| create table `paimon`.`db_paimon`.`customer` (
`c_custkey` int not null,
`c_name` varchar(25),
`c_address` varchar(40),
`c_nationkey` int not null,
`c_phone` char(15),
`c_acctbal` decimal(12, 2),
`c_mktsegment` char(10),
`c_comment` varchar(117),
constraint `pk_c_custkey_c_nationkey` primary key (`c_custkey`, `c_nationkey`) not enforced
) partitioned by (`c_nationkey`)
with (
'bucket' = '1',
'path' = 's3://warehouse/wh/db_paimon.db/customer',
'deletion-vectors.enabled' = 'true'
)
|
+-------------------------------------------------------------------------+
1 row in set
flink sql> desc customer;
+--------------+----------------+-------+-----------------------------+--------+-----------+
| name | type | null | key | extras | watermark |
+--------------+----------------+-------+-----------------------------+--------+-----------+
| c_custkey | int | false | pri(c_custkey, c_nationkey) | | |
| c_name | varchar(25) | true | | | |
| c_address | varchar(40) | true | | | |
| c_nationkey | int | false | pri(c_custkey, c_nationkey) | | |
| c_phone | char(15) | true | | | |
| c_acctbal | decimal(12, 2) | true | | | |
| c_mktsegment | char(10) | true | | | |
| c_comment | varchar(117) | true | | | |
+--------------+----------------+-------+-----------------------------+--------+-----------+
8 rows in set
flink sql> select * from customer order by c_custkey limit 4;
+-----------+--------------------+--------------------------------+-------------+-----------------+-----------+--------------+--------------------------------+
| c_custkey | c_name | c_address | c_nationkey | c_phone | c_acctbal | c_mktsegment | c_comment |
+-----------+--------------------+--------------------------------+-------------+-----------------+-----------+--------------+--------------------------------+
| 1 | customer#000000001 | ivhziaperb ot,c,e | 15 | 25-989-741-2988 | 711.56 | building | to the even, regular platel... |
| 2 | customer#000000002 | xstf4,ncwdvawne6tegvwfmrchlxak | 13 | 23-768-687-3665 | 121.65 | automobile | l accounts. blithely ironic... |
| 3 | customer#000000003 | mg9kdtd2wbhm | 1 | 11-719-748-3364 | 7498.12 | automobile | deposits eat slyly ironic,... |
| 32 | customer#000000032 | jd2xzzi umid,dctnblxkj9q0tl... | 15 | 25-430-914-2194 | 3471.53 | building | cial ideas. final, furious ... |
+-----------+--------------------+--------------------------------+-------------+-----------------+-----------+--------------+--------------------------------+
4 rows in set
04 数据查询
如下所示,doris 集群中已经创建了名为paimon
的 catalog(可通过 show catalogs
查看)。以下为该 catalog 的创建语句:
-- 已创建,无需执行
create catalog `paimon` properties (
"type" = "paimon",
"warehouse" = "s3://warehouse/wh/",
"s3.endpoint"="http://minio:9000",
"s3.access_key"="admin",
"s3.secret_key"="password",
"s3.region"="us-east-1"
);
你可登录到 doris 中查询 paimon 的数据:
mysql> use paimon.db_paimon;
reading table information for completion of table and column names
you can turn off this feature to get a quicker startup with -a
database changed
mysql> show tables;
+---------------------+
| tables_in_db_paimon |
+---------------------+
| customer |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from customer order by c_custkey limit 4;
+-----------+--------------------+---------------------------------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
| c_custkey | c_name | c_address | c_nationkey | c_phone | c_acctbal | c_mktsegment | c_comment |
+-----------+--------------------+---------------------------------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
| 1 | customer#000000001 | ivhziaperb ot,c,e | 15 | 25-989-741-2988 | 711.56 | building | to the even, regular platelets. regular, ironic epitaphs nag e |
| 2 | customer#000000002 | xstf4,ncwdvawne6tegvwfmrchlxak | 13 | 23-768-687-3665 | 121.65 | automobile | l accounts. blithely ironic theodolites integrate boldly: caref |
| 3 | customer#000000003 | mg9kdtd2wbhm | 1 | 11-719-748-3364 | 7498.12 | automobile | deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov |
| 32 | customer#000000032 | jd2xzzi umid,dctnblxkj9q0tlp2iq6zco3j | 15 | 25-430-914-2194 | 3471.53 | building | cial ideas. final, furious requests across the e |
+-----------+--------------------+---------------------------------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
4 rows in set (1.89 sec)
05 读取增量数据
我们可以通过 flink sql 更新 paimon 表中的数据:
flink sql> update customer set c_address='c_address_update' where c_nationkey = 1;
[info] submitting sql update statement to the cluster...
[info] sql update statement has been successfully submitted to the cluster:
job id: ff838b7b778a94396b332b0d93c8f7ac
等 flink sql 执行完毕后,在 doris 中可直接查看到最新的数据:
mysql> select * from customer where c_nationkey=1 limit 2;
+-----------+--------------------+-----------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
| c_custkey | c_name | c_address | c_nationkey | c_phone | c_acctbal | c_mktsegment | c_comment |
+-----------+--------------------+-----------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
| 3 | customer#000000003 | c_address_update | 1 | 11-719-748-3364 | 7498.12 | automobile | deposits eat slyly ironic, even instructions. express foxes detect slyly. blithely even accounts abov |
| 513 | customer#000000513 | c_address_update | 1 | 11-861-303-6887 | 955.37 | household | press along the quickly regular instructions. regular requests against the carefully ironic s |
+-----------+--------------------+-----------------+-------------+-----------------+-----------+--------------+--------------------------------------------------------------------------------------------------------+
2 rows in set (0.19 sec)
benchmark
我们在 paimon(0.8)版本的 tpcds 1000 数据集上进行了简单的测试,分别使用了 apache doris 2.1.5 版本和 trino 422 版本,均开启 primary key table read optimized 功能。
从测试结果可以看到,doris 在标准静态测试集上的平均查询性能是 trino 的 3 -5 倍,后续我们将针对 deletion vector 进行优化,进一步提升真实业务场景下的查询效率。
查询优化
对于基线数据来说,apache paimon 在 0.6 版本中引入 primary key table read optimized 功能后,使得查询引擎可以直接访问底层的 parquet/orc 文件,大幅提升了基线数据的读取效率。对于尚未合并的增量数据( insert、update 或 delete 所产生的数据增量)来说,可以通过 merge-on-read 的方式进行读取。此外,paimon 在 0.8 版本中还引入的 deletion vector 功能,能够进一步提升查询引擎对增量数据的读取效率。
apache doris 支持通过原生的 reader 读取 deletion vector 并进行 merge on read,我们通过 doris 的 explain
语句,来演示在一个查询中,基线数据和增量数据的查询方式。
mysql> explain verbose select * from customer where c_nationkey < 3;
+------------------------------------------------------------------------------------------------------------------------------------------------+
| explain string(nereids planner) |
+------------------------------------------------------------------------------------------------------------------------------------------------+
| ............... |
| |
| 0:vpaimon_scan_node(68) |
| table: customer |
| predicates: (c_nationkey[#3] < 3) |
| inputsplitnum=4, totalfilesize=238324, scanranges=4 |
| partition=3/0 |
| backends: |
| 10002 |
| s3://warehouse/wh/db_paimon.db/customer/c_nationkey=1/bucket-0/data-15cee5b7-1bd7-42ca-9314-56d92c62c03b-0.orc start: 0 length: 66600 |
| s3://warehouse/wh/db_paimon.db/customer/c_nationkey=1/bucket-0/data-5d50255a-2215-4010-b976-d5dc656f3444-0.orc start: 0 length: 44501 |
| s3://warehouse/wh/db_paimon.db/customer/c_nationkey=2/bucket-0/data-e98fb7ef-ec2b-4ad5-a496-713cb9481d56-0.orc start: 0 length: 64059 |
| s3://warehouse/wh/db_paimon.db/customer/c_nationkey=0/bucket-0/data-431be05d-50fa-401f-9680-d646757d0f95-0.orc start: 0 length: 63164 |
| cardinality=18751, numnodes=1 |
| pushdown agg=none |
| paimonnativereadsplits=4/4 |
| paimonsplitstats: |
| splitstat [type=native, rowcount=1542, rawfileconvertable=true, hasdeletionvector=true] |
| splitstat [type=native, rowcount=750, rawfileconvertable=true, hasdeletionvector=false] |
| splitstat [type=native, rowcount=750, rawfileconvertable=true, hasdeletionvector=false] |
| tuple ids: 0
| ............... | |
+------------------------------------------------------------------------------------------------------------------------------------------------+
67 rows in set (0.23 sec)
可以看到,对于刚才通过 flink sql 更新的表,包含 4 个分片,并且全部分片都可以通过 native reader 进行访问(paimonnativereadsplits=4/4
)。并且第一个分片的hasdeletionvector
的属性为 true
,表示该分片有对应的 deletion vector,读取时会根据 deletion vector 进行数据过滤。
结束语
以上是基于 apache doris 与 apache paimon 快速搭建测试 / 演示环境的详细指南,后续我们还将陆续推出 apache doris 与各类主流数据湖格式及存储系统构建湖仓一体架构的系列指南,包括 iceberg、oss、delta lake 等,欢迎持续关注。
发表评论