
Doris 数据的导入导出(学习笔记)
使用 Insert 方式同步数据
用户可以通过 MySQL 协议,使用 INSERT 语句进行数据导入。
INSERT 语句的使用方式和 MySQL 等数据库中 INSERT 语句的使用方式类似。 INSERT 语句支持以下两种语法:
* INSERT INTO table SELECT ...
* INSERT INTO table VALUES(...)
对于 Doris 来说,一个 INSERT 命令就是一个完整的导入事务。
因此不论是导入一条数据,还是多条数据,我们都不建议在生产环境使用这种方式进行数据导入。高频次的 INSERT 操作会导致在存储层产生大量的小文件,会严重影响系统性能。
该方式仅用于线下简单测试或低频少量的操作。
或者可以使用以下方式进行批量的插入操作:
INSERT INTO example_tbl VALUES
(1000, "baidu1", 3.25)
(2000, "baidu2", 4.25)
(3000, "baidu3", 5.25);
导入本地数据
Stream Load 用于将本地文件导入到doris中。Stream Load 是通过 HTTP 协议与 Doris 进行连接交互的。
该方式中涉及 HOST:PORT 都是对应的HTTP 协议端口。
BE 的 HTTP 协议端口,默认为 8040。
FE 的 HTTP 协议端口,默认为 8030。
但须保证客户端所在机器网络能够联通FE, BE 所在机器。
基本原理:
建表语句:
drop table if exists load_local_file_test;
CREATE TABLE IF NOT EXISTS test.load_local_file_test
(
id INT,
name VARCHAR(50),
age TINYINT
)
unique key(id)
DISTRIBUTED BY HASH(id) BUCKETS 3
PROPERTIES
(
"replication_num" = "1"
);
创建一个loadfile.txt
的记事本文件,写入如下数据:
1,zss,28
2,lss,28
3,ww,88
导入数据
执行 curl 命令导入本地文件:
# 语法示例
curl \
-u user:passwd \ # 账号密码
-H "label:load_local_file_test" \ # 本次任务的唯一标识
-T 文件地址 \
http://主机名:端口号/api/库名/表名/_stream_load
curl -u root: -H "label:load_local_file" -H "column_separator:," -T "C:\Users\bob.he\OneDrive - Oerlikon Group\Desktop\project\Doris\loadfile.txt" http://127.0.0.1:8040/api/test/load_local_file_test/_stream_load
参数 | 描述 |
---|---|
user:passwd |
为在 Doris 中创建的用户。初始用户为 root,密码初始状态下为空,[如果有设置以实际为准]。 |
host:port |
为 BE 的 HTTP 协议端口,默认是 8040,可以在 Doris 集群 WEB UI页面查看。 |
label |
可以在 Header 中指定 Label 唯一标识这个导入任务 |
curl的一些可配置的参数
参数 | 描述 |
---|---|
label |
导入任务的标签,相同标签的数据无法多次导入。(标签默认保留30分钟) |
column_separator |
用于指定导入文件中的列分隔符,默认为\t。 |
line_delimiter |
用于指定导入文件中的换行符,默认为\n。 |
columns |
用于指定文件中的列和table中列的对应关系,默认一一对应 例1: 表中有3个列 c1, c2, c3 ,源文件中的三个列一次对应的是c3,c2,c1 ; 那么需要指定-H "columns: c3, c2, c1" 例2: 表中有3个列 c1, c2, c3 , 源文件中前三列依次对应,但是有多余1列;那么需要指定-H "columns: c1, c2, c3, xxx" ;最后一个列随意指定个名称占位即可例3: 表中有3个列 year,month,day 三个列,源文件中只有一个时间列,为2018-06-01 01:02:03 格式;那么可以指定-H "columns: col, year = year(col), month=month(col), day=day(col)" 完成导入 |
where |
用来过滤导入文件中的数据 例1: 只导入大于k1列等于20180601的数据,那么可以在导入时候指定 -H "where: k1 = 20180601" |
max_filter_ratio |
最大容忍可过滤(数据不规范等原因)的数据比例。默认零容忍。数据不规范不包括通过 where 条件过滤掉的行。举例:0.1 就是10% 被过滤掉的数据不能超过总数据的10% |
partitions |
用于指定这次导入所设计的partition。如果用户能够确定数据对应的partition,推荐指定该项。不满足这些分区的数据将被过滤掉。 比如指定导入到p1, p2分区, -H "partitions: p1, p2" |
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可以是数据源中的列,也可以是表结构中的一列。 |
这里我们做个简单的示范,首先创建一个json.txt
的json数据,数据如下:
{"id":1,"name":"zs","age":18}
{"id":2,"name":"lisi","age":18}
{"id":3,"name":"ww","age":18}
{"id":4,"name":"zl","age":18}
{"id":5,"name":"tq","age":18}
然后我们举个例子,使用 root 用户和空密码,将本地 JSON 文件(json.txt
)导入到 Doris 数据库中,设置了任务标签为 load_local_file_json_20221126,列名为 id、name、age,允许最多 10% 的数据被过滤,超时时间为 1000 秒,只导入 id 大于 1 的数据,数据格式为 JSON,逐行读取 JSON 文件,并在导入时删除旧数据。
curl -u root: -H "label:load_local_file_json_20221126" -H "columns:id,name,age" -H "max_filter_ratio:0.1" -H "timeout:1000" -H "where:id>1" -H "format:json" -H "read_json_by_line:true" -H "merge_type:delete" -T "C:\Users\bob.he\OneDrive - Oerlikon Group\Desktop\project\Doris\json.txt" http://127.0.0.1:8040/api/test/load_local_file_test/_stream_load
我们发现只有1条数据了,原因是我们导入的数据id大于1的数据,所以id为1的在原来的数据中不受影响。
但是在2和3本身就存在数据了所以由于冲突直接删除数据,4和5数据并没有添加。
如果我们希望添加就直接将merge_type
改成append
,当冲突时会进行追加的,然后将label
改成改一下:
curl -u root: -H "label:load_local_file_json_20221128" -H "columns:id,name,age" -H "max_filter_ratio:0.1" -H "timeout:1000" -H "where:id>1" -H "format:json" -H "read_json_by_line:true" -H "merge_type:append" -T "C:\Users\bob.he\OneDrive - Oerlikon Group\Desktop\project\Doris\json.txt" http://127.0.0.1:8040/api/test/load_local_file_test/_stream_load
由于我们这里的表结构是unique
所以如果再次添加由于key相同的关系会覆盖。
我们将json
中的文本数据改改:
{"id":1,"name":"zs","age":18}
{"id":2,"name":"lisi","age":18}
{"id":3,"name":"ww","age":19}
{"id":4,"name":"zl","age":19}
{"id":5,"name":"tq","age":19}
然后我们使用MERGE
的类型,并且当冲突时删除id=3
的数据。
执行命令如下:
curl -u root: -H "label:load_local_file_json_20221129" -H "columns:id,name,age" -H "max_filter_ratio:0.1" -H "timeout:1000" -H "where:id>1" -H "format:json" -H "read_json_by_line:true" -H "merge_type:MERGE" -H "delete:id=3" -T "C:\Users\bob.he\OneDrive - Oerlikon Group\Desktop\project\Doris\json.txt" http://127.0.0.1:8040/api/test/load_local_file_test/_stream_load
导入建议
● Stream Load 只能导入本地文件。
● 建议一个导入请求的数据量控制在 1 - 2 GB 以内。如果有大量本地文件,可以分批并发提交。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

