建hive表:
drop table tmp_txzl_as2;
CREATE TABLE `tmp_txzl_as2`(
`signalid` string,
`day_id` string,
`cnts` int)
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim'=',',
'serialization.format'=',')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'hdfs://nameservice1/user/hive/test/tmp_txzl_as2'
TBLPROPERTIES (
'transient_lastDdlTime'='1611109065');
插入数据
insert into tmp_txzl_as2 values("189971997","20210707",1),
("189023234","20210707",1),
("180093111","20210707",1),
("133807928","20210707",1),
("133679691","20210707",1);
建Doris表:
drop table tmp_txzl_as;
CREATE TABLE `tmp_txzl_as` (
`signalid` varchar(32) default '',
`day_id` varchar(32) default '',
cnts int default '1'
) ENGINE=OLAP
DUPLICATE KEY(`signalid`)
COMMENT "OLAP"
DISTRIBUTED BY HASH(`day_id`) BUCKETS 10
PROPERTIES (
"replication_num" = "3",
"in_memory" = "false"
);
导数据
LOAD LABEL testlabel9
(
DATA INFILE("hdfs://dn1.hadoop:8020/user/hive/test/tmp_txzl_as2/test.txt")
INTO TABLE tmp_txzl_as
COLUMNS TERMINATED BY ','
(signalid,day_id,cnts)
SET
(signalid=signalid,day_id=day_id,cnts=cnts)
)
WITH BROKER 'broker1'
(
"username" = "hpp",
"password" = "m4x_1",
"dfs.nameservices" = "nameservice1",
"dfs.ha.namenodes.nameservice1" = "namenode41,namenode74",
"dfs.namenode.rpc-address.nameservice1.namenode41" = "dn1.hadoop:8020",
"dfs.namenode.rpc-address.nameservice1.namenode74" = "dn3.hadoop:8020",
"dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
)
PROPERTIES
(
"timeout"="3600",
"max_filter_ratio"="0.1",
"timezone"="Asia/Shanghai"
);
SHOW LOAD WHERE LABEL = "testlabel9"; 查看任务是否成功finished 失败/cancelled
数据源的分区字段为date类型 成功案例:
hive数据模拟
insert into table test_tb partition(day_id="20210606")
select
signalid,
callid,
caller,
callee from tb2;
drop table test_tb;
CREATE TABLE `test_tb`(
`signalid` string,
`callid` string,
`caller` string,
`callee` string)
PARTITIONED BY (
`day_id` date)
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
WITH SERDEPROPERTIES (
'field.delim'='\t',
'serialization.format'='\t')
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat';
insert into test_tb partition(day_id="2021-06-06")
select signalid,callid,caller,callee from tb2;
doris准备工作:
建复合分区表
CREATE TABLE test.test_tb
(
signalid varchar(32),
callid varchar(32),
caller varchar(32),
callee varchar(32),
day_id DATE
)
ENGINE=olap
PARTITION BY RANGE (day_id)
(
PARTITION p1 VALUES LESS THAN ("2021-05-01"),
PARTITION p2 VALUES LESS THAN ("2021-06-01"),
PARTITION p3 VALUES LESS THAN ("2021-07-01"),
PARTITION p4 VALUES LESS THAN ("2021-08-01")
)
DISTRIBUTED BY HASH(day_id) BUCKETS 31
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "10"
);
ENGINE:默认是olap,也可以是 mysql、broker、es等,但是这些事创建外表使用,推荐olap;
AGGREGATE KEY:表会按照这后面的列进行聚合
PARTITION BY:实际按什么字段分区(如果不做复合分区就不用添加)
DISTRIBUTED BY:按什么字段分桶
dynamic_partition.enable:默认为false,true表示开启动态分区
dynamic_partition.time_unit:按什么字时间进行分区,可选择为HOUR,DAY,WEEK,MONTH
dynamic_partition.end:用于指定提前创建的分区数量,值必须大于0
dynamic_partition.prefix:用于指定自动创建的分区名前缀,但是本文已经制定分区值了,就用不上这个参数
dynamic_partition.buckets:用于指定自动创建的分区分桶数量
LOAD LABEL doris_table2
(
DATA INFILE(“hdfs://nameservice1/user/hive/warehouse/test_db.db/test_tb//”)
INTO TABLE test_tb
COLUMNS TERMINATED BY “\t”
format as ‘ORC’
(signalid,callid,caller,callee)
COLUMNS FROM PATH AS (day_id)
)
WITH BROKER broker1 (
“username” = “hbapp”,
“password” = “3_#2S!wm4x_1”,
“dfs.nameservices” = “nameservice1”,
“dfs.ha.namenodes.nameservice1” = “namenode41,namenode74”,
“dfs.namenode.rpc-address.nameservice1.namenode41” = “dn1.hadoop:8020”,
“dfs.namenode.rpc-address.nameservice1.namenode74” = “dn3.hadoop:8020”,
“dfs.client.failover.proxy.provider” = “org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider”
)
PROPERTIES (
“timeout” = “3600”,
“max_filter_ratio” = “0.1”,
“timezone” = “Asia/Shanghai”);
SHOW LOAD WHERE LABEL = “doris_table2”;
重要参数解释:
(type,id,…,ip):对应hive列的顺序,名称可以不一样,但是需导入doris的列必须和doris列名一致才能自动导入
columns from path as (dt):读取hdfs路径上值作为传入doris的参数
set (cnt = 1):相当于给源表增加一列,这样进doris时就有预聚合后的cnt
hive数据模拟
insert into table test_tb2 partition(day_id="20210607")
select
signalid,
callid,
caller,
callee from tb1;
drop table test_tb;
CREATE TABLE `test_tb2`(
`signalid` string,
`callid` string,
`caller` string,
`callee` string)
PARTITIONED BY (
`day_id` string)
ROW FORMAT SERDE
'org.apache.hadoop.hive.ql.io.orc.OrcSerde'
WITH SERDEPROPERTIES (
'field.delim'='\t',
'serialization.format'='\t')
STORED AS INPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat';
insert into test_tb partition(day_id="2021-06-06")
select signalid,callid,caller,callee from tb2;
doris准备工作:
建复合分区表
CREATE TABLE test.test_tb2
(
signalid varchar(32),
callid varchar(32),
caller varchar(32),
callee varchar(32),
day_id date
)
ENGINE=olap
PARTITION BY RANGE (day_id)
(
PARTITION p1 VALUES LESS THAN ("2021-05-01"),
PARTITION p2 VALUES LESS THAN ("2021-06-01"),
PARTITION p3 VALUES LESS THAN ("2021-07-01"),
PARTITION p4 VALUES LESS THAN ("2021-08-01")
)
DISTRIBUTED BY HASH(day_id) BUCKETS 31
PROPERTIES (
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.end" = "3",
"dynamic_partition.prefix" = "p",
"dynamic_partition.buckets" = "10"
);
LOAD LABEL doris_table3
(
DATA INFILE("hdfs://nameservice1/user/hive/warehouse/test_db.db/test_tb2/*/*")
INTO TABLE `test_tb2`
COLUMNS TERMINATED BY "\t"
format as 'ORC'
(signalid,callid,caller,callee)
COLUMNS FROM PATH AS (day_id)
)
WITH BROKER broker1 (
"username" = "hpp",
"password" = "3_1",
"dfs.nameservices" = "nameservice1",
"dfs.ha.namenodes.nameservice1" = "namenode41,namenode74",
"dfs.namenode.rpc-address.nameservice1.namenode41" = "dn1.hadoop:8020",
"dfs.namenode.rpc-address.nameservice1.namenode74" = "dn3.hadoop:8020",
"dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
)
PROPERTIES (
"timeout" = "3600",
"max_filter_ratio" = "0.1",
"timezone" = "Asia/Shanghai");
SHOW LOAD WHERE LABEL = "doris_table3";
**
**
1.文件路径是否正确 ;
2.检查数据格式是否正常(COLUMNS TERMINATED BY ‘,’) ;
3. 检查数据是否有压缩格式(format as ORC)
语法:
LOAD LABEL load_label
(
data_desc1[, data_desc2, ...]
)
WITH BROKER broker_name
[broker_properties]
[opt_properties];
1. load_label
当前导入批次的标签。在一个 database 内唯一。
语法:
[database_name.]your_label
2. data_desc
用于描述一批导入数据。
语法:
[MERGE|APPEND|DELETE]
DATA INFILE
(
"file_path1"[, file_path2, ...]
)
[NEGATIVE]
INTO TABLE `table_name`
[PARTITION (p1, p2)]
[COLUMNS TERMINATED BY "column_separator"]
[FORMAT AS "file_type"]
[(column_list)]
[PRECEDING FILTER predicate]
[SET (k1 = func(k2))]
[WHERE predicate]
[DELETE ON label=true]
[ORDER BY source_sequence]
说明:
file_path:
文件路径,可以指定到一个文件,也可以用 * 通配符指定某个目录下的所有文件。通配符必须匹配到文件,而不能是目录。
PARTITION:
如果指定此参数,则只会导入指定的分区,导入分区以外的数据会被过滤掉。
如果不指定,默认导入table的所有分区。
NEGATIVE:
如果指定此参数,则相当于导入一批“负”数据。用于抵消之前导入的同一批数据。
该参数仅适用于存在 value 列,并且 value 列的聚合类型仅为 SUM 的情况。
column_separator:
用于指定导入文件中的列分隔符。默认为 \t
如果是不可见字符,则需要加\\x作为前缀,使用十六进制来表示分隔符。
如hive文件的分隔符\x01,指定为"\\x01"
file_type:
用于指定导入文件的类型,例如:parquet、orc、csv。默认值通过文件后缀名判断。
column_list:
用于指定导入文件中的列和 table 中的列的对应关系。
当需要跳过导入文件中的某一列时,将该列指定为 table 中不存在的列名即可。
语法:
(col_name1, col_name2, ...)
PRECEDING FILTER predicate:
用于过滤原始数据。原始数据是未经列映射、转换的数据。用户可以在对转换前的数据前进行一次过滤,选取期望的数据,再进行转换。
SET:
如果指定此参数,可以将源文件某一列按照函数进行转化,然后将转化后的结果导入到table中。语法为 `column_name` = expression。举几个例子帮助理解。
例1: 表中有3个列“c1, c2, c3", 源文件中前两列依次对应(c1,c2),后两列之和对应c3;那么需要指定 columns (c1,c2,tmp_c3,tmp_c4) SET (c3=tmp_c3+tmp_c4);
例2: 表中有3个列“year, month, day"三个列,源文件中只有一个时间列,为”2018-06-01 01:02:03“格式。
那么可以指定 columns(tmp_time) set (year = year(tmp_time), month=month(tmp_time), day=day(tmp_time)) 完成导入。
WHERE:
对做完 transform 的数据进行过滤,符合 where 条件的数据才能被导入。WHERE 语句中只可引用表中列名。
merge_type:
数据的合并类型,一共支持三种类型APPEND、DELETE、MERGE 其中,APPEND是默认值,表示这批数据全部需要追加到现有数据中,DELETE 表示删除与这批数据key相同的所有行,MERGE 语义 需要与delete on条件联合使用,表示满足delete 条件的数据按照DELETE 语义处理其余的按照APPEND 语义处理,
delete_on_predicates:
表示删除条件,仅在 merge type 为MERGE 时有意义,语法与where 相同
ORDER BY:
只适用于UNIQUE_KEYS,相同key列下,保证value列按照source_sequence进行REPLACE, source_sequence可以是数据源中的列,也可以是表结构中的一列。
3. broker_name
所使用的 broker 名称,可以通过 show broker 命令查看。
4. broker_properties
用于提供通过 broker 访问数据源的信息。不同的 broker,以及不同的访问方式,需要提供的信息不同。
3. Apache HDFS
社区版本的 hdfs,支持简单认证、kerberos 认证。以及支持 HA 配置。
简单认证:
hadoop.security.authentication = simple (默认)
username:hdfs 用户名
password:hdfs 密码
namenode HA:
通过配置 namenode HA,可以在 namenode 切换时,自动识别到新的 namenode
dfs.nameservices: 指定 hdfs 服务的名字,自定义,如:"dfs.nameservices" = "my_ha"
dfs.ha.namenodes.xxx:自定义 namenode 的名字,多个名字以逗号分隔。其中 xxx 为 dfs.nameservices 中自定义的名字,如 "dfs.ha.namenodes.my_ha" = "my_nn"
dfs.namenode.rpc-address.xxx.nn:指定 namenode 的rpc地址信息。其中 nn 表示 dfs.ha.namenodes.xxx 中配置的 namenode 的名字,如:"dfs.namenode.rpc-address.my_ha.my_nn" = "host:port"
dfs.client.failover.proxy.provider:指定 client 连接 namenode 的 provider,默认为:org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
4. opt_properties
用于指定一些特殊参数。
语法:
[PROPERTIES ("key"="value", ...)]
可以指定如下参数:
timeout: 指定导入操作的超时时间。默认超时为4小时。单位秒。
max_filter_ratio:最大容忍可过滤(数据不规范等原因)的数据比例。默认零容忍。
exec_mem_limit: 导入内存限制。默认为 2GB。单位为字节。
strict mode: 是否对数据进行严格限制。默认为 false。
timezone: 指定某些受时区影响的函数的时区,如 strftime/alignment_timestamp/from_unixtime 等等,具体请查阅 [时区] 文档。如果不指定,则使用 "Asia/Shanghai" 时区。
5. 导入数据格式样例
整型类(TINYINT/SMALLINT/INT/BIGINT/LARGEINT):1, 1000, 1234
浮点类(FLOAT/DOUBLE/DECIMAL):1.1, 0.23, .356
日期类(DATE/DATETIME):2017-10-03, 2017-06-13 12:34:03。
(注:如果是其他日期格式,可以在导入命令中,使用 strftime 或者 time_format 函数进行转换)
字符串类(CHAR/VARCHAR):"I am a student", "a"
NULL值:\N
https://cloud.baidu.com/doc/PALO/s/Wksis5irl
https://www.kancloud.cn/dorisdb/dorisdb/2146014
http://doris.apache.org/master/zh-CN/installing/compilation.html
https://www.bookstack.cn/read/ApacheDoris-0.12-zh/6b96ad4546db2580.md
/data/app/doris-0.14.7/be/storage/data
[hbapp@dn1 data]$ find ./* -type f
./1019/10083/1547751918/02000000000005dd6d462e2779955cdd6c5866af5a61ed9e_0.dat
./183/15295/1587162996/02000000000007046d462e2779955cdd6c5866af5a61ed9e_0.dat
./183/15295/1587162996/02000000000006e56d462e2779955cdd6c5866af5a61ed9e_0.dat
./208/15395/1587162996/02000000000007056d462e2779955cdd6c5866af5a61ed9e_0.dat
./208/15395/1587162996/02000000000006e66d462e2779955cdd6c5866af5a61ed9e_0.dat
**
**
Doris 可以通过滚动升级的方式,平滑进行升级。建议按照以下步骤进行安全升级。
注:
1.以下方式均建立在高可用部署的情况下。即数据 3 副本,FE 高可用情况下。
测试 BE 升级正确性
1.任意选择一个 BE 节点,部署最新的 palo_be 二进制文件。
2.重启 BE 节点,通过 BE 日志 be.INFO,查看是否启动成功。
3.如果启动失败,可以先排查原因。如果错误不可恢复,可以直接通过 DROP BACKEND 删除该 BE、清理数据后,使用上一个版本的 palo_be 重新启动 BE。然后重新 ADD BACKEND。(该方法会导致丢失一个数据副本,请务必确保3副本完整的情况下,执行这个操作!!!)
测试 FE 元数据兼容性
1.重要!!元数据兼容性异常很可能导致数据无法恢复!!
2.单独使用新版本部署一个测试用的 FE 进程(比如自己本地的开发机)。
3.修改测试用的 FE 的配置文件 fe.conf,将所有端口设置为与线上不同。
4.在 fe.conf 添加配置:cluster_id=123456
5.在 fe.conf 添加配置:metadata_failure_recovery=true
6.拷贝线上环境 Master FE 的元数据目录 palo-meta 到测试环境
7.将拷贝到测试环境中的 palo-meta/image/VERSION 文件中的 cluster_id 修改为 123456(即与第3步中相同)
8.在测试环境中,运行 sh bin/start_fe.sh 启动 FE
9.通过 FE 日志 fe.log 观察是否启动成功。
10.如果启动成功,运行 sh bin/stop_fe.sh 停止测试环境的 FE 进程。
11.以上 2-6 步的目的是防止测试环境的FE启动后,错误连接到线上环境中。
升级准备
1.在完成数据正确性验证后,将 BE 和 FE 新版本的二进制文件分发到各自目录下。
2.通常小版本升级,BE 只需升级 palo_be;而 FE 只需升级 palo-fe.jar。如果是大版本升级,则可能需要升级其他文件(包括但不限于 bin/ lib/ 等等)如果你不清楚是否需要替换其他文件,建议全部替换。
滚动升级
1.确认新版本的文件部署完成后。逐台重启 FE 和 BE 实例即可。
2.建议逐台重启 BE 后,再逐台重启 FE。因为通常 Doris 保证 FE 到 BE 的向后兼容性,即老版本的 FE 可以访问新版本的 BE。但可能不支持老版本的 BE 访问新版本的 FE。
3.建议确认前一个实例启动成功后,在重启下一个实例。实例启动成功的标识,请参阅安装部署文档。
所有 3 位版本可以安全的从对应的官方 2 位版本升级。3 位版本本身也是兼容的,可以安全升级。举例如下:
官方 0.12.0-rc02 可以升级至 0.12.21-release
0.11.10-release 可以升级至 0.11.44-release
0.11.44-release 可以升级至 0.12.21-release
建议在升级 2 位版本之前,先升级到对应的最新的 3 位版本后,再升级 2 位版本。举例如下:
1.当前使用版本为 0.11.10-release,想升级到 0.12 版本。
2.首先升级到 0.11.44-release,即 0.11 的最新 3 位版本。
3.再升级到 0.12.21-release,即 0.12 的最新 3 位版本。
3 位迭代版本也可以安全的和官方 2 位版本升级。如以下的升级序列是安全的
实操案例0.14.7升级到0.14.12.4
① 删除新编译好的doris的fe和be的配置文件
rm -rf output/fe/conf/* rm -rf output/be/conf/*
② 拷贝之前编译好的配置文件和数据
注意,现在需要停止对Doris集群进行操作
cp -r ../incubator-doris-master/output/fe/conf/* output/fe/conf cp -r ../incubator-doris-master/output/be/conf/* output/be/conf cp -r ../incubator-doris-master/output/fe/log output/fe cp -r ../incubator-doris-master/output/be/log output/be cp -r ../incubator-doris-master/output/fe/doris-meta output/fe cp -r ../incubator-doris-master/output/be/storage output/be
因为有的节点只有fe或者be,所以并不是所有的路径都存在,路径不存在问题不用理会,只要保证有用的数据都拷贝好就可以了。
关闭“发送键输入到所有会话”功能,逐一检查数据是否都已经拷贝好
5.升级集群
升级集群应该先升级be节点,后升级fe节点,并采用逐一升级的方式
***① 升级BE***
先操作node2节点
退出原有be节点 (具体的路径以自己安装的路径为准)
/opt/incubator-doris-master/output/be/bin/stop_be.sh
启动新的be进程
/opt/incubator-doris-DORIS-0.13.15-release/output/be/bin/start_be.sh --daemon
用MySQL Client登录Doris集群,输入SQL语句,检查be是否正常
show proc "/backends";
发现新的be已经正常运行(alive=true),并且be的版本号已经升级为新的版本号
按照相同的方式,将34567的be节点都逐一更换为新版本的be
直至所有的be都已经升级完成
② 升级FE(升级前一定要保证兼容性测试成功)
升级fe之前需要做元数据的兼容性测试,以下是官网给出的测试方式,最好还是测一下再整
经过测试后,新的fe对元数据的兼容性没问题,
保证所有的be都已经升级完成之后,再升级fe
和升级be同样的方式,先关闭老fe的进程,再开启新fe的进程,我们升级,先升级非Master节点,最后再升级Master节点
关闭老fe进程
/opt/incubator-doris-master/output/fe/bin/stop_fe.sh
开启新的fe进程
/opt/incubator-doris-DORIS-0.13.15-release/output/fe/bin/start_fe.sh --daemon
逐一检查状态
最终检查状态
如果fe的升级过程中,某个节点出现如下问题
是因为在升级过程中,兼容性出现问题,或者是元数据发生变化造成新旧数据无法对应。只好将新的fe目录下的元数据信息删除,在进行启动了
rm -rf /opt/incubator-doris-DORIS-0.13.15-release/output/fe/doris-meta/
启动命令用helper方式启动
/opt/incubator-doris-DORIS-0.13.15-release/output/fe/bin/start_fe.sh --helper 192.168.124.11:9010 --daemon
删除所有节点新版本文件的be/fe 的log conf 目录
删除broker的conf目录
copy旧版本的log conf到对应的新版本目录下
将fe/be的元数据目录拷贝到对应新版本目录下(配置文件中的路径需要修改)
逐一停掉旧版本的be 启动新版本be 查看是否版本升级了 成功后执行下一个节点 所有be升级完毕再逐一升级fe版本(优先升级非主节点) 先停掉老版本在启动新版本,启动时采用helper启动
/opt/incubator-doris-DORIS-0.13.15-release/output/fe/bin/start_fe.sh --helper 192.168.124.11:9011 --daemon (9010端口改成了9011 /fe通信端口)
mysql> SHOW PROC '/frontends';
mysql> SHOW PROC '/backends'\G;
SHOW BROKER