Redis部署

178 阅读6分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

主从复制

replicaof masterip masterport

读写分离, 数据容灾

全量同步

  • 同步快照
  • 同步写缓冲
  • 同步增量阶段

增量同步

  • slave完成初始化开始正常工作, master每执行一个写命令就会向slave发送相同的写命令

心跳检测

命令传播阶段, 从服务器默认以每秒一次的频率向主服务器发送命令,

replconf ack <replcation_off>

作用:

  • 检测主从的连接状态

  • 辅助实现min-slaves

    min-replicas-to-write 3
    min-replicas-max-lag 10
    

    从服务器的数量少于3个或者三个从服务器的延迟都大于或等于10秒, 主服务器拒绝执行写命令

  • 检测命令丢失

哨兵模式

部署

Master

daemonize yes
#bind 127.0.0.1 
protected-mode no

Slave

replicaof 127.0.0.1 6379

Sentinel

daemonize yes
# 主节点的ip port quorum 当quorum个哨兵认为主节点失联, 客观下线  
sentinel monitor mymaster 127.0.0.1 6379 2
# 主节点 requirepass 123
sentinel auth-pass mymaster 123
# 多少毫秒后,主节点没有应答哨兵, 主观下线 默认30秒
sentinel down-after-milliseconds mymaster 30000
#数字越小,完成failover所需时间越长,数字越大, 越多的slave因为replication不可用, 保证每次只有一个slave处于不能处理命令的状态
sentinel parallel-syncs mymaster 1
# 故障转移时间  默认三分钟
sentinel failover-timeout mymaster 180000
  • 启动并初始化Sentinel

    sentinel 实例不会持久化, 会创建两个连向主服务器的网络连接。

    命令连接: 用于向主服务器发送命令,并接收响应

    订阅连接: 用于订阅主服务器的-sentinel-:hello品道

  • 获取主服务器信息

    每10s向被监控的主服务器发送info, 获取主服务器和从服务器信息

  • 获取从服务器信息

    每10s向从服务器发送info

  • 向主服务器和从服务器发送消息(订阅)

    每2s向所有的主从服务器所订阅的-sentinel-:hello频道上发送消息, 消息中会携带sentinel信息和主服务器信息

  • 接收来自主服务器和从服务器的频道信息

    sentinel订阅-sentinel-:hello

  • 检测主观下线状态

    sentinel每秒向所有建立了命令连接的实例发送PING命令

    实例在down-after-milliseconds毫秒内返回无效回复(除了+PONG、-LOADING、-MASTERDOWN外),如果无回复,就认为是主观下线(SDown)

  • 检查客观下线状态

    当认为是主观下线后, Sentinel向同时监控这个主服务器的Sentinel发送查询命令, 如果达到quorum数量的Sentinel实例都认为主观下线,则主服务器被判定为客观下线(ODown)

故障转移

Raft: leader, follower, candidate

通过raft选举出Leader Sentinel后, 执行故障转移操作。

  • 失效Master的其中一个Slave升级为Master,其他slave复制新的master
  • 客户端连接失效的master,集群返回新master的地址
  • master和slave服务器切换后,master的redis.conf,slave的redis.conf和sentinel.conf的配置文件发生相应改变。

主服务器选择规则:

  • 过滤掉主观下线节点
  • 选择slave-priority最高的节点
  • 选择复制偏移量最大的节点
  • 选择run_id最小的节点

Cluster

去中心化, sharding, replication, failover

Gossip

通信协议,传播消息的方式。

一个节点周期性随机选择一些节点,并把信息传递给这些节点。信息会周期性的传递给N个目标节点。 N被称为fanout(删除)。

消息主要包含 meet, ping, pong, fail ,publish等

slot

平均分配,连续分配。【0-16383】

value-slot-节点

对key使用crc16算法结果后对16384求余数, 这样大致均等的映射到不同的节点

port 7001
cluster-enable yes
 ./redis-cli --cluster create 192.168.72.128:7001 192.168.72.128:7002 192.168.72.128:7003 192.168.72.128:7004 192.168.72.128:7005 192.168.72.128:7006 --cluster-replicas 1
cluster nodes 
cluster slots
cluster keyslot name

moved重定向 槽已确认迁移

ask重定向 槽正在迁移

进行集群扩容和缩容,对槽进行迁移

迁移

  • B的slot状态设为importing
  • A的slot状态设为migrating
  • 向A发送migrate命令
  • cluster setslot重新设置槽位

扩容:

./redis-cli --cluster add-node 192.168.72.128:7007 192.168.72.128:7001

 ./redis-cli --cluster reshard 192.168.72.128:7007
 
 ./redis-cli --cluster add-node 192.168.72.128:7008 192.168.72.128:7007 -- cluster-slave --cluster-master-id 6ff20bf463c954e977b213f0e36f3efc02bd53d6

缩容:

./redis-cli --cluster del-node 192.168.127.128:7008 6be94480315ab0dd2276a7f70c82c578535d6666

容灾

故障检测

每个节点定期向其他节点发送PING消息,一定时间(cluster-node-timeout),A没收到B的PONG回应, A将B标识为pfail, 后续发送时会带上B的pfail信息,通知其他节点, 标记B为pfail的个数大于集群主节点个数的一半, B被标记为fail, A向整个集群广播,节点下线。

从节点选举

raft,每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举。slave 通过向其他master发送FAILVOER_AUTH_REQUEST 消息发起竞选,master 收到后回复FAILOVER_AUTH_ACK 消息告知是否同意。slave 发送FAILOVER_AUTH_REQUEST 前会将currentEpoch 自增,并将最新的Epoch 带入到FAILOVER_AUTH_REQUEST 消息中,如果自己未投过票,则回复同意,否则回复拒绝。所有的Master开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 +1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。

RedisCluster失效的判定:1、集群中半数以上的主节点都宕机(无法投票)2、宕机的主节点的从节点也宕机了(slot槽分配不连续)

手动切换

人工故障切换是预期的操作,而非发生了真正的故障,目的是以一种安全的方式(数据无丢失)将当前master节点和其中一个slave节点(执行cluster-failover的节点)交换角色

1、向从节点发送cluster failover 命令(slaveof no one)

2、从节点告知其主节点要进行手动切换(CLUSTERMSG_TYPE_MFSTART)

3、主节点会阻塞所有客户端命令的执行(10s)

4、从节点从主节点的ping包中获得主节点的复制偏移量

5、从节点复制达到偏移量,发起选举、统计选票、赢得选举、升级为主节点并更新配置

6、切换完成后,原主节点向所有客户端发送moved指令重定向到新的主节点

以上是在主节点在线情况下。

如果主节点下线了,则采用cluster failover force或cluster failover takeover 进行强制切换。