-
哈希槽
Redis集群没有采用一致性hash,而是引入了哈希槽的概念。Redis集群有16384个哈希槽,每个key通过CRC16校验后,对16384取模,来决定放置到哪个哈希槽中。
集群的每个节点都负责一部分的哈希槽。
比如当前有3个接点时,- 节点 A 包含 0 到 5500号哈希槽.
- 节点 B 包含5501 到 11000 号哈希槽.
- 节点 C 包含11001 到 16384号哈希槽.
这种结构很容易进行插入或者删除节点
插入节点D时,只需要将A、B、C节点的部分哈希槽移动到节点D
移除节点A时,只需要将A的哈希槽分给B、C -
集群的主从复制
为了在部分节点无法通信的情况下,集群仍能使用,给集群使用主从复制模型,即给A、B、C分别创建A1、B1、C1三个Slave节点,可以通过在创建集群时通过--cluster-replicas
指定 -
redis哨兵(sentinel),主从自动切换
sentinel(哨兵)是Redis的高可用性解决方案,由一个或多个sentinel实例组成的sentinel系统,可以监视任意多个主服务器,以及主服务器属下的所有从服务器,并在监视的主服务器处于下线状态时,自动将下线主服务器属下的从服务器,升级为新的主服务器。哨兵(sentinel)是一个分布式系统,你可以在一个系统中,运行多个哨兵进程,这些进程使用留言协议(gossipprotocols)来接收主服务器是否下线的信息,并使用投票协议(Agreement Protocols)来决定是否执行自动故障转移,以及选择哪一个slave作为新的Mater。
每个哨兵会定时向其他哨兵、Master、Slave发送消息,以确认对方是否还“活着”,如果发现,在指定的时间(可配置)内,未得到回应,就暂时认为对方已下线,即所谓的“主观认为宕机”。当哨兵群中的多数都认为Master主服务器SDOWN(Subjective Down: 主观认为宕机)。并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,这种方式就是“客观宕机”,英文名称是:Objectively Down, 简称 ODOWN。
通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移(failover)
-
配置哨兵
在redis目录中,有一个sentinel.conf,这个是哨兵的配置文件。修改其中的几个配置项,如下:port 26379 # 默认的端口号 daemonize # 是否后台启动 pidfile # pid文件路径 logfile # log日志地址 sentinel monitor mymaster 127.0.0.1 6379 2 # 设置哨兵监控的主服务器,端口号,以及多少个哨兵确认后,才认为主服务器宕机了(How many replicas we can reconfigure to point to the new replica simultaneously) sentinel down-after-milliseconds mymaster 5000
-
启动哨兵
可以在启动redis-server时,加上--sentinel启动src/redis-server redis.conf --sentinel
也可以单独启动
src/redis-sentinel sentinel.conf
-
-
实践
-
下载redis
wget http://download.redis.io/releases/redis-5.0.3.tar.gz tar zxf redis-5.0.3.tar.gz mv redis-5.0.3 7000 cd 7000 && make
-
修改配置文件
vim 7000/redis.conf # cluster-enabled no => cluster-enabled yes # cluster-config-file nodes.conf # 打开appendonly持久化 appendonly yes # 打开后台运行 daemonize yes # 修改端口号port 7000
-
复制多份
cp -R 7000 7001 #修改7001/redis.conf端口号为7001,下同 cp -R 7000 7002 cp -R 7000 7003 cp -R 7000 7004 cp -R 7000 7005
-
启动多个server
cd 7000 && src/redis-server redis.conf cd 7001 && src/redis-server redis.conf cd 7002 && src/redis-server redis.conf cd 7003 && src/redis-server redis.conf cd 7004 && src/redis-server redis.conf cd 7005 && src/redis-server redis.conf
-
创建集群
cd 7000/src redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replacas 1 # --cluster-replacas 设置后三个节点分别问前三个节点的从节点
以下为输出:
# >>> Performing hash slots allocation on 6 nodes... # Master[0] -> Slots 0 - 5460 # Master[1] -> Slots 5461 - 10922 # Master[2] -> Slots 10923 - 16383 # Adding replica 127.0.0.1:7003 to 127.0.0.1:7000 # Adding replica 127.0.0.1:7004 to 127.0.0.1:7001 # Adding replica 127.0.0.1:7005 to 127.0.0.1:7002 # >>> Trying to optimize slaves allocation for anti-affinity # [WARNING] Some slaves are in the same host as their master # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000 # slots:[0-5460] (5461 slots) master # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001 # slots:[5461-10922] (5462 slots) master # M: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002 # slots:[10923-16383] (5461 slots) master # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003 # replicates c71a7933530d15032e625517de3d706bb29b462d # S: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004 # replicates d84b060378130f42023d3c6006a44b2970f7c96b # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005 # replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b # Can I set the above configuration? (type 'yes' to accept): yes # >>> Nodes configuration updated # >>> Assign a different config epoch to each node # >>> Sending CLUSTER MEET messages to join the cluster # Waiting for the cluster to join # ... # >>> Performing Cluster Check (using node 127.0.0.1:7000) # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000 # slots:[0-5460] (5461 slots) master # 1 additional replica(s) # S: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004 # slots: (0 slots) slave # replicates d84b060378130f42023d3c6006a44b2970f7c96b # M: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002 # slots:[10923-16383] (5461 slots) master # 1 additional replica(s) # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003 # slots: (0 slots) slave # replicates c71a7933530d15032e625517de3d706bb29b462d # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005 # slots: (0 slots) slave # replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001 # slots:[5461-10922] (5462 slots) master # 1 additional replica(s) # [OK] All nodes agree about slots configuration. # >>> Check for open slots... # >>> Check slots coverage... # [OK] All 16384 slots covered.
-
查看
redis-cli -h 127.0.0.1 -p 7000 info # 查看主从信息 # Replication # role:master # connected_slaves:1 # slave0:ip=127.0.0.1,port=7005,state=online,offset=17726,lag=1 redis-cli -h 127.0.0.1 -p 7001 info # 查看主从信息 # Replication # role:master # connected_slaves:1 # slave0:ip=127.0.0.1,port=7003,state=online,offset=17985,lag=1 redis-cli -h 127.0.0.1 -p 7002 info # 查看主从信息 # Replication # role:master # connected_slaves:1 # slave0:ip=127.0.0.1,port=7004,state=online,offset=3474,lag=1
-
操作
-
添加key,获取key
image.png -
kill掉7002之后,主动将7004提升为了Master
image.png -
连接7004查看其信息
7004主动提升为Master -
重新启动7002后,查看7004信息,发现7002变成了7004的从库
7002变为7004的从库 -
添加新的节点
先启动一个新的节点,修改其配置文件类似之前启动的节点,端口号为7006。src/redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000 # >>> Adding node 127.0.0.1:7006 to cluster 127.0.0.1:7000 # >>> Performing Cluster Check (using node 127.0.0.1:7000) # M: fa57c564cc8449b82869fe1c1c97b2f55bad294b 127.0.0.1:7000 # slots:[0-5460] (5461 slots) master # 1 additional replica(s) # M: 265ca55f05999079d903496f58674afdc3b51b18 127.0.0.1:7004 # slots:[10923-16383] (5461 slots) master # 1 additional replica(s) # S: d84b060378130f42023d3c6006a44b2970f7c96b 127.0.0.1:7002 # slots: (0 slots) slave # replicates 265ca55f05999079d903496f58674afdc3b51b18 # S: aee483c4ec738fb10e48e894d299d9eb32bd3372 127.0.0.1:7003 # slots: (0 slots) slave # replicates c71a7933530d15032e625517de3d706bb29b462d # S: 2d136c50a4483ee0b7242cbdb29aeeee5aa4973f 127.0.0.1:7005 # slots: (0 slots) slave # replicates fa57c564cc8449b82869fe1c1c97b2f55bad294b # M: c71a7933530d15032e625517de3d706bb29b462d 127.0.0.1:7001 # slots:[5461-10922] (5462 slots) master # 1 additional replica(s) # [OK] All nodes agree about slots configuration. # >>> Check for open slots... # >>> Check slots coverage... # [OK] All 16384 slots covered. # >>> Send CLUSTER MEET to node 127.0.0.1:7006 to make it join the cluster. # [OK] New node added correctly.
-
查看集群
redis-cli -c -p 7000 cluster nodes #查看集群中的所有节点 ./src/redis-cli --cluster reshard 127.0.0.1:7000 # 重新分配集群中的插槽,将一部分插槽手动移动到新加的节点中 redis-cli -c -p 7006 cluster replicate 0b00721a509444db793d28448d8f02168b94bd38 # 将7006作为7000的从库
-
-