使用Docker Compose部署基于Sentinel的高可用Redis集群
大家一定非常熟悉如何利用Docker啟動單個Redis容器用于開發環境,本文將介紹如何利用Docker Compose模板在本機和云端部署基于Sentinel的高可用Redis 3集群。
Redis集群可以在一組redis節點之間實現高可用性和sharding。今天我們重點圍繞master-slave的高可用模式來進行討論,在集群中會有1個master和多個slave節點。當master節點失效時,應選舉出一個slave節點作為新的master。然而Redis本身(包括它的很多客戶端)沒有實現自動故障發現并進行主備切換的能力,需要外部的監控方案來實現自動故障恢復。
Redis Sentinel是官方推薦的高可用性解決方案。它是Redis集群的監控管理工具,可以提供節點監控、通知、自動故障恢復和客戶端配置發現服務。
今天我們的部署模型是 Redis Sentinel 介紹的實例二,也是實戰中比較常見的一種部署模式:
本文所有示例代碼都可以從 https://github.com/AliyunContainerService/redis-cluster 獲得
本文采用的Redis鏡像全部基于Docker提供的Redis官方鏡像3.2.1
單機部署Redis集群
下面的測試需要本地環境已經安裝Docker Engine和Docker Compose,推薦使用Docker for Mac/Windows。想在云端部署的同學可以直接跳到下一節
下載代碼
git clone https://github.com/AliyunContainerService/redis-cluster cd redis-cluster目錄下面的docker-compose.yml模板定義Redis集群的服務組成
master:image: redis:3 slave:image: redis:3command: redis-server --slaveof redis-master 6379links:- master:redis-master sentinel:build: sentinelenvironment:- SENTINEL_DOWN_AFTER=5000- SENTINEL_FAILOVER=5000 links:- master:redis-master- slave在模板中定義了下面一系列服務
- master: Redis master
- slave: Redis slave
- sentinel: Redis Sentinel
其中sentinel服務的Docker鏡像是由 "./sentinel" 目錄中的Dockerfile構建完成,只是在官方Redis鏡像上添加了sentinel.conf配置文件,并以sentinel模式啟動容器。其配置文件如下,其中包含了sentinel對名為"mymaster"的集群的監控配置:
sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 5000細節請參見sentinel.conf配置自身。
注意:
- slave和sentinel容器初始化配置的Redis master節點主機名為"redis-master",這里我們利用了Docker容器連接的別名機制來連接master和sentinel/slave容器實例
- 由于我們會部署3個Sentinel,我們把sentinel的"quorum"設置為2,只有兩個sentinel同意故障切換,才會真正切換相應的redis master節點。
下面我們先構建 sentinel 服務所需 Docker image
docker-compose build一鍵部署并啟動Redis集群
docker-compose up -d這時我們可以檢查集群狀態,應該是包含3個容器,1個master, 1個slave,和1個sentinel
docker-compose ps顯示結果如下
Name Command State Ports -------------------------------------------------------------------------------------- rediscluster_master_1 docker-entrypoint.sh redis ... Up 6379/tcp rediscluster_sentinel_1 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp rediscluster_slave_1 docker-entrypoint.sh redis ... Up 6379/tcp我們可以伸縮sentinel的實例數量到3個
docker-compose scale sentinel=3伸縮slave的實例數量到2個,這樣我們就有3個redis實例了(包含一個master)
docker-compose scale slave=2檢查集群狀態,結果如下
docker-compose psName Command State Ports -------------------------------------------------------------------------------------- rediscluster_master_1 docker-entrypoint.sh redis ... Up 6379/tcp rediscluster_sentinel_1 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp rediscluster_sentinel_2 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp rediscluster_sentinel_3 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp rediscluster_slave_1 docker-entrypoint.sh redis ... Up 6379/tcp rediscluster_slave_2 docker-entrypoint.sh redis ... Up 6379/tcp我們可以利用下面的測試腳本來模擬master節點失效,并驗證Redis集群的自動主從切換。
./test.sh這個測試腳本實際上利用 docker pause 命令將 Redis master容器暫停,sentinel會發現這個故障并將master切換到其他一個備用的slave上面。
執行結果如下
Redis master: 172.17.0.2 Redis Slave: 172.17.0.3 ------------------------------------------------ Initial status of sentinel ------------------------------------------------ # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=172.17.0.2:6379,slaves=2,sentinels=3 Current master is 172.17.0.2 6379 ------------------------------------------------ Stop redis master rediscluster_master_1 Wait for 10 seconds Current infomation of sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3 Current master is 172.17.0.3 6379 ------------------------------------------------ Restart Redis master rediscluster_master_1 Current infomation of sentinel # Sentinel sentinel_masters:1 sentinel_tilt:0 sentinel_running_scripts:0 sentinel_scripts_queue_length:0 sentinel_simulate_failure_flags:0 master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3 Current master is 172.17.0.3 6379我們可以利用Docker Compose方便地在本地驗證Redis集群的部署和故障恢復,但是這還不是一個分布式的高可用部署。我們下面會利用阿里云容器服務來進行驗證
云端部署高可用Redis集群
阿里云容器服務 在兼容Docker Compose編排模板的基礎上,做了大量的擴展。能夠更好地幫助我們在Docker集群中部署分布式應用。
首先您需要創建一個包含至少三個節點的集群(否則您需要注釋掉相應的"affinity:service"部署約束)
然后我們利用下面的 docker compose模板部署高可用Redis集群
master:image: redis:3environment:- affinity:service!=slaverestart: always slave:image: redis:3command: redis-server --slaveof redis-master 6379environment:- affinity:service!=master- affinity:service!=slavelabels: aliyun.scale: "2"restart: alwayslinks:- master:redis-master sentinel:image: registry.aliyuncs.com/acs-sample/redis-sentinel:3environment:- affinity:service!=sentinellabels: aliyun.scale: "3"restart: alwayslinks:- master:redis-master- slave這里使用了預編譯的sentinel鏡像"registry.aliyuncs.com/acs-sample/redis-sentinel:3"
更重要是,引入了一些阿里云擴展使得對分布式應用更好地控制容器在宿主機節點的部署
- aliyun.scale 標簽:描述了服務的實例數量
- affinity:service 環境變量描述了服務的部署約束:比如對于Redis slave而言,我們不希望在一個宿主機節點上同時部署master和slave,或多個slave,我們可以方便用示例中的方法描述這些約束。
關于這些的詳盡解釋請參見幫助文檔
一鍵部署之后,我們就已經有一個真正高可用的Redis集群了
這樣任何一個宿主機節點失效,都不會導致Redis集群失敗
總結
文章介紹了如何在本地部署一個Redis集群,并利用Redis Sentinel實現自動化的主從切換。并在此基礎上利用阿里云容器服務擴展,一鍵部署一個真正的高可用分布式Redis集群。
對于Redis而言,阿里云提供了云數據庫 Redis 版,對于大部分對SLA有要求的客戶我們建議在生產環境使用Redis云服務。但是如果大家對版本、配置有特殊要求的時候,使用Docker部署Redis也是非常方便的。
出于性能考慮,在Docker容器中運行Redis不建議采用bridge網絡對外提供訪問,如需對外部VM或應用提供服務建議采用host網絡模式,并注意安全保護;如果只是對集群中容器提供redis訪問,則容器服務默認提供的跨宿主機容器網絡會提供優化而安全的網絡配置。同時建議在Docker容器設置中,給Redis容器配置合適的內存設置。
本文也給大家提供了一個示例,如何采用Docker的方式開發分布式應用并在云端部署生產級別環境。阿里云容器服務不但支持docker-compose模板提供的容器功能,使得本地開發的Docker鏡像和編排模板可以輕松上云;更提供了靈活的部署約束描述,使得對分布式應用的部署和控制變得非常方便。
想了解更多容器服務內容,請訪問 https://www.aliyun.com/product/containerservice
總結
以上是生活随笔為你收集整理的使用Docker Compose部署基于Sentinel的高可用Redis集群的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS下开启mysql远程连接,远
- 下一篇: 关于IB_DESIGNABLE / IB