HBase表数据倾斜治理_HBase依赖jar包源码修改与替换

HBase表数据倾斜治理_HBase依赖jar包源码修改与替换

1.HBase开源代码修改

得益于HBase数据库代码是java开发的,且在github上开源了,网址是https://github.com/apache/hbase。

现在由于HBase团队服务更新换代中,导致他们服务器集群上的压缩队列格式与我们集群上的压缩队列格式不同,使得我是用开源jar包读取hbase快照时发生压缩格式错误的问题。hbase快照是使用ZSTD格式压缩的,我读取解压时取到的却是BZip2解压算法。

那么我现在就直接在下载的源码基础上对hbase-common包中的org.apache.hadoop.hbase.io.compress进行一下兼容修改,并打一个过渡版本的jar包。

修改前源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
BZIP2("bzip2") {
// Use base type to avoid compile-time dependencies.
private volatile transient CompressionCodec bzipCodec;
private final transient Object lock = new Object();

@Override
CompressionCodec getCodec(Configuration conf) {
if (bzipCodec == null) {
synchronized (lock) {
if (bzipCodec == null) {
bzipCodec = buildCodec(conf);
}
}
}
return bzipCodec;
}

private CompressionCodec buildCodec(Configuration conf) {
try {
Class<?> externalCodec =
getClassLoaderForCodec().loadClass("org.apache.hadoop.io.compress.BZip2Codec");
return (CompressionCodec) ReflectionUtils.newInstance(externalCodec, conf);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
},
ZSTD("zstd") {
// Use base type to avoid compile-time dependencies.
private volatile transient CompressionCodec zStandardCodec;
private final transient Object lock = new Object();

@Override
CompressionCodec getCodec(Configuration conf) {
if (zStandardCodec == null) {
synchronized (lock) {
if (zStandardCodec == null) {
zStandardCodec = buildCodec(conf);
}
}
}
return zStandardCodec;
}

private CompressionCodec buildCodec(Configuration conf) {
try {
Class<?> externalCodec =
getClassLoaderForCodec().loadClass("org.apache.hadoop.io.compress.ZStandardCodec");
return (CompressionCodec) ReflectionUtils.newInstance(externalCodec, conf);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
};

修改后源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
BZIP2("bzip2") {
// Use base type to avoid compile-time dependencies.
private volatile transient CompressionCodec bzipCodec;
private final transient Object lock = new Object();

@Override
CompressionCodec getCodec(Configuration conf) {
if (bzipCodec == null) {
synchronized (lock) {
if (bzipCodec == null) {
bzipCodec = buildCodec(conf);
}
}
}
return bzipCodec;
}

private CompressionCodec buildCodec(Configuration conf) {
try {

//在此处修改一下,使BZIP2类返回ZSTD解压缩算法
Class<?> externalCodec =
getClassLoaderForCodec().loadClass("org.apache.hadoop.io.compress.ZStandardCodec");
return (CompressionCodec) ReflectionUtils.newInstance(externalCodec, conf);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
},
ZSTD("zstd") {
// Use base type to avoid compile-time dependencies.
private volatile transient CompressionCodec zStandardCodec;
private final transient Object lock = new Object();

@Override
CompressionCodec getCodec(Configuration conf) {
if (zStandardCodec == null) {
synchronized (lock) {
if (zStandardCodec == null) {
zStandardCodec = buildCodec(conf);
}
}
}
return zStandardCodec;
}

private CompressionCodec buildCodec(Configuration conf) {
try {
Class<?> externalCodec =
getClassLoaderForCodec().loadClass("org.apache.hadoop.io.compress.ZStandardCodec");
return (CompressionCodec) ReflectionUtils.newInstance(externalCodec, conf);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
};

然后在maven选项中点击package打包,为了避免与真正的远程仓库中的jar冲突,直接将该jar包改名为一个特殊版本号:hbase-common-1.6.100.jar。

2.将本地jar包上传到本地仓库

安装好jdk和maven之后,使用maven install命令将该文件安装到maven本地仓库,命令模版如下:

1
mvn install:install-file -Dfile=<jar包的路径> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

实际执行命令:

1
mvn install:install-file -Dfile=/Users/jiazhengyang3/JIA/项目文件/2022.04.28_HBase数据倾斜优化/单region多map读取/hbase-common-1.6.100.jar -DgroupId=org.apache.hbase -DartifactId=hbase-common -Dversion=1.6.200 -Dpackaging=jar

看到如下信息即表示安装成功:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.3.1:install-file (default-cli) @ standalone-pom ---
[INFO] Installing /Users/jiazhengyang3/JIA/项目文件/2022.04.28_HBase数据倾斜优化/单region多map读取/hbase-common-1.6.100.jar to /Users/jiazhengyang3/MavenRepository/repository/org/apache/hbase/hbase-common/1.6.100/hbase-common-1.6.100.jar
[INFO] Installing /var/folders/9d/7ym_q_q91rx5x6y48xytv4sc0000gp/T/mvninstall8054187811382952997.pom to /Users/jiazhengyang3/MavenRepository/repository/org/apache/hbase/hbase-common/1.6.100/hbase-common-1.6.100.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.969s
[INFO] Finished at: Sun Aug 07 21:50:52 CST 2022
[INFO] Final Memory: 7M/309M
[INFO] ------------------------------------------------------------------------

3.在项目中引入该依赖

1
2
3
4
5
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
<version>1.6.100</version>
</dependency>

发现引入成功,点击查看源码可以看到是我们修改后的源码。

使用这种方式修改jar包源码最大的优点就是:我们修改打包安装到本地仓库中的jar可以正常引用其他依赖jar包。

如果我们要修改源码的jar包本身就没有依赖其他jar包,只是类似于一个单独的工具包,那么我们可以直接采用添加本地lib依赖的方式来依赖使用。

但是如果这个修改jar包本身还通过maven依赖了其他jar包,那么添加本地lib依赖的方式并不能使该修改jar包与maven仓库中的jar包建立起联系,虽然我们在idea编译器中不会报错,但是整个项目打包执行时,这个修改jar包中的类就会报ClassNotFound异常。

所以只能通过上述maven install命令将修改jar包安装到maven本地仓库,这样才能使修改jar包正常引用到它所依赖的其他maven仓库jar包。