前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >0913-7.7.1-Replication Manager使用优化

0913-7.7.1-Replication Manager使用优化

作者头像
Fayson
发布于 2024-03-05 10:11:04
发布于 2024-03-05 10:11:04
19500
代码可运行
举报
文章被收录于专栏:Hadoop实操Hadoop实操
运行总次数:0
代码可运行

1 源集群中Hive数据分析

1.1 Hive Stats元数据解析

在当前CDP的大部分的场景中,PART_COL_STATSTAB_COL_STATS这两张Hive元数据表都会比较大。因为这两张表是分别存放分区表和非分区表的一些字段上的统计信息,而在CDP中Hive的CBO、Mapjoin和谓词下推等优化查询功能默认是开启的,而这些优化功能又需要基于这些统计信息来做优化,所以在一个已经稳定运行的生产环境中,对应的这两张表可能有非常庞大的数据量(上千万甚至于上亿)。

1.2 分区表

1.在源集群中创建一张表testbdr1,并为其写入几条数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create external table testbdr1 (id string,name string,sex string) partitioned by (daytime string);
insert into table testbdr1 partition (daytime = '20231101') values ('zhangsan','1','boy'),('wangwu','2','boy');
insert into table testbdr1 partition (daytime = '20231102') values ('hahah','3','boy'),('eqweq','4','boy');
insert into table testbdr1 partition (daytime = '20231103') values ('dadsa','5','boy'),('cadeqw','6','boy');
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from testbdr1;

2.查看Hive元数据表信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from PART_COL_STATS where TABLE_NAME = 'testbdr1';

1.3 非分区表

1.在源集群中创建一张表testbdr1,并为其写入几条数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
create external table testbdr2 (id string,name string,sex string);
insert into table testbdr2 values ('1','zhangsan','boy');
insert into table testbdr2 values ('2','dasdas','boy');
insert into table testbdr2 values ('3','daskhdkad','boy');
select * from testbdr2;

2.查看Hive元数据表信息

2 BDR Hive同步任务

2.1 BDR Hive Replication使用介绍

1.BDR Hive Replication作业,在配置页面有高级参数可以配置,如下:

2.资源页面介绍(资源池页面的配置主要针对于Replication MR任务)

Scheduler池: 这里可以指定MR任务运行在哪个资源池,如果MR复制阶段运行较慢,可以考虑将任务发起到一个资源充足的资源池,保障MR的运行速度。

最大Map时隙:指的是 MR任务发起的时候,Map Task的数量,如果MR复制任务需要复制的数据量较大或者文件数量较多,可以考虑适当的加大该值,保证MR的运行速度。

最大带宽: 指的是每个Map Task可以使用到的带宽。

File Listing Threads/复制策略: 一般建议保持默认即可。

3.高级配置页面介绍

Hive复制: 这里可以选择是否同样复制HDFS文件(也就是真实数据),如果不勾选则只同步Hive元数据。

Impala Metadata: 勾选后在BDR同步结束时会对Impala执行invalidate Metadata的动作,这里一般不建议勾选。

Directory for MetadataFile: 这里可以输入一个自定义HDFS路径,作为BDR的临时目录,一般不单独指定,默认使用BDR任务执行用户目录。

Number of concurrent HMS connections: 这里指导入Hive MetaStore的BDR任务线程数量,默认值为4,如果同步的表数量较多,元数据量较大,可以适当加大该值。

MapReduce 服务: 这里保持默认即可。

日志路径: 一般不进行修改,默认路径为process进程目录。

错误处理: 对于BDR任务的错误处理,根据需求来选择处理方式即可。

保留: 这里指从源端同步过来的数据,保留的信息有哪些,根据需求选择对应的保留即可。

删除策略: 这里指的是从源端同步过来的数据,目标端如果有需要删除的文件,如果进行删除,这里根据需求选择即可,一般建议保存到Trash。

警报: 一般保持默认即可。

2.2 当前元数据检查

1.在目标集群中查询这两张Stats表的数据

当前没有这两张表的信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from PART_COL_STATS;
select * from TAB_COL_STATS;

2.使用BDR将源集群中的testbdr1和testbdr2表同步过来

同步任务

同步完成

3.元数据检查

可以看到元数据已经同步过来了,带着States信息也被一起拷贝过来了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select * from PART_COL_STATS;
select * from TAB_COL_STATS;
select * from TBLS where TBL_NAME like 'test%'

2.3 同步执行过程分析

2.3.1 元数据同步,不同步真实数据

1.可以看到,这种同步方式,Replication总共只有如下三个步骤

2.导出远程Hive MetaStore这一个步骤会在源端发起一个导出的命令,以BDR配置的表信息等为准

