準備工作
-
下載Windows版Redis
-
.msi可以直接安裝爲Windows Service (但設定調整比較麻煩,建議使用.zip )
-
.zip
-
建議不要放在OS 槽,會少掉許多權限設定問題
2.準備建立Master-Slave 與Sentinel(下列方式擇一即可)
- 採取實體隔離
- 將zip 解壓縮至資料夾後複製多份並標記用途(eg Redis-{Master|SlaveSentinel})後備用
- 僅建立不同用途之config
3.以下demo 將以建立不同config 方式進行
Master-Slave 設定
-
調整
redis.windows.conf
config設定- Master
- 保留預設值即可
-
Slave
- 如果採用config 隔離,請記得修改檔案(eg redis.windows6380.conf)
- 修改port (不可與master port 重複)
-
加入slave 設定
slaveof {masterip} {masterport>}
- Master
-
啓動Master & Slave (下列方式擇一即可)
如果路徑包含空白請記得使用跳脫字元\
搭配"
將路徑包起來,下面Sentinel有使用範例
設定master
sc.exe create "Redis6379" start = auto binPath= "c:\redis\redis-server.exe --service-run c:\redis\redis.windows-service.conf" DisplayName= "Redis6379"
設定slave
sc.exe create "Redis6380" start = auto binPath= "c:\redis\redis-server.exe --service-run c:\redis\redis.windows-service6380.conf" DisplayName= "Redis6380"
-
確認執行狀況
Sentinel config 設定
Winodws 7 使用Windows Redis 3.2.100 版本無法啓動sentinel,需使用3.0.504 版
- 新增sentinel.conf 檔案
-
逐一加入以下設定
-
指定port
port 26379
-
指定監視名爲
master
ip爲127.0.0.1
port爲6379
的redis master instance,最後數字代表幾個sentinel同意才進行切換sentinel monitor master 127.0.0.1 6379 1
-
指定
3000
毫秒沒有迴應就視名爲master
的instance失效sentinel down-after-milliseconds master 3000
-
指定
18000
毫秒未完成視爲failover失敗sentinel failover-timeout master 18000
-
指定同時只有
1
個salve可以從新master同步資料回去sentinel parallel-syncs master 1
- 數字愈小,failover 耗時就愈久(需等所有slave 都同步完)
- slave 同步資料可能會造成slave 無法迴應,所以也不建議設太大
-
指定連線密碼爲
password
(非必要)sentinel auth-pass password
-
-
最終設定範例
port 26379
sentinel monitor master 127 .0 .0 .1 6379 1
sentinel down-after-milliseconds master 3000
sentinel failover-timeout master 18000
sentinel parallel-syncs master 1
啓動Sentinel
-
指令
-
Windows Service
-
如果路徑包含空白請記得使用跳脫字元
\
搭配"
將路徑包起來
-
sc.exe create "RedisSentinel" start = auto binPath= "\"c:\Program Files\redis\redis-server.exe\" --service-run \"c:\Program Files\redis\sentinel.conf\" --sentinel" DisplayName= "RedisSentinel"
確認執行狀態
redis-cli -h 127 .0 .0 .1 -p 26379 info sentinel
模擬master 失效
-
手動shutdown master
-
確認sentinel 資訊
-
確認slave 資訊
模擬slave 接替成爲master 後,原master 回覆服務
-
手動shutdown master
-
確認sentinel 資訊
-
確認slave 資訊
-
回覆已shutdown 的master
-
再次啓動原master
-
新master (原slave) 同步資料至原master(新slave)
-
Sentinel偵測到
原 master
加入並將其指定爲slave -
原master(新slave) 的config 會被自動加上
slaveof {新 master} {新 masterport>}
-
使用指令確認一下
-
使用ServiceStack.Redis鏈接訪問代碼
public IRedisClient connectredis()
{
var sentinelHosts = new[] { "127.0.0.1:26379" };
var sentinel = new RedisSentinel(sentinelHosts, masterName: "master");
sentinel.SentinelWorkerConnectTimeoutMs = 500;
IRedisClientsManager redisManager = sentinel.Start();
return redisManager.GetClient();
}
[TestMethod]
public void RedisSetValue()
{
for (int i = 0; i < 100; i++)
{
IRedisClient redisClient = connectredis();
redisClient.Db = 0;
//redisClient.Remove(i.ToString());
redisClient.Set<string>(i.ToString(), i.ToString());
Thread.Sleep(3000);
System.Diagnostics.Debug.WriteLine(i.ToString());
}
}
因爲使用ServiceStack.redis結合密碼模式不知道如何配置,所以用了下面的案例?歡迎各位大神賜教!!
結合StackExchange.Redis使用密碼模式
在主從節點得配置文件中添加:
masterauth "foobared"
requirepass "foobared"
在哨兵的配置文件中添加
sentinel auth-pass master foobared
代碼案例:
[TestMethod]
public void RedisSetValue()
{
for (int i = 0; i < 100; i++)
{
ConfigurationOptions sentinelOptions = new ConfigurationOptions();
sentinelOptions.EndPoints.Add("127.0.0.1", 26379);
sentinelOptions.TieBreaker = "";
sentinelOptions.CommandMap = CommandMap.Sentinel;
sentinelOptions.AbortOnConnectFail = false;
sentinelOptions.AllowAdmin = true;
// Connect!
ConnectionMultiplexer sentinelConnection = ConnectionMultiplexer.Connect(sentinelOptions);
// Get a connection to the master
ConfigurationOptions redisServiceOptions = new ConfigurationOptions();
redisServiceOptions.ServiceName = "master"; //master名稱
redisServiceOptions.Password = "foobared"; //master訪問密碼
redisServiceOptions.AbortOnConnectFail = true;
redisServiceOptions.AllowAdmin = true;
ConnectionMultiplexer masterConnection = sentinelConnection.GetSentinelMasterConnection(redisServiceOptions);
var db = masterConnection.GetDatabase(2);
db.StringSet(i.ToString(), i.ToString(), TimeSpan.FromMinutes(10));
Debug.WriteLine(i.ToString());
}
}