Docker Compose——搭建Redis集群
環境配置
Docker 18.x
Docker-Compose 3.7
Redis 6.2.5
主從(Master-Slave)模式
主從復制模式中包含一個主數據庫實例(master)與一個或多個從數據庫實例(slave),如下圖
客戶端可對主數據庫進行讀寫操作,對從數據庫進行讀操作,主數據庫寫入的數據會實時自動同步給從數據庫。
主從模式的具體工作機制
主從模式的特點
- 主服務器負責接收寫請求
- 從服務器負責接收讀請求
- 從服務器的數據由主服務器復制過去。主從服務器的數據是一致的
主從模式的優點
- 讀寫分離(主服務器負責寫,從服務器負責讀)
- 高可用(某一臺從服務器掛了,其他從服務器還能繼續接收請求,不影響服務)
- 處理更多的并發量(每臺從服務器都可以接收讀請求,讀QPS就上去了)
主從模式的缺點
- 不具備自動容錯與恢復功能,master或slave的宕機都可能導致客戶端請求失敗,需要等待機器重啟或手動切換客戶端IP才能恢復
- master宕機,如果宕機前數據沒有同步完,則切換IP后會存在數據不一致的問題
- 難以支持在線擴容,Redis的容量受限于單機配置
主從同步
主從架構的特點之一:主服務器和從服務器的數據是一致的。
主從同步的2種情況
完整的同步
從服務器向主服務器發送PSYNC命令
收到PSYNC命令的主服務器執行BGSAVE命令,在后臺生成一個RDB文件。并用一個緩沖區來記錄從現在開始執行的所有寫命令。
當主服務器的BGSAVE命令執行完后,將生成的RDB文件發送給從服務器,從服務器接收和載入RBD文件。將自己的數據庫狀態更新至與主服務器執行BGSAVE命令時的狀態。
主服務器將所有緩沖區的寫命令發送給從服務器,從服務器執行這些寫命令,達到數據最終一致性。
部分重同步
主從服務器的復制偏移量 主服務器每次傳播N個字節,就將自己的復制偏移量加上N
從服務器每次收到主服務器的N個字節,就將自己的復制偏移量加上N
通過對比主從復制的偏移量,就很容易知道主從服務器的數據是否處于一致性的狀態!
Docker-Compose
https://gitee.com/shentuzhigang/mini-project/tree/master/docker-compose/redis-master-slave
version: "3.7" services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83 networks:redis-cluster-net:external: truename: redis-cluster-net哨兵 Sentinel 模式
Redis 的 Sentinel 系統用于管理多個 Redis 服務器(instance), 該系統執行以下三個任務:
- 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
- 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
- 自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器。
Redis Sentinel 是一個分布式系統, 你可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來接收關于主服務器是否下線的信息, 并使用投票協議(agreement protocols)來決定是否執行自動故障遷移, 以及選擇哪個從服務器作為新的主服務器。
哨兵模式基于主從復制模式,只是引入了哨兵來監控與自動處理故障。如圖
Docker-Compose
哨兵容器應該等待redis容器先啟動,使用depends_on控制
version: "3.7" services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83redis-sentinel1:image: redis:latestcontainer_name: redis-sentinel1command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6373:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.84redis-sentinel2:image: redis:latestcontainer_name: redis-sentinel2command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6374:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.85redis-sentinel3:image: redis:latestcontainer_name: redis-sentinel3command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6375:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.86 networks:redis-cluster-net:external: truename: redis-cluster-netredis-sentinel.conf
sentinel monitor mymaster 192.168.88.81 6379 2設置哨兵監控的主服務器和odown數(sdown數累計達到odown即開啟故障轉移主從切換) sentinel monitor
mymaster 192.168.11.128 6379 2
x秒不回應即單sentinel判定為sdown sentinel down-after-milliseconds
單次故障轉移最長時間,超過則認定為故障轉移失敗 sentinel failover-timeout mymaster 10000
當發生failover主備切換時最多可以有多少個slave同時對新的master同步,數字越小favilover越快.通常設為1
sentinel parallel-syncs <master-name> <numslaves>
哨兵啟動后自動寫入的唯一id,每個sentinel不一樣,故不能用同一份配置文件 sentinel myid
Redis Cluster 集群模式
Redis 集群是一個可以在多個 Redis 節點之間進行數據共享的設施(installation)。
Redis 集群不支持那些需要同時處理多個鍵的 Redis 命令, 因為執行這些命令需要在多個 Redis 節點之間移動數據, 并且在高負載的情況下, 這些命令將降低 Redis 集群的性能, 并導致不可預測的行為。
Redis 集群通過分區(partition)來提供一定程度的可用性(availability): 即使集群中有一部分節點失效或者無法進行通訊, 集群也可以繼續處理命令請求。
Redis 集群提供了以下兩個好處:
- 將數據自動切分(split)到多個節點的能力。
- 當集群中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力。
Docker-Compose
version: "3.7" services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83redis4:image: redis:latestcontainer_name: redis4command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6373:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.84redis5:image: redis:latestcontainer_name: redis5command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6374:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.85redis6:image: redis:latestcontainer_name: redis6command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6375:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.86 networks:redis-cluster-net:external: truename: redis-cluster-net啟動后執行命令
docker exec -it redis1 \ redis-cli --cluster create \ 192.168.88.81:6379 \ 192.168.88.82:6379 \ 192.168.88.83:6379 \ 192.168.88.84:6379 \ 192.168.88.85:6379 \ 192.168.88.86:6379 \ --cluster-replicas 1Keepalived監控
通過 keepalived 的虛擬 IP,提供主從的統一訪問,在主出現問題時, 通過 keepalived 運行腳本將從提升為主,待主恢復后先同步后自動變為主,該方案的好處是主從切換后,應用程序不需要知道(因為訪問的虛擬 IP 不變),壞處是引入 keepalived 增加部署復雜性,在有些情況下會導致數據丟失。
Zookeeper監控
通過 zookeeper 來監控主從實例, 維護最新有效的 IP, 應用通過 zookeeper 取得 IP,對 Redis 進行訪問,該方案需要編寫大量的監控代碼
常見問題
- [ERR] Node 192.168.162.132:7001 is not configured as a cluster node.
- Docker can’t connect to redis from another service
- Could not connect to Redis at 127.0.0.1:6379: Connection refused with homebrew
- Node 172.168.63.202:7001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some
參考文章
- redis集群搭建(非常詳細,適合新手)
- Redis - Official Image | Docker Hub
- Docker下redis的主從、持久化配置
- docker-compose編排redis集群
- Sentinel — Redis 命令參考
- 六、Redis 主從復制 Replicaof、哨兵 Sentinel
- 一文掌握Redis主從復制、哨兵、Cluster三種集群模式
- redis replicaof命令的使用
- 2021-Java后端工程師面試指南-(Redis)
總結
以上是生活随笔為你收集整理的Docker Compose——搭建Redis集群的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客题霸 SQL5 查找所有员工的las
- 下一篇: Go——从文件路径解析解析GAVC坐标解