本文将介绍如何将小文件通过本地文件、对象存储、HDFS 等数据源导入至 ByteHouse。
当您需要测试文件导入,或导入的文件体积较小时(如几 KB 至几十 MB 的小批量数据)时,推荐通过 INSERT INTO 语句完成导入,效率更优。 从导入效率来看,使用批式导入处理对象存储数据源,该过程需要调度 Spark 资源,即使是几 KB 的文件,也需分钟级导入。而 INSERT INTO 方式直接从对象存储读取数据写入 ByteHouse,无需依赖 Spark 资源调度,能快速完成导入。
ByteHouse 从小文件导入功能支持本地文件、对象存储、HDFS 数据源:
INSERT INTO 语句完成导入,导入方式更简单便捷。INSERT INTO 语句完成导入。连接 ByteHouse 操作详情请参考查询窗口和连接集群。INSERT INTO 时,会占用 ByteHouse 集群的 CPU 资源,可能与正在运行的查询任务争抢资源,导致查询响应延迟或性能下降。批式导入功能则采用旁路写入,使用 Spark 集群的 CPU 资源,因此不会发生抢占。INSERT INTO(如下文示例场景),当集群分片数大于 1 时,数据需在分片间进行路由分发,会产生额外的网络传输和数据处理开销,导致导入性能较差。建议您将源数据按分片规则拆分后,分别向各节点的本地表(即示例中的 Local 表)执行导入,可减少资源消耗,提升导入效率。clickhouse client \ --host <host> \ --user <user> \ --password <password> \ --query "INSERT INTO <database_name>.<table_name> FORMAT format SETTINGS key1=value1, key2=value2" \ < File_Name.csv \
您也可以使用 Cat 命令:
cat File_Name.csv | clickhouse-client \ --host <host> \ --user <user> \ --password <password> \ --query="INSERT INTO <database_name>.<table_name> FORMAT format SETTINGS key1=value1, key2=value2";
参数项 | 配置说明 |
|---|---|
host | ByteHouse 集群的网络地址。您可登录 ByteHouse 企业版控制台,在集群管理 > 集群列表 > 集群名称 > 连接集群中,查看并复制 ClickHouse Client 卡片中的 host 地址。 |
user | ByteHouse 账户名。您可登录 ByteHouse 企业版控制台,在集群管理 > 集群列表 > 集群名称 > 连接集群中,查看并复制 ClickHouse Client 卡片中的 user 信息。 |
password | ByteHouse 连接密码。您可登录 ByteHouse 企业版控制台,单击右上角 ByteHouse 个人中心,单击账号管理,复制集群连接密码。 |
query | 设置为
|
File_Name | 需导入的文件路径及文件名。 |
INSERT INTO <database_name>.<table_name> SELECT * FROM s3( path, access_key_id, secret_access_key, format, structure, [compression] ) [SETTINGS key1=value1, key2=value2];
参数项 | 配置说明 |
|---|---|
database_name | 目标数据库名称。 |
table_name | 目标数据表名称。 |
path | 指定对象存储中源表的路径,示例如下:
如果您使用的是 TOS,可通过 TOS 控制台 > 桶列表 > 桶名称 > 文件列表 > 文件名后的详情按钮,查看并复制 URL,并将域名更换为 S3 Endpoint 域名,推荐使用内网域名,详情参见火山引擎 TOS 支持的地域和访问域名。示例如下:
|
access_key_id | 设置为对象存储服务的 Access Key ID,您可参考您使用的对象存储服务的官方文档获取 Access Key ID。如果您使用的是火山引擎 TOS,可参考 Access Key(密钥)管理。 |
secret_access_key | 设置为对象存储服务的 Secret Access Key,您可参考您使用的对象存储服务的官方文档获取 Secret Access Key。如果您使用的是火山引擎 TOS,可参考 Access Key(密钥)管理。 |
format | 设置为源文件格式,如 CSV。当前支持的格式请参见输入和输出数据的格式。 |
structure | 设置为源表结构,包括列名和列类型。示例: |
compression | 可选配置,指定数据的压缩格式,支持 |
SETTINGS | 可选配置,设置 settings 参数,用于配置 CSV 数据的实际格式,灵活适配数据读写需求。当前支持配置的 settings 参数请参见Settings 配置。 |
INSERT INTO <database_name>.<table_name> SELECT * FROM hdfs( 'path', 'format', 'structure' ) [SETTINGS key1=value1, key2=value2];
参数项 | 配置说明 |
|---|---|
database_name | 目标数据库名称。 |
table_name | 目标数据表名称。 |
path | 设置为 HDFS 文件完整路径,格式为
|
format | 设置为源文件格式,如 CSV。 |
structure | 设置为源表结构,包括列名和列类型。示例: |
SETTINGS | 可选配置,设置 settings 参数,用于配置 CSV 数据的实际格式,灵活适配数据读写需求。当前支持配置的 settings 参数请参见Settings 配置。 |
在执行 SQL 语句时,您可根据 CSV 数据的实际格式,按需添加以下 Settings 配置项,灵活适配数据读写需求。
Settings 配置项 | 默认值 | 描述 |
|---|---|---|
format_csv_delimiter |
| 指定 CSV 数据中字段的分隔符字符。如果设置为字符串,该字符串必须长度为 1。 |
format_csv_allow_single_quotes |
| 是否允许使用单引号( |
format_csv_allow_double_quotes |
| 是否允许使用双引号( |
format_csv_write_utf8_with_bom |
| 是否在输出的 CSV 文件开头写入 UTF-8 BOM(字节顺序标记)。如果设置为 true,将在输出的开头写入 BOM。 |
output_format_csv_crlf_end_of_line |
| 输出 CSV 时是否使用行尾符 |
output_format_csv_null_representation |
| 指定输出时用于表示 |
input_format_csv_unquoted_null_literal_as_null |
| 是否将未加引号的文本 |
input_format_csv_enum_as_number |
| 导入 CSV 时,是否将枚举值解释为其对应的枚举索引 |
input_format_csv_arrays_as_nested_csv |
| 是否将数组字段解析为嵌套 CSV 格式。例如: |
在 ByteHouse 中创建目标数据库、表,请确保目标表与源表结构一致,操作详情请参见新建数据库/表。
本文示例以 HaMergeTree 表为例,建表语句如下:
-- 创建数据库 CREATE DATABASE IF NOT EXISTS test_db -- 创建 Local 本地表 CREATE TABLE IF NOT EXISTS test_db.test_table_local ON CLUSTER default_cluster ( `id` String, `name` String, `date` Date ) ENGINE = HaMergeTree('/clickhouse/tables/test_db/test_table_local/{shard}', '{replica}') ORDER BY id; -- 创建 Distributed 分布式表 CREATE TABLE IF NOT EXISTS test_db.test_table ON CLUSTER default_cluster AS test_db.test_table_local ENGINE = Distributed('default_cluster', 'test_db', 'test_table_local', rand());
安装 ClickHouse Client 工具,点此下载。
准备本地文件 test.csv,并写入数据如下。确保本地 CSV 文件的字段顺序与目标表的字段顺序一致。
$ cat /test.csv A001,Amy,2023-01-01 A002,Bob,2023-01-02 A003,Charles,2023-01-03
使用 ClickHouse Client 向目标表写入数据。
cat test.csv | clickhouse-client \ --host 2xxxxxxxxxxxxxxxxx.bytehouse-ce.ivolces.com \ --user demo_user \ --password Mt************** \ --query="INSERT INTO test_db.test_table_local FORMAT CSV";
查询是否写入成功。
SELECT * FROM test_db.test_table;
本示例将演示如何使用 ClickHouse s3() 函数,将本地文件中的数据写入到准备工作章节创建的 ByteHouse 表中。
在开始操作前,请确保您已经具备您使用的对象存储桶的访问权限:
构建 Schema 映射。此步骤用于获取目标表的字段名和字段类型,确保源数据与目标表结构匹配,避免导入时因结构不匹配导致失败。
SELECT arrayStringConcat(groupArray(concat(name, ' ', type)), ', ') FROM system.columns WHERE DATABASE = '<database_name>' AND TABLE = '<table_name>'
从对象存储中导入数据至 ByteHouse。
INSERT INTO test_db.test_table_local SELECT * FROM s3( 'https://bucket.endpoint/file_path/test_outfile.csv', 'AK***************', 'aBc********************', 'CSV', '(id String, name String, date Date)', 'none', );
查询是否写入成功。
SELECT * FROM test_db.test_table;
本示例将演示如何使用 ClickHouse hdfs() 函数,将本地文件中的数据写入到准备工作章节创建的 ByteHouse 表中。
在开始操作前,请确保您已经获取 HDFS 文件的访问路径,且具备该路径的访问权限。
从 HDFS 中导入数据至 ByteHouse。
INSERT INTO test_db.test_table_local SELECT * FROM hdfs( 'hdfs://192.168.x.xxx:8020/user/data/202509_user.csv', 'CSV', '(id String, name String, date Date)' );
查询是否写入成功。
SELECT * FROM test_db.test_table;
如果您在使用中遇到以下报错:
Code: 27, e.displayText() = DB::ParsingException:Cannot parse input: expected '\\N' before: ... (version 21.8.7.1)
\,如 aaa,bbb,cc\c,这种情况会被 ByteHouse 视作特殊字符。input_format_null_as_default = 0,即 ByteHouse 不再识别 \N 为 Null。但此种方案将导致无法导入 Null 值。