1. 程式人生 > >5,redis叢集在專案當中的應用

5,redis叢集在專案當中的應用

前面我們從資料結構開始一路走來,已經比較全面的認識了redis。這篇文章開始分享redis在我們業務當中的使用。 開始分享之前我先提兩個我聽到的問題: 1、哨兵模式下,我們的業務端應該連線到哪個redis伺服器,既我們應該配置哪些資訊?

我先吧jedis提供的JedisSentinelPool資訊帖出來我們一起看一下原始碼就知道這個是怎麼回答了。如果你對過程不感興趣那麼你可以直接讀正經答案我會在那裡給出解答的 JedisSentinelPool的maven座標,請忽略版本(因為這不是重點) redis.clients jedis 2.9.0

對沒錯 它是包含在jedis裡的。 接下來構建JedisSentinelPool例項。(不管田七何首烏先new出來再說)(這個過程是我閱讀原始碼的過程) JedisSentinelPool jedisSentinelPool = new JedisSentinelPool();//當然這裡會報錯,我選擇忽略,因為肯定是有一些東西我還沒做。 摁住CTRL 滑鼠點選JedisSentinelPool,進入JedisSentinelPool.class這個檔案 這裡有多個重寫的構造方法,但是不要急,摁住CTRL 滑鼠點選構造方法裡的this在你跳轉到大概第85行之前你可以一直點。那麼在85行這裡提供了真正意義上的 JedisSentinelPool構造過程: HostAndPort master = initSentinels(sentinels, masterName); initPool(master); 跟蹤進initSentinels()這個方法我發現,這裡的邏輯是用masterName在sentinels裡找master的ip和port,一旦找到可用的master,就構建一個redis例項並返回。

正經答案: JedisSentinelPool的構造方法要求我們傳入兩個引數: 1、Set<String> sentinels 這個String是這樣的 ip:port,sentinels是多個哨兵所在主機的ip和哨兵執行port的集合 2、String masterName 這個masterName是這樣的:任何一臺redis例項的機器上(不管是master還是slave都可以) 輸入info replication 這個命令都會看到 類似mymaster這樣的字樣 這個mymaster就是masterName sentinel模式下是通過在客戶端配置sentinel叢集的資訊和主節點的資訊,來連線redis叢集的。

想看程式碼麼? import java.util.HashSet; import java.util.Set; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisSentinelPool; Set sentinels = new HashSet(); sentinels.add(“0.0.0.0:6379”); sentinels.add(“0.0.0.1:6379”); sentinels.add(“0.0.0.2:6379”); String masterName = “mymaster”; JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName,sentinels); Jedis jedis = jedisSentinelPool.getResource(); jedis.set(“zhugegangtie”,“balabala”); String value = jedis.get(“zhugegangtie”);

2、叢集模式下 ,為什麼會有MOVED的錯誤? 這個問題…先說MOVED是什麼意思吧; 舉個板栗吧(香甜軟糯的高山小板慄) 我有兩個redis例項A和C: 分別對應的slot值是 A:1~10000, C:10001~16383, 在A上呼叫set方法,存一條記錄:{“zhugegangtie”:balabala}, 經過CRC16演算法的處理"zhugegangtie",得到的slot值是10001。也就是說這條記錄應該存到B上。那麼會報這樣一個error: (error) MOVED 10001 0.0.0.0:6379 這裡10001 是"zhugegangtie"對應的slot值; 0.0.0.0:6379 這裡是C的ip和port。

明白了吧!當我們儲存的資料不應該在這個例項上時,才會報這樣一個錯誤,並提醒我們應該去哪裡存?

下面來分享我們可能會使用到的redis客戶端 jedis:內部維護了執行緒池。最普通的redis客戶端不多說了 ;叢集模式中使用JedisCluster。 也是包含在Jedis包中的。 JedisCluster儲存資料的大致過程是這樣的: 先把key通過CRC16進行處理獲得slot值,通過slot其對應節點的資訊,構建連線並存值。 程式碼分享出來: import java.util.HashSet; import java.util.Set; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; Set ipAndPort= new HashSet(); ipAndPort.add(new HostAndPort(“0.0.0.1”,6379)); ipAndPort.add(new HostAndPort(“0.0.0.2”,6379)); ipAndPort.add(new HostAndPort(“0.0.0.3”,6379)); JedisCluster jedisCluster = new JedisCluster(ipAndPort); String str=jedisCluster.set(“mic”,“testJedisCluster”); redisson:實現了分散式環境下、可拓展、java語言編寫的資料結構,他更像zookeeper裡的curator客戶端。 惹認識它之前我最喜歡的是jedis,現在我移情別戀了,redisson才是分散式環境下的王者。 它封裝了redis的基礎命令是得使用起來更加面向物件;同時他還實現了基於redis的一些常用功能,比如我最執念的分散式鎖以前我是手撕的一個用起來不是很順手,但是redisson幫我實現了這個功能;其他還有分散式佇列,原子遞增,全域性ID等等等等等 程式碼分享出來:

import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RList;
import org.redisson.api.RMap;
import org.redisson.api.RSet;
import org.redisson.api.RSortedSet;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

Config config = new Config();
config.useClusterServers().addNodeAddress(
 								  "redis://192.168.152.130:6379",
 								  "redis://192.168.152.129:6379",
 								   "redis://192.168.152.128:6379"
 							);
		RedissonClient redissonClient = Redisson.create(config);
		//操作String
		RBucket<Object> rBucket=redissonClient.getBucket("mic");
		//操作Set
		RSet<Object> rSet = redissonClient.getSet("testRSet");
		//操作有序集合SortedSet
		RSortedSet<Object> rSortedSet=redissonClient.getSortedSet("testSortedSet");
		//操作Map
		RMap <String,Object> map=redissonClient.getMap("xiaoxiaohou");
		//操作List
		RList<Object> rList=redissonClient.getList("testList");
		rBucket.set("testRedisson");
		map.put("test", "testRMap");
		rSortedSet.add("sortedSet");
	}

lettuce:基於netty實現,執行緒安全的redis客戶端(這個我沒仔細研究,因為我從jedis移情到redisson以後就變得忠貞起來了)