源代碼:https://git.oschina.net/zhaord/redis_sentinel_demo.git
參考文獻:
《使用Docker Compose部署基于Sentinel的高可用Redis集群 》 作者:易立
《Docker — 從入門到實踐》
介紹
前段時間一直在學(xué)習(xí)redis,使用C#操作redis等知識,我們知道,redis 是一款優(yōu)秀的kev-value數(shù)據(jù)庫,可以用來搭建緩存服務(wù)器,
在學(xué)習(xí)的過程中,就想如何使用docker技術(shù)搭建redis集群,經(jīng)過三天兩夜的的學(xué)習(xí)和與易立的交流,今天終于測試通了docker下的redis集群。
前提條件:
安裝 docker for windows
閱讀并使用教程: 《使用Docker Compose部署基于Sentinel的高可用Redis集群 》
使用Docker Compose部署基于Sentinel的高可用Redis集群 遇到的問題
- 因為是在 windows下,而作者是在lunix環(huán)境下,所以 sentinel-entrypoint.sh 這個文件存在格式問題,需要轉(zhuǎn)換文件格式
方案: 在 dockerfile 中第12行以后添加如下代碼
RUN apt-get update && apt-get install -y dos2unix
RUN dos2unix /usr/local/bin/sentinel-entrypoint.sh && apt-get --purge remove -y dos2unix && rm -rf /var/lib/apt/lists/*
如果搭建成功,運行結(jié)果如下:

其中 ports 顯示的 是 0.0.0.0:6379是因為我映射了本地端口
修改cluster 實現(xiàn)端口映射到docker寄主
redis集群,在這個案例中,是一個master,兩個slave,三個sentinel,主要工作的是 master 和 slave, sentinel是redis官方推薦的分布式集群方案,用來監(jiān)測master 和slave,保證集群正常工作。
在 參考1 中,是通過 docker-compose scale slave=2 指令擴展 redis slave 容器的,而我們需要讓寄主可以訪問到容器的服務(wù),所以,需要將 redis-master 和 redis-slave 的端口映射到 寄主,于是,修改 docker-compose.yml,修改后的文件如下:
master:
image: redis:3
ports:
- "6379:6379"
slave:
image: redis:3
command: redis-server --slaveof redis-master 6379
ports:
- "6380:6379"
links:
- master:redis-master
slave_1:
image: redis:3
command: redis-server --slaveof redis-master 6379
ports:
- "6381:6379"
links:
- master:redis-master
sentinel:
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
links:
- master:redis-master
- slave
使用
master:
image: redis:3
ports:
- "6379:6379"
映射redis-master 服務(wù)的端口
使用
slave:
image: redis:3
command: redis-server --slaveof redis-master 6379
ports:
- "6380:6379"
links:
- master:redis-master
slave_1:
image: redis:3
command: redis-server --slaveof redis-master 6379
ports:
- "6381:6379"
links:
- master:redis-master
建立兩個 redis-slave ,端口分別映射為寄主的 6380和6381
使用
docker-compose scale sentinel=3
建立三個 sentinel 容器,修改之后,通過docker-compose ps查看容器執(zhí)行內(nèi)容

說明我們的集群已經(jīng)搭建成功
使用C# 代碼測試集群
使用的nuget包: StackExchange.Redis
首先是將 redis-master 和 redis-slaveof 的服務(wù)地址都放在一個數(shù)組里
// 設(shè)置 redis 集群服務(wù)器地址,目前不知道如何自動切換,所以只能給出所有可連接的地址
var ips = new[]
{
"localhost:6379",
"localhost:6380",
"localhost:6381"
};
然會建立redisclient
var connectionip = string.Join(",", ips);
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(connectionip);
在插入db值
IDatabase db = redis.GetDatabase();
// 設(shè)置 db 值
string value = "abcdefg";
db.StringSet("mykey", value);
string message = "Item value is: " + db.StringGet("mykey");
Console.WriteLine(message);
然會循環(huán)讀取 key 為 mykey的值
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
Thread.Sleep(500); // 等待500ms
// 每500 ms取一次
message = DateTime.Now.ToString("HH:mm:ss.fff") + " Item value is: " + db.StringGet("mykey");
Console.WriteLine(message);
if (watch.ElapsedMilliseconds > 60 * 1000)
{
// 運行 1min
break;
}
}
watch.Stop();
期望運行結(jié)果
在循環(huán)讀取的時候,如果stop redis-master ,即暫停主機,而程序依然可以正確讀取數(shù)據(jù),就表明集群成功,因為 master 已經(jīng)暫停了,但是還能正常使用 redis服務(wù)
首先確保 6個docker 容器正常運行

運行程序,得到結(jié)果如下

暫停 redis-master 并查看容器

通過查看容器我們看到 rediscluster_master_1 已經(jīng)是 exit 了,即不在運行狀態(tài)
此時我們看程序的運行結(jié)果

發(fā)現(xiàn)程序正常運行切讀取正確的數(shù)據(jù),表明我們的redis集群成功!
我們關(guān)閉程序,并恢復(fù) redis-master

發(fā)現(xiàn) redis-master 已經(jīng)正常工作,此時在打開程序,

程序正常運行。
通過以上案例,我們發(fā)現(xiàn),集群的好處就是不在單一依賴單個服務(wù),單一依賴服務(wù)的話如果這個服務(wù)發(fā)生了錯誤或者是關(guān)機等等其他情況,也會導(dǎo)致我們的程序不能正常運行,而集群的好處就是,當我的服務(wù) 下線的時候,有其他的服務(wù)來代替我這個服務(wù)運行,保證程序的運行良好
總結(jié)
通過學(xué)習(xí)docker 下redis集群,我掌握了docker的基礎(chǔ)和compose的用法,以及如何使用sentinel 建立redis集群(不使用docker也可以建立集群,只不過多學(xué)習(xí)了docker而已).
建立了 redis集群,那么redis緩存 高可用 分布式也就指日可待了!
QQ:1260825783 (文章中有任何疑惑或遇到問題請與我聯(lián)系)
轉(zhuǎn)載請注明出處