项目简介
使用SparkStreaming2.1.0+Kafka0.8.2.1+SparkSQL2.1.0+Hive1.2.0实时消费数据,处理完之后写入hive分区表。
问题1.语言问题
描述:
在spark官网介绍上,SparkStreaming支持三种语言编写,scala,java,python,
SparkSql支持四种语言(scala,java,python,R)。
我本人比较偏好使用scala编写,但是有一位同事只会使用java,由于项目是分工协做完成的,所以决定是使用java进行开发,这个就遇到很多问题了,比如:1.javaAPI使用起来相对scala负责,如果没有经验的话,需要先熟悉API的使用规则;
2.混合使用javaapi和scala进行编程的时候,需要注意,经常回跳出来序列化的异常;
解决:
1.先熟悉一些javaAPI的调用,比如map,flapmap,filter,join等;
2.不建议混合编程,要么纯java,要么纯scala,因为两者之间调用对象的时候,经常出现序列化问题;
问题2.kafka版本问题
目前kafka和spark结合使用也是很多公司采取的流式数据处理方案,spark官网上给出了版本选择要求:sparkstreaming+kafka版本选择,必须要说明的是,版本的差异很大,0.8.2.1和0.10.0使用起来也不一样,给个样例看下:sparkstreaming+kafka新旧版本api使用java方式
我们选择的是kafka0.8.2.1,综合使用下来,个人不推荐使用老版的,因为需要自己手动维护offset;
同时,线上环境的spark版本比较新的话(spark2.3.0以上),最好结合kafka0.10.0使用,方便许多;
问题3.jar冲突
这个问题恶心了我一整天,具体异常是:
KafKa java.lang.NoSuchMethodError: net.jpountz.util.Utils.checkRange([BII)V
原因分析:spark streaming 1.6.3中引用了lz4-1.2.0.jar的包,但是程序跑起来的时候,使用了1.3版的lz4,1.3版的Utils类没有checkRange方法了,所以报NoSuchMethodError;
在kafka-clients-0.8.2.1中有两个类KafkaLZ4BlockInputStream和KafkaLZ4BlockOutputStream:
在KafkaLZ4BlockInputStream中有一个read方法:
在KafkaLZ4BlockOutputStream中有一个write方法:
解决方案:
1.建一个项目,找到kafka0.8.2.1-source源码,解压之后将整个jar源码放到idea中(注意:不是只编译这两个java文件),project structure->Libraries->添加以下jar(没有这两个jar包,编译源码的时候会报少类异常)
lz4-1.3.0.jar
slf4j-api-1.7.9.jar
2.将上边标红的两处代码改为:
net.jpountz.util.SafeUtils.checkRange(b, off, len);
- 编译,将编译的.class文件替换掉对应的jar包中的文件
用idea编译工具进行编译,需先配置好IDEA的环境;
具体步骤:
然后就是Build->Build Artifact->Build,完成后去项目目录下out拿到.class文件,替换maven下载的kafka-clients-0.8.2.1.jar包中相应的类即可;
这样spark streaming就能正常消费kafka中的数据了。