目前Doris支持两种从本地导入数据的模式:
- Stream Load
- MySQL Load
一、Stream Load导入
Stream load 是一个同步的导入方式,用户通过发送 HTTP 协议发送请求将本地文件或数据流导入到 Doris 中。Stream load 同步执行导入并返回导入结果。用户可直接通过请求的返回体判断本次导入是否成功。
Stream load 主要适用于导入本地文件,或通过程序导入数据流中的数据。
不同于其他命令的提交方式,Stream Load是通过HTTP协议与Doris进行连接交互的。
该方式中涉及HOST:PORT应为HTTP协议端口。
- BE的HTTP协议端口,默认为8040
- FE的HTTP协议端口,默认为8030.但须保证客户端所在机器网络能够联通BE所在机器。
Stream Load的请求体:
PUT /api/{db}/{table}/_stream_load
支持数据格式
Stream Load 支持数据格式:CSV(文本)和JSON。
导入数据命令
curl -u user:passwd -H "label:load_local_file_test" -T /path/to/local/demo.txt http://host:port/api/demo/load_local_file_test/_stream_load
user:passwd为在Doris中创建的用户。初始用户为admin/root,密码初始状态下为空。
host:port为BE的HTTP协议端口,默认是8040,可以在Doris集群WEB UI页面查看。
label:可以在Header中指定Label唯一标识这个导入任务。 --当前Doris内部保留30分钟内最近成功的label。
curl的一些可配置的参数
- label: 导入任务的标签,相同标签的数据无法多次导入。(标签默认保留30分钟)
- column_separator:用于指定导入文件中的列分隔符,默认为\t。
- line_delimiter:用于指定导入文件中的换行符,默认为\n。
- columns:用于指定文件中的列和table中列的对应关系,默认一一对应
- where: 用来过滤导入文件中的数据
- max_filter_ratio:最大容忍可过滤(数据不规范等原因)的数据比例。默认零容忍。数据不规范不包括通过 where 条件过滤掉的行。
- partitions: 用于指定这次导入所设计的partition。如果用户能够确定数据对应的partition,推荐指定该项。不满足这些分区的数据将被过滤掉。
- timeout: 指定导入的超时时间。单位秒。默认是 600 秒。可设置范围为 1 秒 ~ 259200 秒。
- timezone: 指定本次导入所使用的时区。默认为东八区。该参数会影响所有导入涉及的和时区有关的函数结果。
- exec_mem_limit: 导入内存限制。默认为 2GB。单位为字节。
- format: 指定导入数据格式,默认是csv,支持json格式。
- read_json_by_line: 布尔类型,为true表示支持每行读取一个json对象,默认值为false。
- merge_type: 数据的合并类型,一共支持三种类型APPEND、DELETE、MERGE 其中,APPEND是默认值,表示这批数据全部需要追加到现有数据中,DELETE 表示删除与这批数据key相同的所有行,MERGE 语义 需要与delete 条件联合使用,表示满足delete 条件的数据按照DELETE 语义处理其余的按照APPEND 语义处理, 示例:-H "merge_type: MERGE" -H "delete: flag=1"
- delete: 仅在 MERGE下有意义, 表示数据的删除条件 function_column.sequence_col: 只适用于UNIQUE_KEYS,相同key列下,保证value列按照source_sequence列进行REPLACE, source_sequence可以是数据源中的列,也可以是表结构中的一列。
建议一个导入请求的数据量控制在 1 - 2 GB 以内。如果有大量本地文件,可以分批并发提交。
导入普通格式数据
1、创建表
drop table if exists load_local_file_test;
CREATE TABLE IF NOT EXISTS load_local_file_test
(
id INT,
name VARCHAR(50),
age TINYINT
)
unique key(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES("replication_num" = "1");
2、进入doris容器准备导入的数据 --这里是使用docker部署的doris
[root@node1 ~]# docker exec -it doris bash
[root@1a5c6d36820a ~]# vi loadfile.txt
1,zss,28
2,lss,28
3,ww,88
4,zz,99
5,yy,100
6,ls,98
3、导入数据
[root@1a5c6d36820a ~]# curl -u root:123 -H "label:load_local_file" -H "column_separator:," -T /root/loadfile.txt http://172.17.0.2:8040/api/demo/load_local_file_test/_stream_load
注意:status:success表示导入成功。
导入JSON数据
1、创建表
drop table if exists load_local_file_test;
CREATE TABLE IF NOT EXISTS load_local_file_test
(
id INT,
name VARCHAR(50),
age TINYINT
)
unique key(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES("replication_num" = "1");
2、进入doris容器准备导入的数据 --这里是使用docker部署的doris
[root@node1 ~]# docker exec -it doris bash
[root@1a5c6d36820a ~]# vi json.txt
{"id":1,"name":"jack","age":18}
{"id":2,"name":"tatomngyan","age":17}
{"id":3,"name":"jinlitiman","age":19}
{"id":4,"name":"eric","age":20}
{"id":5,"name":"mark","age":18}
3、导入数据
[root@1a5c6d36820a ~]# curl -u root:mis@123 -H "label:load_local_file_json1" -H "columns:id,name,age" -H "max_filter_ratio:0.1" -H "timeout:1000" -H "exec_mem_limit:1G" -H "where:id>1" -H "format:json" -H "read_json_by_line:true" -T /root/json.txt http://172.17.0.2:8040/api/demo/load_local_file_test/_stream_load -H "merge_type:append" -H "merge_type:MERGE"
二、MySQL Load导入
基本原理
MySql Load和Stream Load功能相似, 都是导入本地文件到Doris集群中, 因此MySQL Load实现复用了StreamLoad的基础导入能力:
- FE接收到客户端执行的MySQL Load请求, 完成SQL解析工作
- FE将Load请求拆解,并封装为StreamLoad的请求.
- FE选择一个BE节点发送StreamLoad请求
- 发送请求的同时, FE会异步且流式的从MySQL客户端读取本地文件数据, 并实时的发送到StreamLoad的HTTP请求中.
- MySQL客户端数据传输完毕, FE等待StreamLoad完成, 并展示导入成功或者失败的信息给客户端.
支持数据格式
MySQL Load 支持数据格式:CSV(文本)。
导入语法
LOAD DATA
[LOCAL]
INFILE 'file_name'
INTO TABLE tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[COLUMNS TERMINATED BY 'string']
[LINES TERMINATED BY 'string']
[IGNORE number {LINES | ROWS}]
[(col_name_or_user_var [, col_name_or_user_var] ...)]
[SET (col_name={expr | DEFAULT} [, col_name={expr | DEFAULT}] ...)]
[PROPERTIES (key1 = value1 [, key2=value2]) ]
该语句用于向指定的 table 导入数据,与普通Load区别是,这种导入方式是同步导入。
这种导入方式仍然能够保证一批导入任务的原子性,要么全部数据导入成功,要么全部失败。
- MySQL Load以语法LOAD DATA开头, 无须指定LABEL。
- 指定LOCAL表示读取客户端文件.不指定表示读取FE服务端本地文件. 导入FE本地文件的功能默认是关闭的, 需要在FE节点上设置mysql_load_server_secure_path来指定安全路径, 才能打开该功能。
- INFILE内填写本地文件路径, 可以是相对路径, 也可以是绝对路径.目前只支持单个文件, 不支持多个文件。
- INTO TABLE的表名可以指定数据库名。
- PARTITION语法支持指定分区导入。
- COLUMNS TERMINATED BY指定列分隔符。
- LINES TERMINATED BY指定行分隔符。
- IGNORE num LINES用户跳过CSV的表头, 可以跳过任意行数. 该语法也可以用IGNORE num ROWS代替。
PROPERTIES
- max_filter_ratio:最大容忍可过滤(数据不规范等原因)的数据比例。默认零容忍。
- timeout: 指定导入的超时时间。单位秒。默认是 600 秒。可设置范围为 1 秒 ~ 259200 秒。
- strict_mode: 用户指定此次导入是否开启严格模式,默认为关闭。
- timezone: 指定本次导入所使用的时区。默认为东八区。该参数会影响所有导入涉及的和时区有关的函数结果。
- exec_mem_limit: 导入内存限制。默认为 2GB。单位为字节。
- trim_double_quotes: 布尔类型,默认值为 false,为 true 时表示裁剪掉导入文件每个字段最外层的双引号。
- enclose: 包围符。当csv数据字段中含有行分隔符或列分隔符时,为防止意外截断,可指定单字节字符作为包围符起到保护作用。例如列分隔符为",",包围符为"'",数据为"a,'b,c'",则"b,c"会被解析为一个字段。
- escape: 转义符。用于转义在csv字段中出现的与包围符相同的字符。例如数据为"a,'b,'c'",包围符为"'",希望"b,'c被作为一个字段解析,则需要指定单字节转义符,例如"",然后将数据修改为"a,'b,'c'"。
示例:
1、创建表
drop table if exists load_local_file_test;
CREATE TABLE IF NOT EXISTS load_local_file_test
(
id INT,
name VARCHAR(50),
age TINYINT
)
unique key(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES("replication_num" = "1");
2、本地创建文件,准备数据
[root@node1 ~]# cat demo.txt
1,zss,28
2,lss,28
3,ww,88
4,zz,99
5,yy,100
6,ls,98
3、连接Doris数据库
[root@node1 tmp]# mysql -uroot -P9030 -h192.168.12.100 -p --local-infile
注意:
登录数据库时如果没有指定--local-infile时,导入数据时可能会出现下面的报错。
ERROR 2068 (HY000): LOAD DATA LOCAL INFILE file request rejected due to restrictions on access.
4、导入数据
mysql> use demo
mysql> LOAD DATA LOCAL INFILE '/root/demo.txt' INTO TABLE demo.load_local_file_test COLUMNS TERMINATED BY ',';
导入报错:
mysql> LOAD DATA LOCAL INFILE '/root/demo.txt' INTO TABLE demo.load_local_file_test;
ERROR 1105 (HY000): errCode = 2, detailMessage = [INTERNAL_ERROR]too many filtered rows with load id a7294571-5255-4c2a-9407-e731405626d3
解决方案:
通过show load warnings命令查看详细的报错信息,根据详细信息去分析解决问题。
mysql> show load warnings where label='a7294571-5255-4c2a-9407-e731405626d3';
导入建议:
- MySql Load 只能导入本地文件(可以是客户端本地或者连接的FE节点本地), 而且支持CSV格式。
- 建议一个导入请求的数据量控制在 1 - 2 GB 以内。如果有大量本地文件,可以分批并发提交。




