1. 程式人生 > >Redis Cluster集群搭建後,客戶端的連接研究(Spring/Jedis)(待實踐)

Redis Cluster集群搭建後,客戶端的連接研究(Spring/Jedis)(待實踐)

turn ron 記錄 redis div println 刪除 clu name

說明:無論是否已經搭建好集群,還是使用什麽樣的客戶端去連接,都是必須把全部IP列表集成進去,然後隨機往其中一個IP寫。

這樣做的好處:

1、隨機IP寫入之後,Redis Cluster代理層會自動根據分片寫入其中一臺,隨機IP只是減緩一個IP時的巨大流量問題。

2、對於寫死的IP問題,可以通過動態配置文件或者接口,觀察IP更新或者節點增加時,重新實例化,原有業務不影響,因為對象本身到GC時也代表當前業務已經完成。

下面是基於Spring和Jedis實現的集群,同時後端采用就是Redis Cluster原生集群。

當然,也可以自己手寫這些客戶端等。

原理還待研究,到底是不是只要寫上了這些IP,客戶端就全部保持著這些連接,然後有助於判斷哪個不可用。

還有一種想法是通過HAProxy來聚合出一個IP,然後將這些IP都添加進去,不過沒測試過這種方式對Redis Cluster模式會不會有影響。

我猜測客戶端需要全部IP都寫上,是由於其支持-MOVED 6918 127.0.0.1:7004這樣的命令,去取數據。應該是客戶端實現了這些協議。

而如果是基於Redis Cluster模式的,我猜測應該不能再前面使用HAProxy的代理去聚合IP。

關於這種模式的理解,參考:http://www.searu.org/30194.html,說到:當集群處於穩定狀態時,所有客戶端最終都會保存有一個哈希槽至節點的映射記錄,使得集群非常高效: 客戶端可以直接向正確的節點發送命令請求, 無須轉向、代理或者其他任何可能發生單點故障(single point failure)的實體(entiy)。

這種應該就是不用代理軟件去實現的原因。

下面是基於Spring+Jedis的配置:

在Spring配置文件中添加Jedis配置。(三主三從,9001-9003是主,9004-9006是從)

    <!-- 配置redis客戶端集群版 -->
    <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg>
            <set>
                <bean class="redis.clients.jedis.HostAndPort"
> <constructor-arg name="host" value="192.168.XX.XX"/> <constructor-arg name="port" value="9001"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="XXXXXXX"/> <constructor-arg name="port" value="9002"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="XXXXXXX"/> <constructor-arg name="port" value="9003"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="XXXXXXX"/> <constructor-arg name="port" value="9004"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="XXXXXXX"/> <constructor-arg name="port" value="9005"/> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg name="host" value="XXXXXXX"/> <constructor-arg name="port" value="9006"/> </bean> </set> </constructor-arg> </bean> <bean id="jedisClientCluster" class="com.dianshang.rest.component.impl.JedisClientCluster"/>

封裝Redis的一些常用操作(存儲String 類型,獲取String類型,設置過期時間,刪除hash數據等等)

/**  
 * redis操作工具類  
 * @author xiao  
 *  
 */  
public class JedisClientCluster implements JedisClient{  
      
    //註入jedisCluster  
    @Autowired  
    private JedisCluster jedisCluster;  
  
    /**  
     * 設置String數據類型  
     *   
     * @param key  
     * @param value  
     * @return  
     */  
    @Override  
    public String set(String key, String value) {  
        return jedisCluster.set(key, value);  
    }  
  
    /**  
     * 獲取String數據類型  
     *   
     * @param key  
     * @return  
     */  
    @Override  
    public String get(String key) {  
        return jedisCluster.get(key);  
    }  
      
    /**  
     * 設置hash數據類型  
     *   
     * @param key  
     * @param item  
     * @param value  
     * @return  
     */  
    @Override  
    public Long hset(String key, String item, String value) {  
        return jedisCluster.hset(key, item, value);  
    }  
      
    /**  
     * 獲取hash數據類型  
     *   
     * @param key  
     * @param item  
     * @return  
     */  
    @Override  
    public String hget(String key, String item) {  
        return jedisCluster.hget(key, item);  
    }  
      
    /**  
     * 刪除hash數據  
     * @param key  
     * @param item  
     * @return  
     */  
    @Override  
    public Long incr(String key) {  
        return jedisCluster.incr(key);  
    }  
      
    /**  
     * 加一操作  
     *   
     * @param key  
     * @return  
     */  
    @Override  
    public Long decr(String key) {  
        return jedisCluster.decr(key);  
    }  
      
    /**  
     * 減一操作  
     *   
     * @param key  
     * @return  
     */  
    @Override  
    public Long expire(String key, int second) {  
        return jedisCluster.expire(key, second);  
    }  
      
    /**  
     * 設置key的過期時間  
     *   
     * @param key  
     * @param second  
     * @return  
     */  
    @Override  
    public Long ttl(String key) {  
        return jedisCluster.ttl(key);  
    }  
      
    /**  
     * 判斷key是否過期  
     *   
     * @param key  
     * @return  
     */  
    @Override  
    public Long hdel(String key, String item) {  
         return jedisCluster.hdel(key, item);  
    }  
  
}  

測試:

@Test  
public void testJedisClientSpring() throws Exception {  
    //創建一個spring容器  
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-*.xml");  
    //從容器中獲得JedisClient對象  
    JedisClient jedisClient = applicationContext.getBean(JedisClient.class);  
    //jedisClient操作redis  
    jedisClient.set("cliet1", "1000");  
    String string = jedisClient.get("cliet1");  
    System.out.println(string);  
}  

參考:

http://blog.csdn.net/u010539352/article/details/51778242(以上內容部分轉自此篇文章)

http://blog.csdn.net/younger_z/article/details/51366791

http://m635674608.iteye.com/blog/2292236

https://www.2cto.com/kf/201609/551965.html

http://www.sojson.com/blog/203.html

Redis Cluster集群搭建後,客戶端的連接研究(Spring/Jedis)(待實踐)