通过 Export 导出数据
异步导出(Export)是 Doris 提供的一种将数据异步导出的功能。该功能可以将用户指定的表或分区的数据,以指定的文件格式,通过 Broker 进程或 S3 协议/HDFS 协议 导出到远端存储上,如 对象存储 / HDFS 等。
当前,EXPORT 支持导出 Doris 本地表 / View 视图 / 外表,支持导出到 Parquet / ORC / CSV / csv_with_names / csv_with_names_and_types 文件格式。
本文档主要介绍 Export 的基本原理、使用方式、最佳实践以及注意事项。
原理
用户提交一个 Export 作业后。Doris 会统计这个作业涉及的所有 Tablet。然后根据parallelism
参数(由用户指定)对这些 Tablet 进行分组。每个线程负责一组 tablets,生成若干个SELECT INTO OUTFILE
查询计划。该查询计划会读取所包含的 Tablet 上的数据,然后通过 S3 协议 / HDFS 协议 / Broker 将数据写到远端存储指定的路径中。
总体的执行流程如下:
用户提交一个 Export 作业到 FE。
FE 会统计要导出的所有 Tablets,然后根据
parallelism
参数将所有 Tablets 分组,每一组再根据maximum_number_of_export_partitions
参数生成若干个SELECT INTO OUTFILE
查询计划根据
parallelism
参数,生成相同个数的ExportTaskExecutor
,每一个ExportTaskExecutor
由一个线程负责,线程由 FE 的 Job 调度框架去调度执行。FE 的 Job 调度器会去调度
ExportTaskExecutor
并执行,每一个ExportTaskExecutor
会串行地去执行由它负责的若干个SELECT INTO OUTFILE
查询计划。
开始导出
Export 的详细用法可参考 EXPORT 。
导出到 HDFS
EXPORT TABLE db1.tbl1
PARTITION (p1,p2)
[WHERE [expr]]
TO "hdfs://host/path/to/export/"
PROPERTIES
(
"label" = "mylabel",
"column_separator"=",",
"columns" = "col1,col2",
"parallelusm" = "3"
)
WITH BROKER "hdfs"
(
"username" = "user",
"password" = "passwd"
);
label
:本次导出作业的标识。后续可以使用这个标识查看作业状态。column_separator
:列分隔符。默认为\t
。支持不可见字符,比如\x07
。columns
:要导出的列,使用英文状态逗号隔开,如果不填这个参数默认是导出表的所有列。line_delimiter
:行分隔符。默认为\n
。支持不可见字符,比如\x07
。parallelusm
:并发 3 个线程去导出。
导出到对象存储
通过 S3 协议直接将数据导出到指定的存储。
EXPORT TABLE test TO "s3://bucket/path/to/export/dir/"
WITH S3 (
"s3.endpoint" = "http://host",
"s3.access_key" = "AK",
"s3.secret_key"="SK",
"s3.region" = "region"
);
s3.access_key
/s3.secret_key
:是您访问对象存储的 ACCESS_KEY/SECRET_KEYs3.endpoint
:Endpoint 表示对象存储对外服务的访问域名。s3.region
:表示对象存储数据中心所在的地域。
查看导出状态
提交作业后,可以通过 SHOW EXPORT 命令查询导出作业状态。结果举例如下:
mysql> show EXPORT\G;
*************************** 1. row ***************************
JobId: 14008
State: FINISHED
Progress: 100%
TaskInfo: {"partitions":[],"max_file_size":"","delete_existing_files":"","columns":"","format":"csv","column_separator":"\t","line_delimiter":"\n","db":"default_cluster:demo","tbl":"student4","tablet_num":30}
Path: hdfs://host/path/to/export/
CreateTime: 2019-06-25 17:08:24
StartTime: 2019-06-25 17:08:28
FinishTime: 2019-06-25 17:08:34
Timeout: 3600
ErrorMsg: NULL
OutfileInfo: [
[
{
"fileNumber": "1",
"totalRows": "4",
"fileSize": "34bytes",
"url": "file:///127.0.0.1/Users/fangtiewei/tmp_data/export/f1ab7dcc31744152-bbb4cda2f5c88eac_"
}
]
]
1 row in set (0.01 sec)
JobId:作业的唯一 ID
State:作业状态:
PENDING:作业待调度
EXPORTING:数据导出中
FINISHED:作业成功
CANCELLED:作业失败
Progress:作业进度。该进度以查询计划为单位。假设一共 10 个线程,当前已完成 3 个,则进度为 30%。
TaskInfo:以 JSON 格式展示的作业信息:
db:数据库名
tbl:表名
partitions:指定导出的分区。
空
列表 表示所有分区。column_separator:导出文件的列分隔符。
line_delimiter:导出文件的行分隔符。
tablet num:涉及的总 Tablet 数量。
broker:使用的 Broker 的名称。
coord num:查询计划的个数。
max_file_size:一个导出文件的最大大小。
delete_existing_files:是否删除导出目录下已存在的文件及目录。
columns:指定需要导出的列名,空值代表导出所有列。
format:导出的文件格式
Path:远端存储上的导出路径。
CreateTime/StartTime/FinishTime:作业的创建时间、开始调度时间和结束时间。
Timeout:作业超时时间。单位是秒。该时间从 CreateTime 开始计算。
ErrorMsg:如果作业出现错误,这里会显示错误原因。
OutfileInfo:如果作业导出成功,这里会显示具体的
SELECT INTO OUTFILE
结果信息。
取消导出任务
CANCEL EXPORT
命令自 Doris 1.2.2 版本起支持。
提交作业后,可以通过 CANCEL EXPORT 命令取消导出作业。取消命令举例如下:
CANCEL EXPORT
FROM example_db
WHERE LABEL like "%example%";
最佳实践
并发导出
一个 Export 作业可以设置parallelism
参数来并发导出数据。parallelism
参数实际就是指定执行 EXPORT 作业的线程数量。每一个线程会负责导出表的部分 Tablets。
一个 Export 作业的底层执行逻辑实际上是SELECT INTO OUTFILE
语句,parallelism
参数设置的每一个线程都会去执行独立的SELECT INTO OUTFILE
语句。
Export 作业拆分成多个SELECT INTO OUTFILE
的具体逻辑是:将该表的所有 Tablets 平均的分给所有 Parallel 线程,如:
num(tablets) = 40, parallelism = 3,则这 3 个线程各自负责的 tablets 数量分别为 14,13,13 个。
num(tablets) = 2, parallelism = 3,则 Doris 会自动将 parallelism 设置为 2,每一个线程负责一个 tablets。
当一个线程负责的 Tablets 超过
maximum_tablets_of_outfile_in_export
数值(默认为 10,可在 fe.conf 中添加maximum_tablets_of_outfile_in_export
参数来修改该值)时,该线程就会拆分为多个SELECT INTO OUTFILE
语句,如:一个线程负责的 Tablets 数量分别为 14,
maximum_tablets_of_outfile_in_export = 10
,则该线程负责两个SELECT INTO OUTFILE
语句,第一个SELECT INTO OUTFILE
语句导出 10 个 tablets,第二个SELECT INTO OUTFILE
语句导出 4 个 tablets,两个SELECT INTO OUTFILE
语句由该线程串行执行。当所要导出的数据量很大时,可以考虑适当调大
parallelism
参数来增加并发导出。若机器核数紧张,无法再增加parallelism
而导出表的 Tablets 又较多 时,可以考虑调大maximum_tablets_of_outfile_in_export
来增加一个SELECT INTO OUTFILE
语句负责的 Tablets 数量,也可以加快导出速度。
exec_mem_limit
通常一个 Export 作业的查询计划只有 扫描-导出
两部分,不涉及需要太多内存的计算逻辑。所以通常 2GB 的默认内存限制可以满足需求。
但在某些场景下,比如一个查询计划,在同一个 BE 上需要扫描的 Tablet 过多,或者 Tablet 的数据版本过多时,可能会导致内存不足。可以调整 Session 变量exec_mem_limit
来调大内存使用限制。
注意事项
不建议一次性导出大量数据。一个 Export 作业建议的导出数据量最大在几十 GB。过大的导出会导致更多的垃圾文件和更高的重试成本。
如果表数据量过大,建议按照分区导出。
在 Export 作业运行过程中,如果 FE 发生重启或切主,则 Export 作业会失败,需要用户重新提交。
如果 Export 作业运行失败,已经生成的文件不会被删除,需要用户手动删除。
Export 作业可以导出 Base 表 / View 视图表 / 外表 的数据,不会导出 Rollup Index 的数据。
Export 作业会扫描数据,占用 IO 资源,可能会影响系统的查询延迟。
在使用 EXPORT 命令时,请确保目标路径是已存在的目录,否则导出可能会失败。
在并发导出时,请注意合理地配置线程数量和并行度,以充分利用系统资源并避免性能瓶颈。
导出到本地文件时,要注意文件权限和路径,确保有足够的权限进行写操作,并遵循适当的文件系统路径。
在导出过程中,可以实时监控进度和性能指标,以便及时发现问题并进行优化调整。
导出操作完成后,建议验证导出的数据是否完整和正确,以确保数据的质量和完整性。
相关配置
FE
maximum_tablets_of_outfile_in_export
:ExportExecutorTask 任务中一个 OutFile 语句允许的最大 tablets 数量。
更多帮助
关于 EXPORT 使用的更多详细语法及最佳实践,请参阅 Export 命令手册,你也可以在 MySQL 客户端命令行下输入 HELP EXPORT
获取更多帮助信息。
EXPORT 命令底层实现是SELECT INTO OUTFILE
语句,有关SELECT INTO OUTFILE
可以参阅 同步导出 和 SELECT INTO OUTFILE 命令手册。