3.传输元数据文件的本质就是一个Distcp任务,将元数据文件等在源端导出的信息拷贝到目标集群中

4.导入Hive MetaStore就是将拷贝过来的元数据文件导入进目标端的数据库中,使Hive可读

2.3.2 元数据和真实数据同步

1.这种同步方式相对于只同步元数据,不同步真实数据这个方式来说,只多了两个步骤

2.Hive表数据复制这个步骤,总的来说就是需要拷贝的文件会形成一个列表,然后对于这个列表源集群和目标集群都会进行一个check的动作,最后通过一个Distcp的命令将数据复制过来

3.最后一步Rename Snapshots,这个是如果源集群有启用快照的话,同步完成之后会重命名同步后的快照文件,没有启用快照则跳过

3 BDR同步优化

3.1 Partition Ignored优化

可以如下参考文档:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://docs.cloudera.com/replication-manager/cloud/operations/topics/rm-pc-troubleshoot6.html

The partition parameter names you provide are not compared during the import stage of the partition metadata replication process. Therefore, even if the partition parameters do not match between the exported and existing partitions, the partition is not dropped or recreated. After you configure this key-value pair, the import stage of the partition metadata replication process completes faster.

1.进入CM,点击Hive > 配置 > 搜索replication,添加如下配置参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HIVE_IGNORED_PARTITION_PARAMETERS=transient_lastDdlTime,totalSize,numRows,COLUMN_STATS_ACCURATE,numFiles

2.保存配置即可,该配置修改不需要重启服务

3.重新发起BDR任务,与之前的任务比对

修改参数之前:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dr/chive.sh ["-i","-o","-b","-t","default:testbdr1","-t","default:testbdr2","-f","/user/hdfs/.cm/hive-staging/2023-12-29-03-25-13-3751/export.json","-d","-h","-v","-x","-scheduleId","51","-scheduleName","test","-numThreads","4"]

修改参数之后:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dr/chive.sh ["-i","-o","-b","-t","default:testbdr1","-t","default:testbdr2","-f","/user/hdfs/.cm/hive-staging/2023-12-29-03-48-49-3831/export.json","-d","-h","-v","-x","-scheduleId","51","-scheduleName","test","-numThreads","4","-ignoredPartitionParameter","totalSize","-ignoredPartitionParameter","numRows","-ignoredPartitionParameter","COLUMN_STATS_ACCURATE","-ignoredPartitionParameter","numFiles","-ignoredPartitionParameter","transient_lastDdlTime"]

经过如上比对,可以发现该配置已经生效,正常的加入了Hive Replication中

3.2 Replication Advanced优化

1.进入BDR Hive Replication配置高级参数页面,加大Hive MetaStore concurrent Thread

2.执行该任务,可以看到Hive MetaStore connecting已经变多了,实际中根据需求来进行调整该值,即可达到加快Hive元数据导入的效果

加大线程之前:

加大线程之后:

3.3 Partition/Col Stats优化

参考文档:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://docs.cloudera.com/cdp-private-cloud-base/7.1.8/manager-release-notes/topics/chf14-cm-771.html

3.3.1 场景叙述

1.发起一个BDR Hive Replication任务

2.任务执行完成,进行任务分析

任务完成:

MySQL Binlog检查分析:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat mysqld.log | grep -i part_col

SELECT 'org.apache.hadoop.hive.metastore.model.MPartitionColumnStatistics' AS `NUCLEUS_TYPE`,`A0`.`AVG_COL_LEN`,`A0`.`CAT_NAME`,`A0`.`COLUMN_NAME`,`A0`.`COLUMN_TYPE`,`A0`.`DB_NAME`,`A0`.`BIG_DECIMAL_HIGH_VALUE`,`A0`.`BIG_DECIMAL_LOW_VALUE`,`A0`.`DOUBLE_HIGH_VALUE`,`A0`.`DOUBLE_LOW_VALUE`,`A0`.`ENGINE`,`A0`.`LAST_ANALYZED`,`A0`.`LONG_HIGH_VALUE`,`A0`.`LONG_LOW_VALUE`,`A0`.`MAX_COL_LEN`,`A0`.`NUM_DISTINCTS`,`A0`.`NUM_FALSES`,`A0`.`NUM_NULLS`,`A0`.`NUM_TRUES`,`A0`.`PARTITION_NAME`,`A0`.`TABLE_NAME`,`A0`.`CS_ID`,`A0`.`PARTITION_NAME` AS `NUCORDER0` FROM `PART_COL_STATS` `A0` WHERE `A0`.`TABLE_NAME` = 'testbdr1' AND `A0`.`DB_NAME` = 'default' AND `A0`.`CAT_NAME` = 'hive' AND `A0`.`ENGINE` = 'hive' AND `A0`.`PARTITION_NAME` = 'daytime=20231101' AND (((`A0`.`COLUMN_NAME` = 'id') OR (`A0`.`COLUMN_NAME` = 'name')) OR (`A0`.`COLUMN_NAME` = 'sex')) ORDER BY `NUCORDER0`;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat mysqld.log | grep -i part_col | wc -l
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat mysqld.log | grep -i tab_col

