搭建一个redis 分布式集群,机器有限,采用不同端口,使用版本 redis-5.0.8
模拟了7台服器,3个主节点4个从节点。6台服务器比较好,3主3从,多建了一台。
ip |
---|
127.0.0.1:6390 |
127.0.0.1:6391 |
127.0.0.1:6392 |
127.0.0.1:6393 |
127.0.0.1:6394 |
127.0.0.1:6395 |
127.0.0.1:63906 |
3个主从节点构成分布式,单个主从节点内部高可用,每个单节点数据只有一部分,整个集群数据是完整的
redis.conf
配置如下 # 修改为yes
daemonize yes
#数据存储目录
dir /root/redis-cluster/6390/data
# 修改为 0.0.0.0
bind 127.0.0.1
# 密码配置,可忽略
requirepass ikamg
masterauth ikang
port 6390
pidfile /var/run/redis_6390.pid
# 开启集群模式
cluster-enabled yes
# 每个集群节点都需要一个配置文件,每个节点处于集群中的角色要告知其他所有节点,这个文件是由redis自己维护的,只需要进行配置即可
cluster-config-file nodes-6390.conf
# 超时时间,超时则认为master宕机,随后进行主备切换
cluster-node-timeout 5000
# 开启AOF
appendonly yes
配置6份配置文件
start-redis.sh
redis-server /root/redis-cluster/6390/redis.conf
redis-server /root/redis-cluster/6391/redis.conf
redis-server /root/redis-cluster/6392/redis.conf
redis-server /root/redis-cluster/6393/redis.conf
redis-server /root/redis-cluster/6394/redis.conf
redis-server /root/redis-cluster/6395/redis.conf
redis-server /root/redis-cluster/6396/redis.conf
./start-redis.sh
Redis 3.x创建分布式集群需要在一个ruby的环境下,在Redis的src目录下执行:redis-trib.rbn, 此处使用 Redis 5.0,不需要ruby 环境,使用
redis-cli cluster
即可
redis-cli --cluster create 127.0.0.1:6390 127.0.0.1:6391 127.0.0.1:6392 127.0.0.1:6393 127.0.0.1:6394 127.0.0.1:6395 127.0.0.1:6396 --cluster-replicas 1
- 槽位一共16384个,用来存储集群中所有数据,数据存储位置是由
hash(key)%16384
计算结果就是存储的槽位- 槽位必须保证完整,副本没有槽位的,当主挂点后副本变为从,主槽位归副本所有
- 如果主挂掉,且没有可用副本,此时槽位不完整,集群不可用
- 超过半数以上主挂掉,不管副本是否完整,集群不可用
M: c6a0f6579d032c3655977adbbe155cf2c35501ee 127.0.0.1:6390
slots:[0-16383] (5461 slots) master
M: 8f1b48b38e31072db126c18385638b088b21fcf2 127.0.0.1:6391
slots:[5461-10922] (5462 slots) master
M: 277b33cdad19aebd54c789dbe00f1037f111fa07 127.0.0.1:6392
slots:[10923-16383] (5461 slots) master
S: d331b6fff4b31901b6d865d9115c762cee195db7 127.0.0.1:6393
replicates 277b33cdad19aebd54c789dbe00f1037f111fa07
S: 36c40c11bc07994eb522311050fdea8351135e11 127.0.0.1:6394
replicates c6a0f6579d032c3655977adbbe155cf2c35501ee
S: 7948767ef8358d9f1e7094936e7f33e5201d5a48 127.0.0.1:6395
replicates c6a0f6579d032c3655977adbbe155cf2c35501ee
S: 4dec11e45d58d9533b5ab2af7f3a3ff295290cd0 127.0.0.1:6396
replicates 8f1b48b38e31072db126c18385638b088b21fcf2
127.0.0.1:6390> set a 1
-> Redirected to slot [15495] located at 127.0.0.1:6392
OK
127.0.0.1:6392> set b 2
-> Redirected to slot [3300] located at 127.0.0.1:6390
OK
127.0.0.1:6390> set c 3
-> Redirected to slot [7365] located at 127.0.0.1:6391
OK
127.0.0.1:6391>
127.0.0.1:6391> get a
-> Redirected to slot [15495] located at 127.0.0.1:6392
"1"
127.0.0.1:6392> get b
-> Redirected to slot [3300] located at 127.0.0.1:6390
"2"
127.0.0.1:6390> get c
-> Redirected to slot [7365] located at 127.0.0.1:6391
"3"
127.0.0.1:6391>
- 写入a=1时:被存储到第 15495槽位,127.0.0.1:6392 slots:[10923-16383], 被存储在 6392上,查询时也是从6392 查询
- 集群没有数据库概念,select 失效,keys * 只能查看登陆节点信息
新增 6380、6381 两个节点,6380为主节点,6381为从
- 新建主节点
- 分配槽位
- 配置主节点
# 127.0.0.1:6380 任意一个新增节点
# 127.0.0.1:6390 任意一个可用节点
redis-cli --cluster add-node 127.0.0.1:6380 127.0.0.1:6390 cluster nodes
#按照节点分配,从那些节点分出一部分槽点给新建节点
redis-cli --cluster reshard 127.0.0.1:6390 --cluster-from c6a0f6579d032c3655977adbbe155cf2c35501ee, 277b33cdad19aebd54c789dbe00f1037f111fa07, 8f1b48b38e31072db126c18385638b088b21fcf2 --cluster-to 99f55dfe4bd4e621760efa79089b51519ae4474d --cluster-slots 4096 --cluster-yes
# 另一种分配方式, 将原有的所有slot进行总量分配
redis-cli --cluster reshard 127.0.0.1:6390 --cluster-from all --cluster-to ac9a38f82c78b7c6f283e1f05c08c8c32726d7dd --cluster-slots 4096 --cluster-yes
redis-cli --cluster add-node 127.0.0.1:6381 127.0.0.1:6390 --cluster-slave --cluster-master-id 99f55dfe4bd4e621760efa79089b51519ae4474d
集群新增了 6380,6381 两个节点,把两个节点删除,
- 先删除从节点6381
- 转移主节点槽位
- 删除主节点6380
# 登陆任意节点 127.0.0.1:6390
redis-cli --cluster del-node 127.0.0.1:6390 e1b0e6fdd23a0ef776cc0893d9bc44adeb1fe5f7
# 转移到其他节点--cluster-from 从哪里转,--cluster-to 到哪 --cluster-slots 槽位个数
redis-cli --cluster reshard 127.0.0.1:6390 --cluster-from 99f55dfe4bd4e621760efa79089b51519ae4474d --cluster-to 277b33cdad19aebd54c789dbe00f1037f111fa07 --cluster-slots 1365 --cluster-yes
redis-cli --cluster reshard 127.0.0.1:6390 --cluster-from 99f55dfe4bd4e621760efa79089b51519ae4474d --cluster-to c6a0f6579d032c3655977adbbe155cf2c35501ee --cluster-slots 1365 --cluster-yes
redis-cli --cluster reshard 127.0.0.1:6390 --cluster-from 99f55dfe4bd4e621760efa79089b51519ae4474d --cluster-to 8f1b48b38e31072db126c18385638b088b21fcf2 --cluster-slots 1365 --cluster-yes
redis-cli --cluster del-node 127.0.0.1:6390 99f55dfe4bd4e621760efa79089b51519ae4474d
删除成功
- 客户端向主节点6390写入数据
- 主节点6390 写入成功后向客户端返回写入成功
- 主节点6390 先从节点同步数据
从上面过程得知,redis集群,保证了AP,数据是弱一致性,强调最终一致性,可能会导致数据丢失。集群内部出现脑裂时,导致数据丢失。
- 每个主节点必须要有一个从节点,槽位分布在主节点的,如果一旦启动一个主节点崩溃,槽位丢失,数据不完整,导致服务不可用
- 数据存储,根据key 的哈希值与槽位取模存储到不同槽位
- 集群创建后,自动分配槽位。