Jedis包中有个很恶心的问题,那就是包里面有支持分片的ShardeJedis客户端类,也有支持哨兵的池类JedisSentinelPool,就是没有既支持分片又支持哨兵的池类,所以必须自己自定义一个ShardedJedisSentinelPool,定义这个类,在网上有个很受欢迎的版本,是继承了Pool<ShardeJedis>类后重写相关的池操作的方法,个人觉得这种方案太麻烦,而且据反馈也有很多考虑不全面的细节,造成bug。一开始我试图去继承JedisSentinelPool类并重写相关方法把分配功能加进去,发现很难搞。后来改变了思路,其实可以建立一个JedisSentinelPool数组,每个元素其实对应监视一个主备的redis服务节点,然后可以根据分片规则去确定从哪个JedisSentinelPool中获取jedis。这个方案比较简单实用,唯一难点就是要去实现跟ShardeJedis一样的一致性哈希分片规则。好在sharde.java中有相关源码,只要稍作修改即可。实现源码如下:
public class ShardedJedisSentinelPool {private Map<String,JedisSentinelPool> poolMap = new HashMap<String,JedisSentinelPool>();
private Hashing algo = Hashing.MURMUR_HASH;
private TreeMap<Long, JedisShardInfo> nodes;
public ShardedJedisSentinelPool(Set<HostAndPort> hostInfo, Set<String> sentinels){
List<JedisShardInfo> list = new ArrayList<JedisShardInfo>();