SELECT 'org.apache.hadoop.hive.metastore.model.MTableColumnStatistics' AS `NUCLEUS_TYPE`,`A0`.`AVG_COL_LEN`,`A0`.`CAT_NAME`,`A0`.`COLUMN_NAME`,`A0`.`COLUMN_TYPE`,`A0`.`DB_NAME`,`A0`.`BIG_DECIMAL_HIGH_VALUE`,`A0`.`BIG_DECIMAL_LOW_VALUE`,`A0`.`DOUBLE_HIGH_VALUE`,`A0`.`DOUBLE_LOW_VALUE`,`A0`.`ENGINE`,`A0`.`LAST_ANALYZED`,`A0`.`LONG_HIGH_VALUE`,`A0`.`LONG_LOW_VALUE`,`A0`.`MAX_COL_LEN`,`A0`.`NUM_DISTINCTS`,`A0`.`NUM_FALSES`,`A0`.`NUM_NULLS`,`A0`.`NUM_TRUES`,`A0`.`TABLE_NAME`,`A0`.`CS_ID` FROM `TAB_COL_STATS` `A0` WHERE `A0`.`TABLE_NAME` = 'testbdr2' AND `A0`.`DB_NAME` = 'default' AND `A0`.`CAT_NAME` = 'hive' AND `A0`.`ENGINE` = 'hive' AND (((`A0`.`COLUMN_NAME` = 'id') OR (`A0`.`COLUMN_NAME` = 'name')) OR (`A0`.`COLUMN_NAME` = 'sex'));
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat mysqld.log | grep -i tab_col | wc -l

从上图中可以看到,同步testbdr1和testbdr2的时候,在MySQL的PART_COL_STATS和TAB_COL_STATS这两张表里进行了多次的连续查询,我们接下来去查看源端中这两张表的数据量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
show create table testbdr1;
show create table testbdr2;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select count(*) from testbdr1;
select count(*) from testbdr2;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
show partitions testbdr1;

从上图的查询中可以看到,表testbdr1和testbdr2,都是字段少、数据量小、分区少的测试表,但是同步这两张表都会在MySQL中进行如此复杂的查询,并且查询了多次。那么当一个集群已经平稳运行了较长时间,元数据表PART_COL_STATS和TAB_COL_STATS表也有上千万数据量的时候,同步Hive元数据就会花费特别长的时间,来做这些在数据库内的查询。

3.3.2 优化方案

1.进入CM,点击Hive > 配置 > 搜索Replication,添加如下配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SKIP_COLUMN_STATS_IMPORT=true

2.重新发起BDR任务

这里为了直观的观察,我们先将目标端的元数据PART_COL_STATS和TAB_COL_STATS清空

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
truncate PART_COL_STATS;
truncate TAB_COL_STATS;
select count(*) from PART_COL_STATS;
select count(*) from TAB_COL_STATS;

发起任务:

元数据库检查:

