大数据Doris之_8_数据导出
前言
Github:https://github.com/HealerJean
一、概述
数据导出功能,用于将查询结果集或者 Apache Doris 的表数据,使用指定的文件格式,写入指定的存储系统中的。
导出功能和数据备份功能有以下区别:
| 数据导出 | 数据备份 | |
|---|---|---|
| 数据最终存储位置 | HDFS、对象存储、本地文件系统 |
HDFS、对象存储 |
| 数据格式 | Parquet、ORC、CSV 等开放格式 |
Apache Doris 内部存储格式 |
| 执行速度 | 中等(需要读取数据并转换成目标数据格式) | 快速(无需解析和转换,直接上传 Apache Doris 数据文件) |
| 灵活度 | 可以通过 SQL 语句灵活定义要导出的数据 |
仅支持表级别全量备份 |
| 使用场景 | 结果集下载、不同系统之间的数据交换 | 数据备份、Apache Doris 集群间的数据迁移 |
Apache Doris 提供以下三种不同的数据导出方式:
SELECTINTOOUTFILE:支持任意SQL结果集的导出。EXPORT:支持表级别的部分或全部数据导出。MySQLDUMP:兼容MySQLDump指令的数据导出。
三种导出方式的异同点如下:
SELECT INTO OUTFILE |
EXPORT |
MySQL DUMP |
|
|---|---|---|---|
| 同步/异步 | 同步 | 异步(提交 EXPORT 任务后通过 SHOW EXPORT 命令查看任务进度) |
同步 |
支持任意 SQL |
支持 | 不支持 | 不支持 |
| 导出指定分区 | 支持 | 支持 | 不支持 |
导出指定 Tablets |
支持 | 不支持 | 不支持 |
| 并发导出 | 支持且并发高(但取决于 SQL 语句是否有 ORDER BY 等需要单机处理的算子) |
支持且并发高(支持 Tablet 粒度的并发导出) |
不支持,只能单线程导出 |
| 支持导出的数据格式 | Parquet、ORC、CSV |
Parquet、ORC、CSV |
MySQL Dump 专有格式 |
| 是否支持导出外表 | 支持 | 部分支持 | 不支持 |
是否支持导出 View |
支持 | 支持 | 支持 |
| 支持的导出位置 | S3、HDFS | S3、HDFS | LOCAL |
二、Export
Export是Doris提供的一种将数据异步导出的功能。该功能可以将用户指定的表或分区的数据,以指定的文件格式,导出到目标存储系统中,包括对象存储、HDFS或本地文件系统。Export是一个异步执行的命令,命令执行成功后,立即返回结果,用户可以通过Show Export命令查看该Export任务的详细信息。
1、适用场景
Export 适用于以下场景:
- 大数据量的单表导出、仅需简单的过滤条件。
- 需要异步提交任务的场景。
使用 Export 时需要注意以下限制:
- 当前不支持文本文件压缩格式的导出。
- 不支持
Select结果集导出
2、导出说明
1)导出数据源
EXPORT 当前支持导出以下类型的表或视图
Doris内表- Doris 逻辑视图
- External Catalog 中的表
1)导出数据存储位置
Export 目前支持导出到以下存储位置:
- 对象存储:Amazon S3、COS、OSS、OBS、Google GCS
- HDFS
3)导出文件类型
EXPORT 目前支持导出为以下文件格式:
- Parquet
- ORC
- csv
- csv_with_names
- csv_with_names_and_types
3、基本原理
Export任务的底层是执行SELECT INTO OUTFILESQL语句。
1、用户发起一个 Export 任务后,Doris 会根据 Export 要导出的表构造出一个或多个 SELECT INTO OUTFILE 执行计划,
2、随后将这些SELECT INTO OUTFILE 执行计划提交给 Doris 的 Job Schedule 任务调度器
3、Job Schedule 任务调度器会自动调度这些任务并执行。
4、实践
根据返回结果判断导出执行情况,Export 命令本质上是将任务拆分成多个 SELECT INTO OUTFILE 子句进行执行。通过 SHOW EXPORT 命令返回的结果中包含一个 Json 字符串,是一个二维数组。第一维代表 Export 并发的线程数,并发多少个线程代表并发发起了多少个 Outfile 语句。第二维代表单个 Outfile 语句的返回结果
示例中,发起了 2 个 Outfile 命令。每个命令有 4 个 Writer 并发写出。
通过调整 Export 命令属性中的 parallelism 参数,可以控制并发 Outfile 的个数,从而控制并发度。
[
[
{
"fileNumber": "1",
"totalRows": "640321",
"fileSize": "350758307",
"url": "file:///127.0.0.1/mnt/disk2/ftw/tmp/export/exp_59fd917c43874adc-9b1c3e9cd6e655be_*",
"writeTime": "17.989",
"writeSpeed": "19041.66"
},
{...},
{...},
{...}
],
[
{
"fileNumber": "1",
"totalRows": "646609",
"fileSize": "354228704",
"url": "file:///127.0.0.1/mnt/disk2/ftw/tmp/export/exp_c75b9d4b59bf4943-92eb94a7b97e46cb_*",
"writeTime": "17.249",
"writeSpeed": "20054.64"
},
{...},
{...},
{...}
]
]
三、SELECT INTO OUTFILE
SELECT INTO OUTFILE命令将SELECT部分的结果数据,以指定的文件格式导出到目标存储系统中,包括对象存储或 HDFS。
SELECT INTO OUTFILE是一个同步命令,命令返回即表示导出结束。若导出成功,会返回导出的文件数量、大小、路径等信息。若导出失败,会返回错误信息。
1、适用场景
SELECT INTO OUTFILE 适用于以下场景:
- 导出数据需要经过复杂计算逻辑的,如过滤、聚合、关联等。
- 适合需要执行同步任务的场景。
在使用 SELECT INTO OUTFILE 时需要注意以下限制:
- 不支持文本压缩格式的导出。
- 2.1 版本
pipeline引擎不支持并发导出。
2、导出说明
1)导出数据存储位置
SELECT INTO OUTFILE 目前支持导出到以下存储位置:
- 对象存储:Amazon S3、COS、OSS、OBS、Google GCS
- HDFS
2)导出文件类型
SELECT INTO OUTFILE 目前支持导出以下文件格式
- Parquet
- ORC
- csv
- csv_with_names
- csv_with_names_and_types
3)导出并发度
可以通过会话参数 enable_parallel_outfile 开启并发导出, 并发导出会利用多节点、多线程导出结果数据,以提升整体的导出效率。但并发导出可能会产生更多的文件。注意,某些查询即使打开此参数,也无法执行并发导出,如包含全局排序的查询。如果导出命令返回的行数大于 1 行,则表示开启了并发导出。
SET enable_parallel_outfile=true;
4、注意事项
-
导出数据量和导出效率:
SELECT INTO OUTFILE功能本质上是执行一个SQL查询命令。如果不开启并发导出,查询结果是由单个BE节点,单线程导出的,因此整个导出的耗时包括查询本身的耗时和最终结果集写出的耗时。开启并发导出可以降低导出的时间。 -
导出超时:导出命令的超时时间与查询的超时时间相同,如果数据量较大导致导出数据超时,可以设置会话变量
query_timeout适当的延长查询超时时间。 -
导出文件的管理:
-
Doris不会管理导出的文件,无论是导出成功的还是导出失败后残留的文件,都需要用户自行处理。另外,
SELECT INTO OUTFILE命令不会检查文件及文件路径是否存在。SELECT INTO OUTFILE是否会自动创建路径、或是否会覆盖已存在文件,完全由远端存储系统的语义决定。
-
-
如果查询的结果集为空:对于结果集为空的导出,依然会产生一个空文件。
-
文件切分:文件切分会保证一行数据完整的存储在单一文件中。因此文件的大小并不严格等于
max_file_size。 -
非可见字符的函数:对于部分输出为非可见字符的函数,如 BITMAP、HLL 类型,导出到 CSV 文件格式时输出为
\N。
5、实践
1)开启并行导出
SELECT INTO OUTFILE返回的行数即代表并行的Writer数量。Writer的数量越多,则导出的并发度越高,但写出的文件数量也会越多。如果发现只有一个Writer,则可以尝试开启并行导出功能。
SET enable_parallel_outfile=true
a、并行度计算
- 会话变量控制:
parallel_pipeline_task_num:单个BE节点的最大并行度(默认值为 单节点 CPU 核数的一半)。- 示例:若单节点 CPU 为 8 核,则
parallel_pipeline_task_num = 4。
- 集群规模扩展:
- 若查询的数据仅位于部分
BE节点(如分区表),则并行度 =parallel_pipeline_task_num× 涉及数据的节点数。 - 总并行度 =
parallel_pipeline_task_num× 可用BE节点数。 - 示例:3
节点集群,每节点 8 核 → 总并行度 = 4 × 3 = 12。
- 若查询的数据仅位于部分
b、无法并行导出的场景
-
包含全局排序(如
ORDER BY、LIMIT)。 -
聚合操作(如
SUM、COUNT)。 -
子查询或复杂连接(如
JOIN)。
2)判断导出速度
a、Writer 速度数据的含义
数据来源:
- 每次
SELECT INTO OUTFILE执行后,结果集的每一行对应一个 Writer 实例(由并行度决定数量)。 - 每行包含两个关键指标:
write_time:该Writer的导出耗时(单位:秒);write_speed:该Writer的导出速度(单位:KB/s)。
示例结果:
SELECT * FROM table INTO OUTFILE 'hdfs://path'
WHERE ...;
-- 结果片段(假设3个BE节点,每个节点4个Writer):
+-----------+------------+
| write_time | write_speed |
+-----------+------------+
| 10 | 5000 | -- BE1-Writer1
| 12 | 4800 | -- BE1-Writer2
| 11 | 5200 | -- BE1-Writer3
| 9 | 5100 | -- BE1-Writer4
| 10 | 4900 | -- BE2-Writer1
| ... | ... | -- 其他Writer
+-----------+------------+
b、导出速度计算方法
1、单节点:同一节点 Writer 速度累加:
- 按
BE节点分组,将同一节点的所有Writer速度相加,得到该节点的总导出速度。 - 单节点速度 =
SUM(同一BE节点下所有Writer的write_speed)
2、集群总导出速度:
- 集群总速度 =
SUM(所有BE节点的单节点速度)
c、带宽瓶颈判断逻辑
| 导出目标 | 瓶颈参考指标 | 判断方法 |
|---|---|---|
本地磁盘(BE 节点) |
磁盘顺序写入带宽(如 SSD 约 500MB/s) | 若单节点速度 ≥ 磁盘带宽的 80%,则达瓶颈 |
对象存储(如 S3) |
网络带宽(如专线 10Gbps=1250MB/s) | 若集群总速度 ≥ 网络带宽的 70%,则达瓶颈 |
HDFS |
集群写入带宽(由 DataNode 数量决定) | 对比 HDFS 写入测试基准值 |
四、MySQL Dump
Doris 在 0.15 之后的版本已经支持通过
mysqldump工具导出数据或者表结构
1、使用示例
1)导出
1、导出 test 数据库中的 table1 表:
`mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables table1`
2、导出 test 数据库中的 table1 表结构:
`mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test --tables table1 --no-data`
3、导出 test1, test2 数据库中所有表:
`mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --databases test1 test2`
4、导出所有数据库和表
`mysqldump -h127.0.0.1 -P9030 -uroot --no-tablespaces --all-databases`
2)导入
mysqldump 导出的结果可以重定向到文件中,之后可以通过 source 命令导入到 Doris 中 source filenamme.sql
2、注意
- 由于
Doris中没有MySQL里的tablespace概念,因此在使用MySQLDump时要加上--no-tablespaces参数 - 使用
MySQLDump导出数据和表结构仅用于开发测试或者数据量很小的情况,请勿用于大数据量的生产环境


