ByteHouse 云数仓支持通过脚本工具,以离线方式将您存储在 Doris 中的数据快速迁移至 ByteHouse 云数仓并投入使用,助力实现数据的统一管理与开发。本文将详细介绍 Doris 数据库表及数据向 ByteHouse 云数仓的迁移方法。
功能概述
将 Doris 数据迁移至 ByteHouse 云数仓依赖于 ByteHouse 自研迁移脚本:Doris 数据导出脚本和数据导入脚本。在迁移时,
使用 ByteHouse 自研 Doris 数据导出脚本将数据从 Doris 导出至对象存储; 使用基于 ByteHouse S3 外表功能开发的数据导入脚本完成从对象存储的数据导入。 脚本名称
能力说明
ByteHouse 自研 Doris 数据导出脚本
断点续传 :能够精准记录导入状态,对于已成功执行的导入任务不再重复执行,若任务失败则支持回滚操作,保障迁移过程的稳定性与连续性。并发导出 :支持并发导出,提升导出效率。通用导出能力 :具备通用导出能力,适配多种数据场景。进度条展示 :通过进度条直观展示导出进度。ByteHouse 自研数据导入脚本
断点续传 :能够精准记录导入状态,对于已成功执行的导入任务不再重复执行,若任务失败则支持回滚操作,保障迁移过程的稳定性与连续性。并发执行 :支持外表创建和导入 SQL 的并发处理,可有效提升迁移效率,缩短整体迁移时间。多表多库支持 :可同时对多个数据库中的多张表进行迁移操作,满足复杂数据环境下的迁移需求。外表分区过滤导入 :支持针对单表设置分区筛选策略,仅导入符合条件的分区数据,减少不必要的数据处理。外表存储格式配置 :支持单表粒度的存储格式自定义,可根据实际业务需求选择合适的存储格式。导入重试能力 :当导入任务出现异常时,支持自动或手动重试,提高任务成功率。单表操作支持 :支持单表粒度的 insert into(插入)及 insert overwrite(覆盖)操作,满足不同的数据导入需求。dry-run 功能 :可提前运行脚本进行检查,验证脚本的正确性,避免因脚本问题导致迁移失败。N 级分区外表 :对于 Hive 分区表,支持按照 Hive 分区表模式,为单表配置粒度化的分区规则,灵活适配不同的数据分区场景。
迁移流程
从 Doris 迁移至 ByteHouse 的流程主要包括下三大步骤:
准备目标表,在 ByteHouse 中创建迁移所需的目标表。 将数据从 Doris 中导出到对象存储服务,并检查导出至对象存储服务中的数据和目录是否符合预期。 将数据从对象存储导入到 Bytehouse,并检查数据一致性。
使用限制
如果您的迁移场景符合以下任一条件,请联系 ByteHouse 团队处理:
单表大小超过 10 亿行; 计算组规格较小(规格为 M 或以下规格),同时表大小超过 1 亿行。
注意事项
迁移过程中,目标数据库与源数据库、S3 协议对象存储服务(以下简称对象存储服务)间的网络互通且网络环境稳定。
通常情况下,Doris、对象存储服务、ByteHouse 间需通过公网传输,请确保网络环境稳定;若您已搭建专线,可切换为私网传输,此时需确保专线配置完成且网络环境稳定。 使用火山引擎对象存储服务 TOS 传输到 ByteHouse 时,需确保 TOS 与 ByteHouse 实例处于相同地域,以保障数据传输效率并避免跨地域访问产生额外费用。 数据迁移涉及的传输流量及存储服务可能产生费用,具体计费规则以各产品官方文档及实际账单为准,请提前确认计费模式。
准备工作
获取 Doris、对象存储服务、ByteHouse 的连接信息,包括域名、端口号、账号、密码、Access Key ID(AK)、Secret Access Key(SK)等。 请确保您使用的 Doris、ByteHouse 账号拥有对象存储服务的全读写权限。 确认您已在 ByteHouse 中配置默认写计算组,该计算组用于数据 merge 操作。您可登录 ByteHouse 控制台,单击顶部租户管理 ,在参数设置 页签下,设置默认写计算组。
如果您的 Bytehouse 计算组需要设置特定的兼容性配置,请联系 ByteHouse 团队。 如果您对时区有特殊需求,可联系 ByteHouse 团队设置租户级别的 session timezone 为指定的时区。默认情况下,您在火山引擎中使用的 ByteHouse 服务使用东八区,在 AWS 中使用的 ByteHouse 服务使用 UTC 时区,使用的 BytePlus ByteHouse 服务使用东八区。
步骤一:准备目标表
请确保 Doris 源数据库/表已准备就绪,且在 ByteHouse 中创建了目标数据库/表,创建 ByteHouse 数据库/表请参见数据库管理 。ByteHouse 也提供了建表最佳实践,详情请参考ByteHouse 建表配置最佳实践 和ByteHouse 唯一键表最佳实践 。
如果您需要创建的表数量较多,可提交工单或联系 ByteHouse 团队。
步骤二:从 Doris 导出数据到对象存储服务
Doirs 导出到对象存储的逻辑 根据库表配置,按照表级别进行串行导出。 查询出某张表的所有 tablet。此操作要求您使用的 Doris 账号具有查看 table 的 tablet 的权限。 按照配置的 parallelism 并发导出一张表的所有 tablet。 注意
Doris 导出到对象存储的逻辑中,若导出 SQL 执行失败,由于当前 Doris 导出逻辑缺乏原子性,因此 SQL 执行失败时可能还是会导出对应的文件。而当前脚本有重试能力,会出现两种不同的情况。情况 1
对象存储中也会出现不完整的文件,因此,导出过程中需要检查是否出现过Error executing export query on Doris报错 ,常见报错请参见下方代码块示意。
[INFO] data-migrator-doris-to-s3.py v1.0.1: Executing export query on Doris [SELECT * FROM store_sales.Sales1 TABLET(12757)] into outfile s3 beginning
[INFO] data-migrator-doris-to-s3.py v1.0.1: Error executing export query on Doris (attempt 1/10): (1105, 'errCode = 2, detailMessage = (172.20.80.6)[CANCELLED]Process memory not enough, cancel top memory used query: <Query#Id=18f73238313943d6-9b3b82b7c136cd40> consumption 35.25 MB, backend 172.20.80.6, process memory used 805.76 MB exceed limit 13.86 GB or sys available memory 675.82 MB less than low water mark 788.68 MB. Execute again after enough memory, details see be.INFO.')
[INFO] data-migrator-doris-to-s3.py v1.0.1: Error executing export query on Doris (attempt 2/10): (1105, 'errCode = 2, detailMessage = (172.20.80.6)[INTERNAL_ERROR]Failed to get query fragments context. Query may be timeout or be cancelled. host: 172.20.80.6')
[INFO] data-migrator-doris-to-s3.py v1.0.1: Error executing export query on Doris (attempt 3/10): (1105, 'errCode = 2, detailMessage = (172.20.80.6)[INTERNAL_ERROR]Failed to get query fragments context. Query may be timeout or be cancelled. host: 172.20.80.6')
[INFO] data-migrator-doris-to-s3.py v1.0.1: Executing export query on Doris [SELECT * FROM store_sales.Sales1 TABLET(12757)] into outfile s3 successful
如果有出现过该报错,需要检查表是否为 Unique Table,操作如下:
如果对应的目标表在 ByteHouse 中是 Unique Table(唯一键表) ,则只需要查看对应的对象存储中库表的目录下是否存在 SUCCESS 文件。比如下图示例中 TABLET(12757) 存在 SUCCESS 文件,则可以忽略该错误,因为 ByteHouse 唯一键表可以去重,将忽略导出的重复文件。 如果对应的目标表在 ByteHouse 中是非 Unique Table, 则需要将 12757 开头的文件删除,并重新导出该 Tablet,确保再次导出的时候不存在 Error executing export query on Doris 报错。 情况 2
默认脚本会重试 10 次,如果所有重试最终均失败,则脚本对应会报错 There are [xxx] tablets export failed in table [xxx], need to retry,这种情况下也需要重新导出 Tablet。报错提示中,第一个 [xxx] 是以 ',' 分割的 Tabletid string 数组,第二个 [xxx] 为表名。重新导出时,可通过配置 tablets 单独配置需要导出的 tablets,并指定 export_level=tablet。
操作步骤 下载 Python 工具及 ByteHouse 自研 Doris 数据导出脚本文件。您可根据您使用的 Python 版本下载对应的脚本文件。
下载后,请将该脚本存储至您自定义的路径,并记录该路径,用户后续执行脚本时配置。
pip3 install pymysql
pip3 install dbutils
pip3 install tqdm
Python 版本
迁移脚本文件
Python 3.12.0
data-migrator-doris-to-s3.py
未知大小
Python 3.6.8
data-migrator-doris-to-s3.py
未知大小
在 Doris 数据导出脚本的同一路径下,创建并配置 ini 文件。本文示例中将 ini 文件命名为 data-migrator-doris-to-s3.ini,请使用实际的 Doris 连接信息、对象存储的目标存储路径、数据迁移参数值替换示例中的占位符或示例参数值,以便数据导出脚本可以正常执行。
该配置文件中分为 table 和 tablet 两种导出模式,请参见配置中的说明。
适用于对象存储服务为火山引擎对象存储 TOS。
# Doris 信息
doris_host={your_doris_ip}
doris_port=9030
doris_user={your_doris_user_name}
doris_password={your_doris_password}
# 对象存储连接信息
s3_access_key={tos_access_key}
s3_secret_key={tos_secret_access_key}
# 无需包含最后的 '/' 符号,格式:s3://桶名称/输出路径
s3_url=s3://{bucket_name}/{output_path}
s3_endpoint=https://tos-s3-{your_region}.volces.com
s3_region={your_region}
# export 模式:table 或 tablet,默认值:table
export_level=table
# 导出的库名,目前只支持单库的方式导出
database_name=databases_name
# 导出库下面所有表名的信息,如果是全部,可以填写*,如果指定部分可以用逗号分割。
table_names=*
# 需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid
# 以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。
# tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
tablets=test_bitmap:1940519
# 导出 SQL 中 select 不同列的匹配规则,当前情况下保持下面的配置默认即可。
field_rules=bitmap:bitmap_to_array($Field$)
# 可选配置
# 失败后最大的重试次数,默认值:10
max_retries=10
# 每次重试延迟时间,默认值:5
retry_delay_seconds=5
# session 配置,例如:enable_parallel_outfile:开启并发导出,query_timeout:sql执行的超时时间,
# 默认值:enable_parallel_outfile = true;query_timeout =3600;exec_mem_limit=16G
outfile_sets=enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G
# 导出文件格式,默认值:PARQUET
file_format=PARQUET
# 其他过滤条件(filters)
where=
# 并发导出 SQL 的数量,默认为 4,代表每次同时并发导出 4 个tablet_id
parallelism=4
max_file_size=128MB
适用于对象存储服务为 AWS S3。
# Doris 信息
doris_host={your_doris_ip}
doris_port=9030
doris_user={your_doris_user_name}
doris_password={your_doris_password}
# 对象存储连接信息
s3_access_key={aws_access_key_id}
s3_secret_key={aws_secret_access_key}
# 无需包含最后的 '/' 符号,格式:s3://桶名称/输出路径
s3_url=s3://{bucket_name}/{output_path}
s3_endpoint=https://s3.{your_aws_region}.amazonaws.com
s3_region={your_aws_region}
# export 模式:table 或 tablet,默认值:table
export_level=table
# 导出的库名,目前只支持单库的方式导出
database_name=databases_name
# 导出库下面所有表名的信息,如果是全部,可以填写*,如果指定部分可以用逗号分割。
table_names=*
# 需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid
# 以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。
# tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
tablets=test_bitmap:1940519
# 导出 SQL 中 select 不同列的匹配规则,当前情况下保持下面的配置默认即可。
field_rules=bitmap:bitmap_to_array($Field$)
# 可选配置
# 失败后最大的重试次数,默认值:5
max_retries=10
# 每次重试延迟时间,默认值:5
retry_delay_seconds=5
# session 配置,例如:enable_parallel_outfile:开启并发导出,query_timeout:sql执行的超时时间,
# 默认值:enable_parallel_outfile = true;query_timeout =3600;exec_mem_limit=16G
outfile_sets=enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G
# 导出文件格式,默认值:PARQUET
file_format=PARQUET
# 其他过滤条件(filters)
where=
# 并发导出 SQL 的数量,默认为 4,代表每次同时并发导出 4 个tablet_id
parallelism=4
max_file_size=128MB
适用于对象存储服务为阿里云 OSS。
# Doris 信息
doris_host={your_doris_ip}
doris_port=9030
doris_user={your_doris_user_name}
doris_password={your_doris_password}
# 对象存储连接信息
s3_access_key={oss_access_key_id}
s3_secret_key={oss_secret_access_key}
# 无需包含最后的 '/' 符号,格式:s3://桶名称/输出路径
s3_url=s3://{bucket_name}/{output_path}
s3_endpoint=https://oss.{your_oss_region}.aliyuncs.com
s3_region={your_oss_region}
# export 模式:table 或 tablet,默认值:table
export_level=table
# 导出的库名,目前只支持单库的方式导出
database_name=databases_name
# 导出库下面所有表名的信息,如果是全部,可以填写*,如果指定部分可以用逗号分割。
table_names=*
# 需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid
# 以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。
# tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
tablets=test_bitmap:1940519
# 导出 SQL 中 select 不同列的匹配规则,当前情况下保持下面的配置默认即可。
field_rules=bitmap:bitmap_to_array($Field$)
# 可选配置
# 失败后最大的重试次数,默认值:5
max_retries=10
# 每次重试延迟时间,默认值:5
retry_delay_seconds=5
# session 配置,例如:enable_parallel_outfile:开启并发导出,query_timeout:sql执行的超时时间,
# 默认值:enable_parallel_outfile = true;query_timeout =3600;exec_mem_limit=16G
outfile_sets=enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G
# 导出文件格式,默认值:PARQUET
file_format=PARQUET
# 其他过滤条件(filters)
where=
# 并发导出 SQL 的数量,默认为 4,代表每次同时并发导出 4 个tablet_id
parallelism=4
max_file_size=128MB
适用于对象存储服务为华为云 OBS。
# Doris 信息
doris_host={your_doris_ip}
doris_port=9030
doris_user={your_doris_user_name}
doris_password={your_doris_password}
# 对象存储连接信息
s3_access_key={obs_access_key_id}
s3_secret_key={obs_secret_access_key}
# 无需包含最后的 '/' 符号,格式:s3://桶名称/输出路径
s3_url=s3://{bucket_name}/{output_path}
s3_endpoint=https://obs.{your_obs_region}.myhuaweicloud.com
s3_region={your_obs_region}
# export 模式:table 或 tablet,默认值:table
export_level=table
# 导出的库名,目前只支持单库的方式导出
database_name=databases_name
# 导出库下面所有表名的信息,如果是全部,可以填写*,如果指定部分可以用逗号分割。
table_names=*
# 需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid
# 以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。
# tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
tablets=test_bitmap:1940519
# 导出 SQL 中 select 不同列的匹配规则,当前情况下保持下面的配置默认即可。
field_rules=bitmap:bitmap_to_array($Field$)
# 可选配置
# 失败后最大的重试次数,默认值:5
max_retries=10
# 每次重试延迟时间,默认值:5
retry_delay_seconds=5
# session 配置,例如:enable_parallel_outfile:开启并发导出,query_timeout:sql执行的超时时间,
# 默认值:enable_parallel_outfile = true;query_timeout =3600;exec_mem_limit=16G
outfile_sets=enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G
# 导出文件格式,默认值:PARQUET
file_format=PARQUET
# 其他过滤条件(filters)
where=
# 并发导出 SQL 的数量,默认为 4,代表每次同时并发导出 4 个tablet_id
parallelism=4
max_file_size=128MB
适用于对象存储服务为 MinIO。
# Doris 信息
doris_host={your_doris_ip}
doris_port=9030
doris_user={your_doris_user_name}
doris_password={your_doris_password}
# 对象存储连接信息
s3_access_key={minio_access_key}
s3_secret_key={minio_secret_key}
# 无需包含最后的 '/' 符号,格式:s3://桶名称/输出路径
s3_url=s3://{bucket_name}/{output_path}
s3_endpoint=http://{minio-host}:9000
# MinIO 无需指定区域,可留空或填写自定义区域标识
s3_region=
# export 模式:table 或 tablet,默认值:table
export_level=table
# 导出的库名,目前只支持单库的方式导出
database_name=databases_name
# 导出库下面所有表名的信息,如果是全部,可以填写*,如果指定部分可以用逗号分割。
table_names=*
# 需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid
# 以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。
# tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
tablets=test_bitmap:1940519
# 导出 SQL 中 select 不同列的匹配规则,当前情况下保持下面的配置默认即可。
field_rules=bitmap:bitmap_to_array($Field$)
# 可选配置
# 失败后最大的重试次数,默认值:5
max_retries=10
# 每次重试延迟时间,默认值:5
retry_delay_seconds=5
# session 配置,例如:enable_parallel_outfile:开启并发导出,query_timeout:sql执行的超时时间,
# 默认值:enable_parallel_outfile = true;query_timeout =3600;exec_mem_limit=16G
outfile_sets=enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G
# 导出文件格式,默认值:PARQUET
file_format=PARQUET
# 其他过滤条件(filters)
where=
# 并发导出 SQL 的数量,默认为 4,代表每次同时并发导出 4 个tablet_id
parallelism=4
max_file_size=128MB
配置 Key
类型
描述
doris_host
string
Doris 的地址。
doris_port
string
Doris 的端口,配置为 9030。
doris_user
string
Doris 的用户名。
doris_password
string
Doris 的密码。
s3_access_key
string
存储导出文件的对象存储服务的 Access Key ID。
如果您使用的是火山引擎 TOS,获取方式可参考 Access Key(密钥)管理 。
s3_secret_key
string
存储导出文件的对象存储服务的 Secret Access Key。
如果您使用的是火山引擎 TOS,获取方式可参考 Access Key(密钥)管理 。
s3_url
string
导出文件在对象存储中的目标存储目录,不需要加上目录最后的/,如:s3://bucket_name/output。
s3_endpoint
string
导出文件的对象存储桶的访问域名(endpoint)。不同对象存储服务的示例如下:
TOS:可参考地域和访问域名(Endpoint) 文档中 S3 Endpoint 列。
公网:https://tos-s3-{your_region}.volces.com 私网:https://tos-s3-{your_region}.ivolces.com AWS S3:https://s3.{your_aws_region}.amazonaws.com 阿里云 OSS:https://oss.{your_oss_region}.aliyuncs.com 华为云 OBS:https://obs.{your_obs_region}.myhuaweicloud.com MinIO:http://{minio-host}:9000 s3_region
string
导出文件的对象存储桶所在的地域(region)。
export_level
string
导出模式。可选项为 table 或 tablet。
table 代表以表级别导出。 tablet 代表以 tablet 级别导出。 database_name
string
Doris 中需导出的数据库名称。
table_names
string
Doris 数据库中需导出的表名称,如果需要导出多张表,可使用逗号(,)分开。如果使用星号(*),则代表导出数据库中的所有表。该配置仅在 export_level 为 table 时生效。
field_rules
string
该参数用于定义导出 SQL 中列的匹配规则,通过修改导出 SQL 中对应列的查询逻辑,以适配特殊数据类型的导出需求。默认值为 bitmap:bitmap_to_array($Field$)。例如,Doris 中需要将 Bitmap 类型需转换为 Array 数组格式才能正确导出,可通过此参数指定转化逻辑,示例如下:
bitmap:bitmap_to_array($Field$)
默认值为 null,即默认情况下导出的 SQL 为 select col1,col2,col3 from xxx ...;配置规则后,脚本会自动替换对应列的查询逻辑。
规则配置格式为:column_type:function($Field$);column_type:function(function($Field$)),采用 Key-Value 格式,多规则间用分号分隔。当某列的类型匹配规则中的 column_type 时,导出 SQL 中该列的查询逻辑会被替换为配置的函数:
Key:需匹配的 Doris 列类型,例如 BITMAP;value:Doris 的转换函数,用于对该类型的列进行转换,其中 $Field$ 为占位符,会自动替换为实际的列名,如 field1、field2。tablets
string
需要导出的 Tablet 信息。该配置仅在 export_level 为 tablet 时生效,格式:table_name1:tabletid;table_name2:tabletid,tabletid,tabletid。
以分号分割每张表的 tablet 信息,每张表以 table_name:tabletids 为组合。tabletids 则以该表所需要导出的 tablet 的 id 并以逗号分割。
file_format
string
导出的文件格式,默认值:PARQUET。
max_retries
int
失败后最大的重试次数,默认值:10。
retry_delay_seconds
int
每次重试延迟时间,默认:5,单位:秒。
outfile_sets
string
连接时需要提前设置的一些 session 级别参数,以分号分开。默认设置:enable_parallel_outfile = true;query_timeout = 3600;exec_mem_limit=16G,参数说明如下:
enable_parallel_outfile:控制是否启用并行导出功能。 query_timeout:设置导出任务的超时时间(单位:秒)。 exec_mem_limit:限制单个导出任务的内存使用上限。 where
string
可使用该参数为某张表设置 filter 条件,支持导出一份数据,对数据库级别生效。
如果您需要为不同的表设置不同的筛选条件,请按照 table_names 进行细分,并为每张表生成新的配置文件执行导出任务。
parallelism
string
并发导出 SQL 的数量,默认为 4。代表每次同时并发导出 4 个 tablet_id。
max_file_size
string
导出文件最大的数量,默认为 128 MB。
执行 Python 脚本文件,即可将 Doris 中的数据导出至对象存储。
运行前,请确保当前工作目录为脚本所在目录,或使用绝对路径指定脚本位置。
python3 data-migrator-doris-to-s3.py data-migrator-doris-to-s3.ini
Doris 数据导出后,检查对象存储中的导出的数据和目录是否符合预期。
按照上述操作导出的数据文件将会使用以下目录结构存储到对象存储中,您可按照以下示例路径,在您使用的对象存储服务中查看目录和数据是否符合预期。以上面的配置文件中的 URL 为例,存储路径如下:
s3://bucket_name/output/{database_name}/{table_name}/{tablet_id}_{uuid}_{file_index}.parquet
步骤三:从对象存储服务导入到 ByteHouse
使用 ByteHouse 自研数据导入脚本将导出的数据从对象存储服务导入到 ByteHouse。ByteHouse 自研导入脚本利用 S3 外表功能实现数据迁移:通过创建 S3 外表直连对象存储读取数据,并自动同步至目标内表完成导入。详细操作请参考数据导入 。