目录
背景
spark1.6.1 升级到 spark 2.1.0,codis版本是0.4.0
现象
代码没有改动,但是使用codis出现了问题,导致无法正常运行,错误如下
redis.clients.jedis.exceptions.JedisException: Proxy list empty
看源码
pools为空的情况下会抛出该异常,但是为什么会是空
一开始怀疑是①或者②这个地方出现了问题,但是去zk上看,没有问题。
修改log方式,出现以下异常
java.lang.NoSuchMethodError: redis.clients.jedis.JedisPool.<init>(Lorg/apache/commons/pool2/impl/GenericObjectPoolConfig;Ljava/lang/String;IIILjava/lang/String;ILjava/lang/String;ZLjavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/SSLParameters;Ljavax/net/ssl/HostnameVerifier;)V
第一印象是包冲突,但是mvn查了下,没有问题,怀疑spark运行的环境上的jar问题,迫切需要知道在executor在真正执行的时候,到底使用的是什么jar包中的JedisPool
定位方法
在代码中加入下面这行
System.err.println("DEBUG: Executor:" + classOf[redis.clients.jedis.JedisPool].getProtectionDomain.getCodeSource.getLocation.toString)
运行在yarn-client下方便观察输出,得到以下信息
DEBUG: Executor:file:/etc/azkaban/spark-2.1.0-bin-hadoop2.6/jars/logging-assembly-0.1.0-protobuf3.jar
到此终于知道问题出在了哪里
解决办法
很简单,通过maven的shade打包插件,做如下处理即可
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>redis.clients</pattern>
<shadedPattern>shaded.redis.clients</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>