之前有介紹過在 Winodws 上安裝 Redis,從 Redis 3.0 開始提供了 Cluster 的架構,我們可以把一群 Redis Instance 集合起來使用,而且 Client 端只要存取其中一台就可以獲得相同的數據,以下是 Redis Cluster 的設定步驟。
Redis Cluster 是怎樣的一個概念?
Redis 被設計了一個東西叫 hash slot,而 hash slot 的個數是固定的 - 16384 個,Cluster 在建立的時候就將 16384 個 hash slot 分配每一個 Node 之中。
舉例來說,假設我有 3 個 Nodes,分配後的情況大概就會像這樣:
- Node 1: 0 ~ 5500
- Node 2: 5501 ~ 11000
- Node 3: 11001 ~ 16384
之後 Redis 會自己決定哪些 Key 要放到哪個 hash slot。
安裝 Ruby
直接到 Ruby Installer 下載安裝,在安裝過程記得選取下面這 2 個選項。
安裝 Redis 函式庫
執行 gem install redis
下載安裝 redis 的 ruby 函式庫。
建立 Redis Node
Redis 要可以支持 Cluster 功能,需要改變一下設定。
主要的設定就是下面這些:
appendonly yes
# 因為我將設定都放在一起,所以 appendfilename 的命名我加上 port number 以示區別。
appendfilename "appendonly.6380.aof"
cluster-enabled yes
# 因為我將設定都放在一起,所以 cluster-config-file 的命名我加上 port number 以示區別。
cluster-config-file nodes.6380.conf
cluster-node-timeout 15000
cluster-slave-validity-factor 10
cluster-migration-barrier 1
cluster-require-full-coverage yes
我建立了 3 個 Redis Nodes,因為 Redis Cluster 至少要 3 個 Nodes,不然我們就會收到下面的提示訊息。
Redis 的 Node 也要各自都有自己的 conf 檔,檔名加上 port number 以示區別。
接著就執行指令將這 3 個 Redis Nodes 啟動。
redis-server --service-install redis.6380.conf --service-name redis6380
redis-server --service-start --service-name Redis6380
redis-server --service-install redis.6381.conf --service-name redis6381
redis-server --service-start --service-name Redis6381
redis-server --service-install redis.6382.conf --service-name redis6382
redis-server --service-start --service-name Redis6382
確定一下這 3 個 Nodes 真的有跑起來。
建立 Cluster
我們利用 Ruby 的 Script 來建立 Cluster,Ruby 的 Script 在這裡可以下載得到,執行下列指令。
redis-trib.rb create --replicas 0 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382
建立的過程中 Ruby 會要求更改 nodes.conf 檔案,就輸入 yes 就可以了。
當我們看到下面的訊息,就表示 Cluster 建立成功了。
開防火牆的 Port
預設要開啟的防火牆 Port 除了 Redis Nodes 用的 6380 ~ 6382 之外,還要另外開啟 16380 ~ 16382,因為 Redis 還需要另外一個用來做 Node 與 Node 之間溝通的 Port,這個 Port 預設就是把 Node 用的 Port Number 加上 10000。
使用 StackExchange.Redis 測試 Redis Cluster
指定從 port 6380 快取資料並指定過期時間
private void SetValue()
{
// 建立 Redis 連線,port 指定是 6380。
var redis = StackExchange.Redis.ConnectionMultiplexer.Connect("localhost:6380");
// 取得 Redis Database
var redisDatabase = redis.GetDatabase();
// 快取 Key 為 "hello",Value 為 "world" 的資料,而且 10 秒後過期。
redisDatabase.StringSet("hello", string.Format("world {0}", DateTime.Now.ToString("HH:mm:ss.fff")), TimeSpan.FromSeconds(10));
}
指定從 port 6381 取得快取資料
private void GetValue()
{
// 建立 Redis 連線,port 指定是 6381。
var redis = StackExchange.Redis.ConnectionMultiplexer.Connect("localhost:6381");
// 取得 Redis Database
var redisDatabase = redis.GetDatabase();
// 取得 Key 為 "hello" 的 Value。
var helloValue = redisDatabase.StringGet("hello");
}