最近要把项目从HDP2.4.0 升级到HDP3.0.1 其中各种坑,这里记录一下.

先列一下主要用到的技术与版本

老环境 HDP-2.4.0

HADOOP 2.7.1.2.4

HBase 1.1.2.2.4

Storm 0.10.0.2.4

ZooKeeper 3.4.6.2.4

Kafka 0.9.0.2.4

新环境 HDP-3.0.1

HADOOP 3.1.1

HBase 2.0.0

Storm 1.2.1

ZooKeeper 3.4.6

Kafka 1.1.1

第一类坑:HDP-3.0.1,这几个版本在Maven里的依赖本身就不一样。

比如:kafka1.1.1,我使用的Maven依赖如下,它实际上依赖的是zookeeper3.4.10,而HDP自己集成的3.4.6超前了4个版。

好在这只是个小坑,是小版本超前4个版,并不会对我的程序造成什么影响。

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka_2.11</artifactId>
    <version>1.1.1</version>
</dependency>

第二类坑:jar包之间的依赖主要是Storm相关的依赖冲突

用过Storm的同事使用的Storm提供的相关依赖。storm-hbase,storm-kafka

由于环境原因我需要使用Storm1.2.1与HBase2.0集成,引入maven依赖如下,

一个一个说:storm-core不用说了,scope都懂,在storm集群里跑肯定不需要打storm的依赖了,

storm-hbase,这个就比较坑了,它依赖的是Hbase1.1.0,而我要使用的是2.0.0差了一个大版本,这是非常致命的,而且storm-hbase的maven仓库里最新只支持到Hbase1.1.1。Hbase2.0的相关jar包还没出来,因为里边封装了API,那么我只想到2~3种办法解决

1.storm-hbase,去掉hbase-client的相关依赖,之后引入Hbase-client2.0的包,这里maven就不写了。但是这个办法行不通,至少我没试验通过,因为转成Hbase-client2.0之后,storm-hbase的函数里会报一个函数不存在异常,NoSuchMethod,说明storm-hbase的函数里用到了Hbase的老函数,想解决这个问题,我是不会重写storm-hbase源码,或者集成出问题那个类进行覆盖的。

一是没能力怕驾驭不了,二是没时间毕竟项目时间紧,就给一周时间,前后台6个工程,全部要升级调试完成。

2.不使用storm-hbase的类库,二是在storm类里使用原始的hbase-clientAPI进行数据存取。其实最一开始,项目启动的时候,我就是准备使用Hbase原生API的,但是项目不是我做,做那个的同事说了一句:使用storm,那么使用storm-hbase肯定比你自己用hbase原生API要好,当时我竟无言以对,TMD,现在终于知道怎么怼他了(注意上边的红字),storm-hbase,是storm-hbase提供的,那么当Hbase升级了,storm-hbase可能压根还没有对应新版本Hbase的依赖,这个时候你想要升级,就没办法了,说这些都是吐槽,最后还得我给他擦屁股,哎~ ╮(╯▽╰)╭。这个办法我也没采用,因为需要重写Hbase存储那块,这又涉及到了一个知识点需要记录一下,本来Hbase存储,很明显是可以封装的,Hbase的put函数本身就是key-value形式的,而我们Storm里的数据就是个Map,只要设计一个(表名,数据)的函数,很容易就可以封装出来,但是storm-hbase里必须一张表写一个类,继承的HbaseBolt,我当时问过那个同事能不能整合一下用一个Bolt,他说不能(所以如果采用第二种方式,我需要把每个表的Bolt改一遍,同样没时间。)

3.这个办法是我目前采用的,虽然HBASE集群是使用的2.0.0,但是我依然使用Hbase1.1.0的client,希望可以兼容,事实证明是可以兼容的,还好Hbase兼容性好。但是具体还要测试才知道。

		<dependency>
			<groupId>org.apache.storm</groupId>
			<artifactId>storm-core</artifactId>
			<version>1.2.1</version>
			<scope>provided</scope>
		</dependency>
                
		<dependency>
			<groupId>org.apache.storm</groupId>
			<artifactId>storm-hbase</artifactId>
			<version>1.2.1</version>
			<exclusions>
				<exclusion>
					<groupId>jdk.tools</groupId>
					<artifactId>jdk.tools</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

                <dependency>
			<groupId>org.apache.storm</groupId>
			<artifactId>storm-kafka</artifactId>
			<version>1.2.1</version>
			<!--  -->
			<exclusions>
				<exclusion>
					<groupId>org.apache.kafka</groupId>
					<artifactId>kafka-clients</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

第三类坑:代码的坑,因为版本升级了API肯定有变化,及时工程不报错,发布之后也可能存在各种jar包冲突,导致运行时异常。这里记录几个我印象深刻的修改点。

 

HDP3.1里kafka的版本是2.0.0,但是我的代码使用的是storm-kafka,版本2.1我如果不用这个包,需要自己重新写一个spout,可能还会出现性能问题,断线重连,游标同步等问题都需要考虑,没那个时间,但是如果我排除storm-kafka依赖的客户端,然后引入kafka2.0的client,那么storm-kafka会报错,原始是源码中的KafkaConfig里使用了kafka.api.OffsetRequest.DefaultClientId()这个函数在kafka2.0的客户端里已经被移除了,所以如果要使用storm-kafka的话,我必须要降低我的kafka-client版本,这里我使用的是1.1.1版本,这个版本里这个类是@deprecated的,还能用。

另外一个坑是2.0里消费之后storm-kafka没办法创建一个/offsetZkRoot/offsetZkId的目录,正常这个目录是用来storm存储kafka相关信息的,使用2.4的时候可以自动创建,升级之后不能自动创建,没研究出来为什么,我的解决方式是使用zookeeper命令在zookeeper里手动创建了这个目录,之后程序就不会报找不到这个目录的错误了。这里要注意的一点是这个目录刚创建完如果先启动strom会提示一个key.serializer没有默认值的错误。后来我先启动的生产者,让topic里有数据之后再启动storm就不报这个错了.

 

 

 

 

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