可以看到,STATS信息已经没再更新,参数成功生效:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
select count(*) from TAB_COL_STATS;
select count(*) from PART_COL_STATS;
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-02-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hadoop实操 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Golang 反射
在Go语言中,大多数时候值/类型/函数非常直接,要的话,定义一个。你想要个Struct
李海彬
2019/03/07
9590
Golang 反射
013.反射reflection
反射reflection 反射可大大提高程序的灵活性,使得 interface{} 有更大的发挥余地 反射使用 TypeOf 和 ValueOf 函数从接口中获取目标对象信息 反射会将匿名字段作为独立字段(匿名字段本质) 想要利用反射修改对象状态,前提是 interface.data 是 settable, 即 pointer-interface 通过反射可以“动态”调用方法 ---- package main import ( "fmt" "reflect" ) type User
qubianzhong
2018/08/15
2300
Go语言——反射
反射是众多编程语言中的一个非常实用的功能,它是一种能够自描述、自控制的应用,Go语言也对反射提供了友好的支持。
传说之下的花儿
2023/04/16
1.6K0
Go语言——反射
上篇:Go的反射基础
TypeOf()方法获取到变量的类型后,再调用它的Kind()方法可以将返回的结果用来进行类型的判断
不背锅运维
2022/10/25
1880
上篇:Go的反射基础
Golang反射-上篇
反射是指在运行时动态的访问和修改任意类型对象的结构和成员,在go语言中提供reflect包提供反射的功能,每一个变量都有两个属性:类型Type和值Value
仙人技术
2021/11/12
8580
Golang反射-上篇
go语言反射
oValue := reflect.ValueOf(obj) field := oValue.Field(i) -> fieldValue :=value.Field(i).Interface{}(获取第i个属性的值的“正射”形式)
程序员小饭
2020/09/07
3880
Go通关16:运行时反射,深度解析!
对于反射,之前的文章已经有所介绍,传送门:《断言、反射的理解与使用!》,此处我们再深入讲解下反射。
微客鸟窝
2021/08/18
4230
golang中的反射
本文转载自https://github.com/KeKe-Li/For-learning-Go-Tutorial/edit/master/src/chapter07/01.0.md
ccf19881030
2020/12/16
1.2K0
Goalng下的反射模块reflect学习使用
注意:我们上面的示例是使用值类型进行进行反射构造的。如果是指针类型的话,我们需要使用reflect.Struct字段进行判断接口类型的Kind()方法
李海彬
2018/12/13
8430
GoLang反射
反射是 Go 语言比较重要的特性。虽然在大多数的应用和服务中并不常见,但是很多框架都依赖 Go 语言的反射机制实现简化代码的逻辑。因为 Go 语言的语法元素很少、设计简单,所以它没有特别强的表达能力,但是 Go 语言的 reflect 包能够弥补它在语法上的一些劣势。
大忽悠爱学习
2022/08/23
4860
GoLang反射
Go通关08:断言、反射的理解与使用!
您诸位好啊,我是无尘,学习Go语言肯定经常看到断言、反射这两个词,曾因为使用场景不太熟悉,让我很是费解,今天就好好唠唠!
微客鸟窝
2021/08/18
1.1K0
Go系列:通过反射来操作结构体
在日常开中,总是会有各种trick的需求,Go这种强类型语言按常规写法就不能完成一些需求,所以反射就是一般瑞士军刀,在某些场合可以用简单的方法功能。
用户9805946
2024/11/19
590
(四十五)golang--反射
反射注意事项和使用细节: (1)reflect.Vale.Kind,获取变量的类别,返回的是一个常量;
西西嘛呦
2020/08/26
3540
深入了解Golang中的反射机制
        反射是指在程序运行时动态地检查和修改对象的能力。在Go语言中,通过反射可以在运行时检查变量的类型、获取结构体字段和方法的信息,以及动态调用方法等操作。反射在一些需要处理未知类型或需要在运行时进行动态操作的场景中非常有用。
周小末天天开心
2023/10/16
3090
Golang的反射reflect深入理解和示例
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。这是元编程的一种形式。它同时也是造成混淆的重要来源。
Allen.Wu
2022/11/13
5690
go-反射
反射是指在程序运行期对程序本身进行访问和修改的能力。程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分。在运行程序时,程序无法获取自身的信息。
新人小试
2020/03/23
8400
Go:反射(Reflection)
在Go语言中,反射是一个强大且复杂的特性,它允许程序在运行时检查对象的类型和值,甚至修改对象。反射在处理未知类型的数据时特别有用,例如解析JSON或在编写通用函数时。本文将通过一个实例详细介绍Go的反射,帮助大家理解和运用反射。
运维开发王义杰
2024/03/07
1240
Go:反射(Reflection)
【初识Go】| Day11 反射机制
第一个参数funcPtr以接口的形式传入函数指针,函数参数args以可变参数的形式传入,bridge函数中可以用反射来动态执行funcPtr函数。
yussuy
2020/12/24
4690
【初识Go】| Day11 反射机制
Go基础之--反射
反射:可以在运行时动态获取变量的相关信息 反射需要导入reflect 反射中重要函数的演示 反射有几下几个重要的函数: reflect.TypeOf :获取变量的类型,返回reflect.Type类型 reflect.ValueOf:获取变量的值,返回reflect.Value类型 reflect.Value.Kind:获取变量的类别,返回一个常量 reflect.Value.Interface():转换成interface{}类型 通过一个小例子来理解: package main import (
coders
2018/03/30
5820
Go基础之--反射
深入理解 go 反射
反射是可以让我们在程序运行时(runtime)访问、检测和修改对象本身状态或行为的一种机制。
leobhao
2024/04/01
1300
深入理解 go 反射
相关推荐
Golang 反射
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验