前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、概述

数据导出功能,用于将查询结果集或者 Apache Doris 的表数据,使用指定的文件格式,写入指定的存储系统中的。

导出功能和数据备份功能有以下区别:

  数据导出 数据备份
数据最终存储位置 HDFS、对象存储、本地文件系统 HDFS、对象存储
数据格式 ParquetORC、CSV 等开放格式 Apache Doris 内部存储格式
执行速度 中等(需要读取数据并转换成目标数据格式) 快速(无需解析和转换,直接上传 Apache Doris 数据文件)
灵活度 可以通过 SQL 语句灵活定义要导出的数据 仅支持表级别全量备份
使用场景 结果集下载、不同系统之间的数据交换 数据备份、Apache Doris 集群间的数据迁移

Apache Doris 提供以下三种不同的数据导出方式:

  • SELECT INTO OUTFILE:支持任意 SQL 结果集的导出。
  • EXPORT:支持表级别的部分或全部数据导出。
  • MySQL DUMP:兼容 MySQL Dump指令的数据导出。

三种导出方式的异同点如下:

  SELECT INTO OUTFILE EXPORT MySQL DUMP
同步/异步 同步 异步(提交 EXPORT 任务后通过 SHOW EXPORT 命令查看任务进度) 同步
支持任意 SQL 支持 不支持 不支持
导出指定分区 支持 支持 不支持
导出指定 Tablets 支持 不支持 不支持
并发导出 支持且并发高(但取决于 SQL 语句是否有 ORDER BY 等需要单机处理的算子) 支持且并发高(支持 Tablet 粒度的并发导出) 不支持,只能单线程导出
支持导出的数据格式 ParquetORCCSV ParquetORCCSV MySQL Dump 专有格式
是否支持导出外表 支持 部分支持 不支持
是否支持导出 View 支持 支持 支持
支持的导出位置 S3、HDFS S3、HDFS LOCAL

二、Export

ExportDoris 提供的一种将数据异步导出的功能。该功能可以将用户指定的表或分区的数据,以指定的文件格式,导出到目标存储系统中,包括对象存储、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 OUTFILE SQL 语句。

1、用户发起一个 Export 任务后,Doris 会根据 Export 要导出的表构造出一个或多个 SELECT INTO OUTFILE 执行计划,

2、随后将这些SELECT INTO OUTFILE 执行计划提交给 DorisJob Schedule 任务调度器

3、Job Schedule 任务调度器会自动调度这些任务并执行。

4、实践

根据返回结果判断导出执行情况,Export 命令本质上是将任务拆分成多个 SELECT INTO OUTFILE 子句进行执行。通过 SHOW EXPORT 命令返回的结果中包含一个 Json 字符串,是一个二维数组。第一维代表 Export 并发的线程数,并发多少个线程代表并发发起了多少个 Outfile 语句。第二维代表单个 Outfile 语句的返回结果

示例中,发起了 2Outfile 命令。每个命令有 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、并行度计算

  1. 会话变量控制
    • parallel_pipeline_task_num:单个 BE 节点的最大并行度(默认值为 单节点 CPU 核数的一半)。
    • 示例:若单节点 CPU 为 8 核,则 parallel_pipeline_task_num = 4
  2. 集群规模扩展
    • 若查询的数据仅位于部分 BE 节点(如分区表),则并行度 = parallel_pipeline_task_num × 涉及数据的节点数
    • 总并行度 = parallel_pipeline_task_num × 可用 BE 节点数
    • 示例:3 节点集群,每节点 8 核 → 总并行度 = 4 × 3 = 12

b、无法并行导出的场景

  • 包含全局排序(如 ORDER BYLIMIT)。

  • 聚合操作(如 SUMCOUNT)。

  • 子查询或复杂连接(如 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 节点下所有 Writerwrite_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 命令导入到 Dorissource filenamme.sql

2、注意

  1. 由于 Doris 中没有 MySQL 里的 tablespace 概念,因此在使用 MySQL Dump 时要加上 --no-tablespaces 参数
  2. 使用 MySQL Dump 导出数据和表结构仅用于开发测试或者数据量很小的情况,请勿用于大数据量的生产环境

ContactAuthor