redis---第三部分 多机数据库的实现

 1 复制

2 Sentinel

3 集群

主服务器和集群中的主节点,从服务器和集群中的从节点有什么区别?


 1 复制

1 同步

 

命令传播

 

新版复制功能

部分重同步的实现

1 复制偏移量

## 新版复制功能的实现

PSYNC具有完整重同步和部分重同步两种模式

## 部分重同步的实现

部分重同步功能由以下三个部分构成:

- 主服务器的复制偏移量和从服务器的复制偏移量

- 主服务器的复制积压缓冲区

- 服务器的运行ID

## 心跳检测

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

`REPLCONF ACK <replication_offset>`

- 检测主从服务器的网络连接状态

- 辅助实现`min-slaves`选项

- 检测命令丢失

 

2复制积压缓冲区

3服务器运行ID

 

复制的实现

1 设置主服务器的地址和端口

2 建立套接字连接

3 发送PING命令

4 身份验证

5 发送端口信息

6 同步

7 命令传播

2 Sentinel

# Sentinel

在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

## 检测主观下线状态

在默认情况下,Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例(包括主服务器、从服务器、其他Sentinel在内)发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。

## 检查客观下线状态

当Sentinel从其他Sentinel那里接收到足够数量(超过Sentinel配置中设置的quorum参数的值)的已下线判断之后,Sentinel就会将服务器判定为客观下线,并对主服务器执行故障转移操作

## 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。(Raft算法实现)

 

1 启动并初始化Sentinel

  初始化服务器

  使用Sentinel

  初始化 Sentinel 状态

  初始化 Sentinel 状态的masters属性

  创建连向主服务器的网络连接

2 获取主服务器的信息

3 获取从服务器的信息

4 向主服务器和从服务器发送信息

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

  更新sentinels字典

  创建连向其它Sentinel的命令连接

6 检测主观下线状态

7 检测客观下线状态

  发送SENTINEL is-master-down-by-addr命令

  接收SENTINEL is-master-down-by-addr命令

  接收SENTINEL is-master-down-by-addr命令的回复

8 选举领头Sentinel

9 故障转移

  选出新的主服务器

  修改从服务器的复制目标

  将旧的主服务器变为从服务器

3 集群

1节点

  启动节点

  集群数据结构

 

  CLUSTER MEET命令的实现

2槽指派

## 槽指派

Redis集群通过分片的方式来保存数据库中的键值对:集群的整个数据库被分为16384个槽(slot),数据库中的每个键都属于这16384个槽的其中一个,集群中的每个节点可以处理0个或最多16384个槽

`CLUSTER ADDSLOTS <slot> [slot ...] `

 

  记录节点的槽指派信息

传播节点的槽指派信息

  记录集群所有槽的指派信息

  CLUSTER ADDSLOTS命令的实现

3 在集群中执行命令

  计算键属于哪个槽

### 计算键属于那个槽

```
def slot_number(key):
    return CRC16(key) & 16383
```

  判断槽是否由当前节点负责处理

### 判断槽是否由当前节点负责处理

当节点计算出键所属的槽`i`之后,节点就会检查自己在`clusterState.slots`数组中的项`i`,判断键所在的槽是否由自己负责

  MOVED错误

### MOVED错误

`MOVED <slot> <ip>:<port>`

  节点数据库的实现


### 节点数据库的实现

节点和单机服务器在数据库方面的一个区别是,节点只能使用0号数据库,而单机Redis服务器则没有这一限制

4 重新分片

## 重新分片

Redis集群的重新分片操作是由Redis的集群管理软件redis-trib负责执行的,Redis提供了进行重新分片所需的所有命令,而redis-trib则通过向源节点和目标节点发送命令来进行重新分片操作

5  ASK错误

## ASK错误

ASK错误只是两个节点在迁移槽的过程中使用的一种临时措施

   CLUSTER SETSLOT IMPORTING 命令的实现

   CLUSTER SETSLOT MIGRATING 命令的实现

   ASK错误

   ASKING命令

   ASK错误和MOVED错误的区别

6 复制与故障转移

   设置从节点

## 设置从节点

`CLUSTER REPLICATE <node_id>`

   故障检测

## 故障检测

如果在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线(FAIL),将主节点x标记为已下线的节点会向集群广播一条关于主节点x的FAIL消息,所有收到这条
FAIL消息的节点都会立即将主节点x标记 为已下线。
 

   故障转移

   选举新的主节点

## 选举新的主节点

对于每个配置纪元,集群里每个复制处理槽的主节点都有一次投票的机会,而第一个向主节点要求投票的从节点将获得主节点的投票

如果在一个配置纪元里面没有从节点能搜集到足够多的支持票,那么集群进入一个新的配置纪元,并再次进行选举,直到选出新的主节点为止。

7  消息

   消息头

   MEET、PING、PONG消息的实现

## MEET  PING PONG消息的实现

Redis集群中的各个节点通过Gossip协议来交换各自关于不同节点的状态信息,其中Gossip协议由MEET、PING、PONG三种消息实现

   FAIL消息的实现

   PUBLISH 消息的实现

主服务器和集群中的主节点,从服务器和集群中的从节点有什么区别?

 

主要区别在于:主服务器和从服务器是运行在单机模式(stand alone mode)下的 Redis 服务器,而主节点和从节点则是运行在集群模式(cluster mode)下的 Redis 服务器,服务器所处的模式决定了服务器可以执行的功能。

相同的地方在于:主从服务器和主从节点一样,都是复制关系。