基於目前爛大街微服務的情況下,Redis在企業中使用非常頻繁,比如:緩存服務、分佈式鎖、分佈式原子計數鎖、隊列等等。本文主要講解redis-cluster集羣搭建,規劃模擬6個節點,三主三從。
系統 | CentOS 7 |
CPU | 2核 |
內存 | 4G |
硬盤 | 50G |
Docker | 19.03.5(安裝) |
Docker-compose | 1.16.1(與docker版本映射表格)(安裝) |
Redis | 5.0 |
節點規劃
容器名 | IP | 端口映射 | 運行模式 |
redis-master1 | 172.50.0.2 | 6391 -> 6391 | Master |
redis-master2 | 172.50.0.3 | 6392 -> 6392 | Master |
redis-master3 | 172.50.0.4 | 6393 -> 6393 | Master |
redis-slave1 | 172.50.0.5 | 6394 -> 6394 | Slave |
redis-slave2 | 172.50.0.6 | 6395 -> 6395 | Slave |
redis-slave3 | 172.50.0.7 | 6396 -> 6396 | Slave |
準備 redis.conf
創建數據存放目錄
# 注意:以下命令均在/mnt/redis/目錄下執行
mkdir /mnt/redis
cd /redis
# data 數據目錄,config 配置文件目錄
mkdir -p {redis-master1/data,redis-master2/data,redis-master3/data,redis-slave1/data,redis-slave2/data,redis-slave3/data,redis-master1/config,redis-master2/config,redis-master3/config,redis-slave1/config,redis-slave2/config,redis-slave3/config}
獲取5.0版本redis.conf文件(堅~單擊跳轉),對redis.conf內如下配置內容進行修改:
# 修改 可以接受連接的網卡地址,0.0.0.0 接受所有
bind 0.0.0.0
# 端口
port 6391
# 節點超時時間,毫秒
cluster-node-timeout 15000
# 集羣內部配置文件
cluster-config-file "nodes-6379.conf"
## 設置密碼
###1、如果對集羣設置密碼,那麼requirepass和masterauth都需要設置,否則發生主從切換時,就會遇到授權問題,可以模擬並觀察日誌
###2、各個節點的密碼都必須一致,否則Redirected就會失敗
###3、設置密碼後,操作redis-cli需(redis-cli -c -p 端口)通過auth password進行密碼驗證
### -c 集羣方式登陸客戶端程序
masterauth 123456
requirepass 123456
將redis.conf複製6份到對應的config文件夾下:
echo redis-master1 redis-master2 redis-master3 redis-slave1 redis-slave2 redis-slave3 | xargs -n 1 cp -v redis.sh
- -n 1 - 告訴 xargs 命令每個命令行最多使用一個參數,併發送到 cp 命令中。
- cp – 用於複製文件。
- -v – 啓用詳細模式來顯示更多複製細節。
修改redis.conf端口號以及文件名
# 批量修改端口
sed -i 's/port 6391/port 6392/' redis-master2/redis.conf && \
sed -i 's/port 6391/port 6393/' redis-master3/redis.conf && \
sed -i 's/port 6391/port 6394/' redis-slave1/redis.conf && \
sed -i 's/port 6391/port 6395/' redis-slave2/redis.conf && \
sed -i 's/port 6391/port 6396/' redis-slave3/redis.conf
# 批量修改文件名
mv redis-master1/redis.conf redis-master1/nodes-3691.conf && \
mv redis-master2/redis.conf redis-master2/nodes-3692.conf && \
mv redis-master3/redis.conf redis-master3/nodes-3693.conf && \
mv redis-slave1/redis.conf redis-slave1/nodes-3694.conf && \
mv redis-slave2/redis.conf redis-slave2/nodes-3695.conf && \
mv redis-slave3/redis.conf redis-slave3/nodes-3696.conf
編寫啓動文件
vim redis.sh
# 內容:
redis-server /config/nodes-${PORT}.conf
編寫 redis-docker-compose.yml
version: "3.3"
services:
redis-master1:
image: redis:5.0 # 基礎鏡像
container_name: redis-master1 # 容器服務名
working_dir: /config # 工作目錄
environment: # 環境變量
- PORT=6391 # 跟 config/nodes-6391.conf 裏的配置一樣的端口
ports: # 映射端口,對外提供服務
- "6391:6391" # redis 的服務端口
- "16391:16391" # redis 集羣監控端口
stdin_open: true # 標準輸入打開
# docker 網絡設置
networks:
redis-cluster:
ipv4_address: 172.50.0.2
tty: true
privileged: true # 擁有容器內命令執行的權限
# 映射數據卷,配置目錄
volumes: [
"/mnt/redis/redis-master1/data:/data",
"/mnt/redis/redis-master1/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime" # 時間同步
]
entrypoint: # 設置服務默認的啓動程序
- /bin/bash
- redis.sh
redis-master2:
image: redis:5.0
working_dir: /config
container_name: redis-master2
environment:
- PORT=6392
networks:
redis-cluster:
ipv4_address: 172.50.0.3
ports:
- "6392:6392"
- "16392:16392"
stdin_open: true
tty: true
privileged: true
volumes: [
"/mnt/redis/redis-master2/data:/data",
"/mnt/redis/redis-master2/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime"
]
entrypoint:
- /bin/bash
- redis.sh
redis-master3:
image: redis:5.0
container_name: redis-master3
working_dir: /config
environment:
- PORT=6393
networks:
redis-cluster:
ipv4_address: 172.50.0.4
ports:
- "6393:6393"
- "16393:16393"
stdin_open: true
tty: true
privileged: true
volumes: [
"/mnt/redis/redis-master3/data:/data",
"/mnt/redis/redis-master3/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime"
]
entrypoint:
- /bin/bash
- redis.sh
redis-slave1:
image: redis:5.0
container_name: redis-slave1
working_dir: /config
environment:
- PORT=6394
networks:
redis-cluster:
ipv4_address: 172.50.0.5
ports:
- "6394:6394"
- "16394:16394"
stdin_open: true
tty: true
privileged: true
volumes: [
"/mnt/redis/redis-slave1/data:/data",
"/mnt/redis/redis-slave1/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime"
]
entrypoint:
- /bin/bash
- redis.sh
redis-salve2:
image: redis:5.0
working_dir: /config
container_name: redis-salve2
environment:
- PORT=6395
ports:
- "6395:6395"
- "16395:16395"
stdin_open: true
networks:
redis-cluster:
ipv4_address: 172.50.0.6
tty: true
privileged: true
volumes: [
"/mnt/redis/redis-slave2/data:/data",
"/mnt/redis/redis-slave2/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime"
]
entrypoint:
- /bin/bash
- redis.sh
redis-salve3:
image: redis:5.0
container_name: redis-slave3
working_dir: /config
environment:
- PORT=6396
ports:
- "6396:6396"
- "16396:16396"
stdin_open: true
networks:
redis-cluster:
ipv4_address: 172.50.0.7
tty: true
privileged: true
volumes: [
"/mnt/redis/redis-slave3/data:/data",
"/mnt/redis/redis-slave3/config:/config",
"/mnt/redis/redis.sh:/config/redis.sh",
"/etc/localtime:/etc/localtime"
]
entrypoint:
- /bin/bash
- redis.sh
networks:
redis-cluster:
driver: bridge # 創建一個docker 的橋接網絡
ipam:
driver: default
config:
-
subnet: 172.50.0.0/16
Docker編排Redis集羣
在這裏提供一個批量修改文件,設置密碼的方式(如果你再最開始已經設置密碼,請忽略!!):
sed -i 's/\#\ masterauth\ <master-password>/masterauth\ 123456/g' `grep nodes-63 -rl --include="*.conf" redis/`
sed -i 's/# requirepass foobared/requirepass 123456/g' `grep nodes-63 -rl --include="*.conf" redis/`
docker-compose -f redis-cluster-docker-compose.yml up -d
集羣初始化
# 進入容器內部
docker exec -it redis-master1 bash
# 初始化
redis-cli --cluster create 172.50.0.2:6391 172.50.0.3:6392 172.50.0.4:6393 172.50.0.5:6394 172.50.0.6:6395 172.50.0.7:6396 --cluster-replicas 1
########################################
## 當然你也可以直接這樣執行 ##
########################################
docker exec -it redis-master1 redis-cli --cluster create 172.50.0.2:6391 172.50.0.3:6392 172.50.0.4:6393 172.50.0.5:6394 172.50.0.6:6395 172.50.0.7:6396 --cluster-replicas 1
# 查看一下集羣狀態信息,設置密碼時,不可用
docker exec -it redis-master1 redis-cli -p 6391 --cluster-replicas 1 cluster info
驗證集羣數據一致性
驗證手段:我們再redis-master1創建一條數據(key:testKey,value:1),分別在redis-master2、edis-slave3分片查詢數據(get testKey)。
你可能會用到的命令:
# 進入容器內部
docker exec -it redis-master1 bash
# 連接客戶端
redis-cli -p 6396 -c
# 創建數據
set testKey 1
# 查看數據
get testKey
從上圖可以看出,如果在當前分片沒有get到數據,集羣會自動切換到特定的分片,如果你想了解更多請百度/Google Redis集羣路由規則原理。我們無論從那個節點都能get到數據(slave節點只讀),因此我們的Redis-Cluster 集羣數據具備一致性。