jedis针对三种redis工作模式、哨兵模式的源码阅读分析

只要是非单机模式,一定要配置JedisPoolConfig,无论何种集群,最终都是要通过它的源码中是这样写的

  1. import org.apache.commons.pool2.impl.GenericObjectPoolConfig;  
  2.   
  3. public class JedisPoolConfig extends GenericObjectPoolConfig {  
  4.   public JedisPoolConfig() {  
  5.     // defaults to make your life with connection pool easier :)  
  6.     setTestWhileIdle(true);  
  7.     setMinEvictableIdleTimeMillis(60000);  
  8.     setTimeBetweenEvictionRunsMillis(30000);  
  9.     setNumTestsPerEvictionRun(-1);  
  10.   }  
  11. }  

在spring配置中,如果想要更改其参数值,直接覆写该值即可。在Spring中这个基本连接池一般这样配置

  1. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
  2.     <property name="maxTotal" value="200" />  
  3.     <property name="maxIdle" value="30" />  
  4.     <property name="maxWaitMillis" value="30000" />  
  5.     <property name="testOnBorrow" value="false" /><!-- 向调用者输出“链接”资源时,是否检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取。设为true,一个挂都不能用 -->  
  6.     <property name="testOnReturn" value="true" /><!-- 向连接池“归还”链接时,是否检测“链接”对象的有效性。 -->  
  7. </bean>  



 

这里说的三种工作模式是指:

    1、单机模式   

  1. Jedis jedis=new Jedis("192.168.0.100", 6379);  

这种是最纯粹的单机模式,一般都采用连接池+连接工厂(JedisConnectionFactory)的模式进行开发

  1. public class JedisConnectionFactory implements InitializingBean, DisposableBean, RedisConnectionFactory {  
  2.   
  3.     private final static Log log = LogFactory.getLog(JedisConnectionFactory.class);  
  4.     private static final ExceptionTranslationStrategy EXCEPTION_TRANSLATION = new PassThroughExceptionTranslationStrategy(  
  5.             JedisConverters.exceptionConverter());  
  6.   
  7.     private static final Method SET_TIMEOUT_METHOD;  
  8.     private static final Method GET_TIMEOUT_METHOD;  
  9.   
  10.     private JedisShardInfo shardInfo;  
  11.     private String hostName = "localhost";  
  12.     private int port = Protocol.DEFAULT_PORT;  
  13.     private int timeout = Protocol.DEFAULT_TIMEOUT;  
  14.     private String password;  
  15.     private boolean usePool = true;  
  16.     private Pool<Jedis> pool;  
  17.     private JedisPoolConfig poolConfig = new JedisPoolConfig();  
  18.     private int dbIndex = 0;  
  19.     private boolean convertPipelineAndTxResults = true;  
  20.     private RedisSentinelConfiguration sentinelConfig;  


由源码中分析可以得到,默认的主机名是localhst这个显然不行,肯定要覆盖重新主机为真是的IP地址,然后加上连接池信息,通过注入方式即可实现。
    2、分片模式

通过分片池ShardedJedisPool 实现

通过阅读源码,我们可以看到它的其中一个构造函数为(CTRL+SHIFT_T直接源码中查找)

  1. public class ShardedJedisPool extends Pool<ShardedJedis> {  
  2.   public ShardedJedisPool(final GenericObjectPoolConfig poolConfig, List<JedisShardInfo> shards) {  
  3.     this(poolConfig, shards, Hashing.MURMUR_HASH);  
  4.   }  

根据这个构造函数,我们可以在spring实现它

  1.       <!-- redis sharding -->  
  2. lt;bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool">  
  3. <constructor-arg index="0" ref="jedisPoolConfig" />  
  4. <constructor-arg index="1">  
  5.     <list>  
  6.         <bean name="redis1" class="com.my.cache.MyJedisShardInfo">  
  7.             <constructor-arg index="0" value="${redis.slaver1.host}" />  
  8.             <constructor-arg index="1" value="${redis.client.connectionTimeout}" />  
  9.             <constructor-arg index="2" value="${redis.client.soTimeout}" />  
  10.         </bean>  
  11.         <bean name="redis2" class="com.my.cache.MyJedisShardInfo">  
  12.             <constructor-arg index="0" value="${redis.slaver2.host}" />  
  13.             <constructor-arg index="1" value="${redis.client.connectionTimeout}" />  
  14.                                       <constructor-arg index="2" value="${redis.client.soTimeout}" />  
  15.         </bean>  
  16.     </list>  
  17. </constructor-arg>  
  18. lt;/bean>  


    3、集群模式(since 3.0)

通过JedisCluster实现,源码构造函数如下所示,一般集群环境中,我们要加上基本连接池,所以选择第一个构造函数。

  1. public class JedisCluster implements JedisCommands, BasicCommands, Closeable {  
  2.   public static final short HASHSLOTS = 16384;  
  3.   private static final int DEFAULT_TIMEOUT = 2000;  
  4.   private static final int DEFAULT_MAX_REDIRECTIONS = 5;  
  5.   
  6.   public static enum Reset {  
  7.     SOFT, HARD  
  8.   }  
  9.   
  10.   private int maxRedirections;  
  11.   
  12.   private JedisClusterConnectionHandler connectionHandler;  
  13.   
  14.   public JedisCluster(Set<HostAndPort> nodes, final GenericObjectPoolConfig poolConfig) {  
  15.     this(nodes, DEFAULT_TIMEOUT, DEFAULT_MAX_REDIRECTIONS, poolConfig);  
  16.   }  
  17.   
  18.   public JedisCluster(Set<HostAndPort> nodes) {  
  19.     this(nodes, DEFAULT_TIMEOUT);  
  20.   }  
  21.   
  22.    


哨兵模式是通过JedisSentinelPool 实现的,源代码如下

  1. public class JedisSentinelPool extends Pool<Jedis> {  
  2.   
  3.   protected GenericObjectPoolConfig poolConfig;  
  4.   
  5.   protected int timeout = Protocol.DEFAULT_TIMEOUT;  
  6.   
  7.   protected String password;  
  8.   
  9.   protected int database = Protocol.DEFAULT_DATABASE;  
  10.   
  11.   protected Set<MasterListener> masterListeners = new HashSet<MasterListener>();  
  12.   
  13.   protected Logger log = Logger.getLogger(getClass().getName());  
  14.   
  15.   private volatile JedisFactory factory;  
  16.   private volatile HostAndPort currentHostMaster;  
  17.   
  18.   public JedisSentinelPool(String masterName, Set<String> sentinels,  
  19.       final GenericObjectPoolConfig poolConfig) {  
  20.     this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null,  
  21.         Protocol.DEFAULT_DATABASE);  
  22.   }  

这样在spring就可以这样写,第一个构造函数的参数为master服务器,这个由于在源码中没有单独写出来,所以我们只能用构造器方式去射入值。

  1. <bean id="jedisPool" class="redis.clients.jedis.JedisSentinelPool">  
  2.     <constructor-arg index="0" value="mymaster" />  
  3.     <constructor-arg index="1">  
  4.         <set>  
  5.             <value>127.0.0.1:26379</value>  
  6.             <value>127.0.0.1:36379</value><!--配置了两个哨兵 -->  
  7.         </set>  
  8.     </constructor-arg>  
  9.     <constructor-arg index="2" ref="jedisPoolConfig" />  
  10. </bean>  


通过配置后,在程序中就可以直接引用:

  1. @Resource  
  2. private JedisSentinelPool jedisSentinelPool;  
  3.             
  4. 然后通过jedis=jedisSentinelPool.getResource();就可以获取当前的jedis了 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值