Redis集群是Redis分布式解决方案,解决了单机中心化的问题
一、理论基础
主要包括2部分:节点主从、哈希Slot(槽)
节点主从:
1、master可由有多个slaver,slaver可以有自己的slaver,主从关系手动指定,当master下线后slaver会自动升为master;
2、读写分离,master负责写以及数据同步给slaver,slaver负责读,slaver扩容提高读效率;
3、slaver获取master数据后压入磁盘,再load进内存,client端从内存中读取数据,当增加一个slaver,会主动通知master,master将全量数据发送给slaver,数据量大将影响性能;
优点:读写分离,增加slaver提交读的并发能力;
缺点:master写是瓶颈;
hash slot
1、对象保存前先进行CRC16哈希到指定slot(节点);
2、每个节点分配一个slot段,slot不能缺失也不能重复;
3、node之间相互监听,一旦有node退出或加入,会按照slot为单位做数据迁移;
优点:每个node互相监听,高并发数据写入、读出,任务繁重;
优点:将写操作分摊到了多个节点,提高写并发,扩容简单;
节点主从 && 哈希slot
1、主从和hash相互弥补优缺点;
2、先hash分逻辑节点,每个节点内部主从;
3、扩展并发读添加slaver,扩展并发写添加master;
二、集群搭建
集群操作:
//集群(cluster)
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
//节点(node)
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
//槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
//键 (key)
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
1、安装redis镜像
yimaoqian@yimaoqian ~ docker pull redis
2、修改配置文件
下载redishttp://download.redis.io/releases/,解压后得到redis.conf,添加或修改如下配置:
bind 0.0.0.0
daemonize no
requirepass 123456
masterauth 123456
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
3、运行redis集群
使用6个redis节点,3主3从
docker run --privileged=true --name redis1 --net redis-net -p 6001:6379 -v $PWD/6001/conf/redis.conf:/data/config/redis.conf -v $PWD/6001/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
docker run --privileged=true --name redis2 --net redis-net -p 6002:6379 -v $PWD/6002/conf/redis.conf:/data/config/redis.conf -v $PWD/6002/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
docker run --privileged=true --name redis3 --net redis-net -p 6003:6379 -v $PWD/6003/conf/redis.conf:/data/config/redis.conf -v $PWD/6003/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
docker run --privileged=true --name redis4 --net redis-net -p 6004:6379 -v $PWD/6004/conf/redis.conf:/data/config/redis.conf -v $PWD/6004/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
docker run --privileged=true --name redis5 --net redis-net -p 6005:6379 -v $PWD/6005/conf/redis.conf:/data/config/redis.conf -v $PWD/6005/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
docker run --privileged=true --name redis6 --net redis-net -p 6006:6379 -v $PWD/6006/conf/redis.conf:/data/config/redis.conf -v $PWD/6006/data:/data -d redis:latest redis-server /data/config/redis.conf --appendonly yes
4、查看容器状态
yimaoqian@yimaoqian ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
264773dfc76a redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6006->6379/tcp redis6
cf017727c5e1 redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6005->6379/tcp redis5
ab6041e6e5c2 redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6004->6379/tcp redis4
8faeccf80150 redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6003->6379/tcp redis3
bdb2a392c8c9 redis:latest "docker-entrypoint.s…" 3 hours ago Up 3 hours 0.0.0.0:6002->6379/tcp redis2
a986b0a1a4d8 redis:latest "docker-entrypoint.s…" 3 hours ago Up 37 minutes 0.0.0.0:6001->6379/tcp redis1
5、运行redis集群容器
查看容器IP:
yimaoqian@yimaoqian ~/wutong/specialGroup/redis docker inspect redis1 redis2 redis3 redis4 redis5 redis6|grep IPA
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.2",
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.3",
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.4",
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.5",
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.6",
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAMConfig": null,
"IPAddress": "172.20.0.7",
集群感知:
localhost:6001> CLUSTER MEET 172.20.0.3 6379
OK
localhost:6001> CLUSTER MEET 172.20.0.4 6379
OK
localhost:6001> CLUSTER MEET 172.20.0.5 6379
OK
localhost:6001> CLUSTER MEET 172.20.0.6 6379
OK
localhost:6001> CLUSTER MEET 172.20.0.7 6379
OK
localhost:6001> cluster nodes
a4cfac29113a66a278c37268d2ca49fb62873e93 172.20.0.7:6379@16379 master - 0 1572328475000 5 connected
e3316f5cdc75a7e7ea259c3b9a00dee4dc6afb4c 172.20.0.5:6379@16379 master - 0 1572328476000 3 connected
8a5363c38e406227ffcc89080edd4b84d0d22ba4 172.20.0.2:6379@16379 myself,master - 0 1572328474000 1 connected
a179d778c65c3caeeaca5f095fb4a1380453a07a 172.20.0.4:6379@16379 master - 0 1572328476510 2 connected
fdddf383f8bf53447926e5efb80a7405ec85294d 172.20.0.3:6379@16379 master - 0 1572328474495 0 connected
383bd17b9a8c3a64f664637dd7cdb764a17324b8 172.20.0.6:6379@16379 master - 0 1572328475000 4 connected
分配slot:
查看槽信息
localhost:6001> CLUSTER INFO
cluster_state:fail
cluster_slots_assigned:0 # 被分配槽的个数为0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:2
cluster_stats_messages_ping_sent:260418
cluster_stats_messages_pong_sent:260087
cluster_stats_messages_meet_sent:10
cluster_stats_messages_sent:520515
cluster_stats_messages_ping_received:260086
cluster_stats_messages_pong_received:260328
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:520415
分配槽位:
#!/bin/bash
# node1 localhost:6001 172.20.0.2
n=0
for ((i=n;i<=5461;i++))
do
/usr/local/bin/redis-cli -h localhost -p 6001 -a 123456 CLUSTER ADDSLOTS $i
done
# node2 localhost:6002 172.20.0.3
n=5462
for ((i=n;i<=10922;i++))
do
/usr/local/bin/redis-cli -h localhost -p 6002 -a 123456 CLUSTER ADDSLOTS $i
done
# node3 localhost:6003 172.20.0.4
n=10923
for ((i=n;i<=16383;i++))
do
/usr/local/bin/redis-cli -h localhost -p 6003 -a 123456 CLUSTER ADDSLOTS $i
done
6、高可用
添加从节点:
#!/bin/bash
/usr/local/bin/redis-cli -h localhost -p 6004 -a 123456 CLUSTER REPLICATE 8a5363c38e406227ffcc89080edd4b84d0d22ba4
/usr/local/bin/redis-cli -h localhost -p 6005 -a 123456 CLUSTER REPLICATE fdddf383f8bf53447926e5efb80a7405ec85294d
/usr/local/bin/redis-cli -h localhost -p 6006 -a 123456 CLUSTER REPLICATE a179d778c65c3caeeaca5f095fb4a1380453a07a
1、备用节点不允许分配槽位;
2、在当前节点操作,将当前节点添加为node_id的副本节点;
3、从节点需要运行在cluster模式下,先添加到集群,再做复制;
查看节点信息:3主3从高可用
ocalhost:6004> cluster nodes
a4cfac29113a66a278c37268d2ca49fb62873e93 172.20.0.7:6379@16379 slave a179d778c65c3caeeaca5f095fb4a1380453a07a 0 1572332713422 5 connected
a179d778c65c3caeeaca5f095fb4a1380453a07a 172.20.0.4:6379@16379 master - 0 1572332714428 2 connected 10923-16383
fdddf383f8bf53447926e5efb80a7405ec85294d 172.20.0.3:6379@16379 master - 0 1572332712417 0 connected 5462-10922
383bd17b9a8c3a64f664637dd7cdb764a17324b8 172.20.0.6:6379@16379 slave fdddf383f8bf53447926e5efb80a7405ec85294d 0 1572332713000 4 connected
e3316f5cdc75a7e7ea259c3b9a00dee4dc6afb4c 172.20.0.5:6379@16379 myself,master - 0 1572332712000 6 connected 0-5461
8a5363c38e406227ffcc89080edd4b84d0d22ba4 172.20.0.2:6379@16379 slave e3316f5cdc75a7e7ea259c3b9a00dee4dc6afb4c 0 1572332712000 6 connected