redis集群的搭建
参考: https://www.jianshu.com/p/9622d5906bcf
1. 集群的介绍
1. redis集群,无论有几个节点,一共只有16384个槽
所有的槽位都必须分配,哪怕有1个槽位不正常,整个集群都不能用
每个节点的槽的顺序不重要,重点是数量
2. hash算法足够随机,足够平均
每个槽被分配到数据的概率是相当的
3. 集群的高可用依赖于主从复制
4. 集群拥有自己的配置文件,动态更新,不要手欠修改
5. 集群通讯会使用基础端口号+10000的端口,这个是自动创建的,不是配置文件配置的
6. 集群槽位分配比例允许误差在%2之间
集群通讯会使用基础端口号+10000的端口,这个是自动创建的,不是配置文件配置的
哨兵模式的不足:
资源的利用率低
主库压力大
连接过程繁琐
集群的架构图
当是这种架构的时候
我们使用这种
2. 集群的搭建
端口
主节点端口号 | 6380 |
---|---|
从节点的端口号 | 6381 |
192.168.80.51 | db01 |
---|---|
192.168.80.11 | web04 |
192.168.80.8 | web03 |
2.1 目录的创建
三台都做
mkdir -p /opt/redis_cluster/redis_{6380,6381}/{conf,logs,pid}
mkdir -p /data/redis_{6380,6381}
2.2 master配置文件三台
cat >/opt/redis_cluster/redis_6380/conf/redis_6380.conf<<EOF
bind $(ifconfig eth0 | awk 'NR==2 {print $2}')
port 6380
daemonize yes
pidfile "/opt/redis_cluster/redis_6380/pid/redis_6380.pid"
logfile "/opt/redis_cluster/redis_6380/logs/redis_6380.log"
dbfilename "redis_6380.rdb"
dir "/data/redis_6380/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes
cluster-config-file nodes_6380.conf
cluster-node-timeout 15000
EOF
2.3 slave的配置文件三台
cat >/opt/redis_cluster/redis_6381/conf/redis_6381.conf<<EOF
bind $(ifconfig eth0 | awk 'NR==2 {print $2}')
port 6381
daemonize yes
pidfile "/opt/redis_cluster/redis_6381/pid/redis_6381.pid"
logfile "/opt/redis_cluster/redis_6381/logs/redis_6381.log"
dbfilename "redis_6381.rdb"
dir "/data/redis_6381/"
appendonly yes
appendfilename "redis.aof"
appendfsync everysec
cluster-enabled yes
cluster-config-file nodes_6381.conf
cluster-node-timeout 15000
EOF
2.4 集群的管理脚本
mkdir /server
cd /server
vim redis_shell.sh
#!/bin/bash
#redis集群的启动管理脚本,主要更改的就是文件路径的问题
men(){
echo "bash reids_shell.sh {start|stop|login|ps|restart|tail}"
}
if [ "$#" = 1 ];then
REDIS_PORT=6379
elif [ "$#" = 2 -a -z "$(echo $2 |sed 's#[0-9]##g')" ]
then
REDIS_PORT="$2"
else
men
exit 0
fi
REDIS_IP=`ifconfig eth0|awk 'NR==2 {print $2}'`
REDIS_DIR=/opt/redis_cluster/redis_${REDIS_PORT}
REDIS_CONF=/opt/redis_cluster/redis_${REDIS_PORT}/conf/redis_${REDIS_PORT}.conf
REDIS_LOGS=/opt/redis_cluster/redis_${REDIS_PORT}/logs/redis_${REDIS_PORT}.log
REDIS_START(){
redis-server ${REDIS_CONF}
}
REDIS_STOP(){
redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT} shutdown
}
REDIS_LOGIN(){
redis-cli -c -h ${REDIS_IP} -p ${REDIS_PORT}
}
REDIS_PS(){
ps -ef | grep redis
}
REDIS_TAIL(){
tail -f ${REDIS_LOGS}
}
case $1 in
start)
REDIS_START
REDIS_PS
;;
stop)
REDIS_STOP
REDIS_PS
;;
ps)
REDIS_PS
;;
tail)
REDIS_TAIL
;;
login)
REDIS_LOGIN
;;
restart)
REDIS_STOP
REDIS_START
REDIS_PS
;;
*)
men
;;
esac
根据自己的目录不同进行修改
集群的启动
sh redis-shell.sh start 6380
sh redis-shell.sh start 6381
端口号
[root@db01 server]# netstat -lntup | grep redis
tcp 0 0 192.168.80.51:6380 0.0.0.0:* LISTEN 88275/redis-server
tcp 0 0 192.168.80.51:6381 0.0.0.0:* LISTEN 88314/redis-server
tcp 0 0 192.168.80.51:16380 0.0.0.0:* LISTEN 88275/redis-server
tcp 0 0 192.168.80.51:16381 0.0.0.0:* LISTEN 88314/redis-server
2.5 systemctl的启动方式(与上边二选一)
6380
cat >/usr/lib/systemd/system/redis-master.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_cluster/redis_6380/conf/redis_6380.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print $2}') -p 6380 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
6381
cat >/usr/lib/systemd/system/redis-master.service<<EOF
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /opt/redis_cluster/redis_6381/conf/redis_6381.conf --supervised systemd
ExecStop=/usr/local/bin/redis-cli -h $(ifconfig eth0|awk 'NR==2{print $2}') -p 6381 shutdown
Type=notify
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
EOF
2.6 手动发现集群节点
CLUSTER MEET ip port
sh redis_shell.sh login 6380
CLUSTER MEET 192.168.80.51 6381
CLUSTER MEET 192.168.80.11 6381
CLUSTER MEET 192.168.80.11 6380
CLUSTER MEET 192.168.80.9 6380
CLUSTER MEET 192.168.80.9 6381
192.168.80.51:6380> CLUSTER NODES
3f419d104a13004f8f3b4029fe18bc2b48e1b070 192.168.80.51:6381@16381 master - 0 1638350410182 1 connected
e8847af82f07a2c6206a516aa1f93b5b043ca6bf 192.168.80.11:6381@16381 master - 0 1638350412210 0 connected
92960e21bf51dc9370f1ab5168db5355b1be4c96 192.168.80.51:6380@16380 myself,master - 0 1638350409000 3 connected
4833c4341fd5dd16f955e7bdfdc7bc44b03cfdbc 192.168.80.9:6380@16380 master - 0 1638350410000 4 connected
72e824af1822c6acf08417d69f1b7d208c0a1da9 192.168.80.11:6380@16380 master - 0 1638350409178 2 connected
84d4cc130eb10ea82c4f6f4800098d3f5b976dbd 192.168.80.9:6381@16381 master - 0 1638350411192 5 connected
解释
84d4cc130eb10ea82c4f6f4800098d3f5b976dbd 192.168.80.9:6381@16381 master - 0 1638350411192 5 connected
id号 也是下边进行复制关系的用到的
2.7 槽位的规划
db01:6380 5461 0-5460
web04:6380 5461 5461-10921
web03:6380 5462 10922-16383
分配
redis-cli -h 192.168.80.51 -p 6380 CLUSTER ADDSLOTS {0..5460}
redis-cli -h 192.168.80.11 -p 6380 CLUSTER ADDSLOTS {5461..10921}
redis-cli -h 192.168.80.9 -p 6380 CLUSTER ADDSLOTS {10922..16383}
192.168.80.51:6380> CLUSTER NODES
d758f75d76e73361f67a740fdd6a99d4dc42c55e 192.168.80.9:6381@16381 master - 0 1638351022000 0 connected
ca41a886abdf45a2e799999832eab16e3da860f6 192.168.80.51:6380@16380 myself,master - 0 1638351020000 2 connected 0-5460
6bc969b0fba3741a3e8374a35ac29142e254b9c2 192.168.80.11:6381@16381 master - 0 1638351023000 3 connected
cea53a5efac3147cfdbf03f2f6c77f1dee6a7f65 192.168.80.11:6380@16380 master - 0 1638351021844 5 connected 5461-10921
2b9d112e78122fcc5867d3e2f8b6f4876c9852c3 192.168.80.9:6380@16380 master - 0 1638351022000 4 connected 10922-16383
id 槽位(这个跟序号没有关系)
6910e90378cfaf52882e73a68ea891ba512f75c6 192.168.80.51:6381@16381 master - 0 1638351023867 1 connected
192.168.80.51:6380> CLUSTER INFO
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_ping_sent:147
cluster_stats_messages_pong_sent:157
cluster_stats_messages_meet_sent:5
cluster_stats_messages_sent:309
cluster_stats_messages_ping_received:157
cluster_stats_messages_pong_received:152
cluster_stats_messages_received:309
2.8 确定复制关系
过程
redis-cli -h db01 -p 6381 CLUSTER REPLICATE web03的6380的id
redis-cli -h web04 -p 6381 CLUSTER REPLICATE db01的6380的id
redis-cli -h web03 -p 6381 CLUSTER REPLICATE web04的6380的id
redis-cli -h 192.168.80.51 -p 6381 CLUSTER REPLICATE d758f75d76e73361f67a740fdd6a99d4dc42c55e
redis-cli -h 192.168.80.11 -p 6381 CLUSTER REPLICATE ca41a886abdf45a2e799999832eab16e3da860f6
redis-cli -h 192.168.80.9 -p 6381 CLUSTER REPLICATE cea53a5efac3147cfdbf03f2f6c77f1dee6a7f65
检查复制关系
redis-cli -h db01 -p 6380 CLUSTER NODES
[root@db01 ~]# redis-cli -h db01 -p 6380 CLUSTER NODES
d758f75d76e73361f67a740fdd6a99d4dc42c55e 192.168.80.9:6381@16381 slave cea53a5efac3147cfdbf03f2f6c77f1dee6a7f65 0 1638351731000 5 connected
ca41a886abdf45a2e799999832eab16e3da860f6 192.168.80.51:6380@16380 myself,master - 0 1638351727000 2 connected 0-5460
6bc969b0fba3741a3e8374a35ac29142e254b9c2 192.168.80.11:6381@16381 slave ca41a886abdf45a2e799999832eab16e3da860f6 0 1638351731000 3 connected
cea53a5efac3147cfdbf03f2f6c77f1dee6a7f65 192.168.80.11:6380@16380 master - 0 1638351728000 5 connected 5461-10921
2b9d112e78122fcc5867d3e2f8b6f4876c9852c3 192.168.80.9:6380@16380 master - 0 1638351732024 4 connected 10922-16383
6910e90378cfaf52882e73a68ea891ba512f75c6 192.168.80.51:6381@16381 slave 2b9d112e78122fcc5867d3e2f8b6f4876c9852c3 0 1638351731016 4 connected
插入一条数据
192.168.80.51:6380> set k1 v1
-> Redirected to slot [12706] located at 192.168.80.9:6380
OK
192.168.80.9:6380> get k1
"v1"
192.168.80.9:6380>
插入不成功报错的原因
192.168.80.51:6380> set k1 v1
(error) MOVED 12706 10.0.0.53:6380
原因
在db01的6380节点插入数据提示报错
报错内容提示应该移动到web03的6380上
在web03的6380上执行相同的插入命令可以插入成功
在db01的6380节点插入数据有时候可以,有时候不行
使用-c参数后,可以正常插入命令,并且节点切换到了提示的对应节点上
因为集群模式有ASK路由规则,加入-c参数后,会自动跳转到目标节点处理
并且最后由目标节点返回信息
误差查看
[root@db01 server]# redis-cli --cluster rebalance 192.168.80.51 6380
>>> Performing Cluster Check (using node 192.168.80.51:6380)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.