写点什么

redis 集群

作者:想要飞的猪
  • 2022-11-21
    广东
  • 本文字数:7312 字

    阅读完需:约 24 分钟

一、主从复制


实现:主服务器不需要特殊配置,修改从服务器 redis.conf


#repllicaof [主服务器ip 端口号] replicaof 127.0.0.1 6379
复制代码


作用:


1、读写分离 ,一主多从,提 redis 高性能和吞吐量


2、数据容灾,主机宕机,从机可读不可写,默认情况下从机不可变为主机,可利用哨兵机制,实现主从切换,实现高可用。
复制代码


原理与实现:


当客户端向从服务器发送主服务器ip 与端口时,从服务器将主机的ip 与端口保存到redisServer的moasterhost 和masterport中。
Struct redisServer{ char*masterhost;// 主服务器ip int masterport;// 主服务器端口}
复制代码


从服务器将向发送 SLAVEOF 命令的客户端返回 OK,表示复制命令以及被接收,而实际上复制工作是在 ok 返回之后进行。


建立 socket 连接


slave 与 master 建立 socket 连接,slave 关联文件事件处理器,第一次连接时接收 RDB 文件(全量复制),后面接收 master 传播来的写命令(增量复制)


实现方式


redis 的同步功能分为同步(sync)和命令传播(command propagate)。


1)同步操作


1、通过从服务器发送到 sync 命令给主服务器


2、主服务器生成 rdb 文件并发送给从服务器,同时发送保存所有写命令从服务器


3、从服务器清空以前的数据并执行 rdb 文件。


4、保持数据一致性(还需要命令传播过程才能操持一致)


2)命令传播操作


同步操作完成后,主服务器执行写命令,该命令发送给从服务器并执行,使主从一致。


缺点:


没有全部同步和增来给你同步的概念,从服务器在同步的时候每次都会清空以前的数据,主从断线了之后重新复制,主从服务器会重新生成新的 rdb 文件和重新记录缓存区的所有命令并且同步给从服务器。


新版 2.8 之后:


在 redis 2.8 之后使用 psync 命令,具备完整重同步和部分同步模式。


redis 主从同步,分为全量同步和增量同步,只有在第一次的时候是全量同步,断线之后可能会触发全量同步或者是增量同步(master 根据 runid 来判断)


全量同步分为三步:


一、同步快找 rdb 文件(master 创建并发送 rdb 文件给 slave,slave 载入并且解析,master 同时将此阶段所产生的写命令存储到缓存区)


二、同步写缓存区(master 向 slave 不同缓存区写操作命令)


三、同步增量阶段(master 向 slave 同步写操作命令)


增量同步


  • redis 增量同步主要指的是 slave 初始化完成之后,master 发生写操作时同步到 salve 的过程

  • 一般情况下 master 没执行一个写命令就会向 slave 发送相同的写命令,然后 slave 接收并执行。


二、哨兵模式


哨兵模式是 redis 的一种高可用解决方案,sentinel 监控主从,当主机宕机时,可以实现故障转移,把其中一个从服务器升级为主服务器(实现原理就是:修改所有的 sentinel 的 sentinel.conf 与主从的 redis.conf 配置文件内容实现把从服务器升级问主服务器)


配置:


sentinel 监控集群只需要需改


# 哨兵sentinel监控的redis主节点的 ip port # master-name 可以自己#命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。 #quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提 供密码 # 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
复制代码


执行流程


1、启动初始化 sentinel,sentinel 时一个特殊的 redis 服务器,不会进行持久化,sentinel 实列启动后,每个 sentinel 会创建 2 个连向主服务器的网络连接;


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


订阅连接:用于订阅主服务器的一个—sentinel—:hello d��(频道。


2、sentinel 默认没 10 秒一次,向被监控的额主服务器发送 info 命令,获取主服务器和其下属服务器的信息。


3、获取从服务器的信息,当 sentinel 发现主服务器有新的从服务器出现时,sentinel 还会向从服务器建立命令里那句和订阅连接,在简练连接之后,sentinel 化石会默认 10s 一次,向从服务器发送 info 命令,并记录从服务器的信息。


4、向主服务器和从服务器发送消息(以订阅的方式)


默认情况下,sentinel 没 2s 一次,向所有被监控的主服务器和从服务器所订阅的—sentinel—:hello 频道上发送消息,消息中会携带 sentinel 自身的信息和主服务器的信息。


5、检测主管下线状态


sentinel 每秒钟一次向所有与它建立了命令里那句的实列(主服务器与从服务器和其他的 sentinel)发送 ping 命令,如果有实列在配置的时间捏返回无效回复或者是超时,sentinel 就会主观的认为该实列下线。


6、检查客观下线


当一个 sentinel 将一个主机判断为主管下线之后,sentinel 会向同时监控这个主服务器的所有其他的 sentinel 发送查询该主机的命令。当认为该主机下线了的 sentinel 数量达到 quorum 数量时,则该主机就会被判定为下线。


选举 leader sentinel


当要给主机被客观下线了之后,监控这个主服务器的所有 sentinel 就会通过选举算法(raft0,选举出一个 leader sentinel 去执行(failover)故障转移操作。


sentinel 的 leader 选举流程


1、当一个 sentinel 判断一个主机客观下线了之后,该 sentinel 会先看看自己有没有投过票,如果以及给其他的 sentinel 投过票了,在一定时间内自己就不会成为 leader 了;


2、当没有投过票时,那么二它就成为 candidate(候选者)


3、sentinel 需要做几件事情:


  • 更新故障转移状态为 start

  • 当前 epoch 加 1 相当于进入一个新的 term (选举任期)

  • 向其他节点发送 is-master-down-by-addr 命令请求投票,命令会带上自己的额 epoch

  • 给自己投一票


4、当其他的 sentinel 收到哨兵命令时,可以同意或者时拒绝它成为领导者(通过判断 epoch)


5、candidate 会不断的额统计自己的额票数,当它发现自己的票数超过一半并且超过配置的 quorum 时,这时它就成为了 leader


6、其他的 sentinel 等待 leader 从 slave 选举出 master 后,检测到新的 master 正常工作后,就会去掉客观下线的标识。


主服务器的选择:


去掉宕机的主服务器,在 salve 中选择 salve-priority 最高的,没有最高的就看偏移量最大的,没有则选择 run_id 最小的节点。


三、集群 cluster


分区


 分区是将数据分布到多台redis实实例上,以至于每个实例包含一部分数据。
复制代码


分区的意义:


  • 性能提升

  • 存储能力的横向扩展


分区方式


根据分区键(id)进行分区


  1. 优点:实现简单,迁移方便缺点:热点数据分布不均,性能损失


client 端分区


对应给定的一个 key,客户端直接选择确认正确的节点来进行读取,许多 redis 客户端都实现了客户端分区,如 JedisPool,也可以自行编程实现。


实现算法


hash 算法:直接使用 key 的 hash(key)%N;


优点:实现简单,热点数据分布均匀;
缺点:节点数固定,扩展的话需要重新计算
复制代码


一致性 hash:一致性 hash 是对 2^32(4294967296)取模,把 2^32 想象 4 成一个圆,就像一个钟表,总共有 0 到 2^32-1 数字,我们把这个想象的圆称为 hash 环。


 把服务器映射到hash环上,比如我们呢有ABC三个服务器时,这三台服务器根据ip地址的hash (ip)% 2^32 得到对应的位置,存数据时算出key的hash (key),在环上顺时针寻找,遇到的第一个服务器就是目标节点。
复制代码


存在 hash 环偏移的问题,解决方案就是添加虚拟节点。


优点:添加或者移除节点时,数据只需要做部分的迁移;
缺点:复杂度高,不易扩展(需要手动迁移部分key),
复制代码


官方 cluster 分区


   方案采用去中心化的方式,包括:sharding(分区),replication(复制),failover(故障转移),称为RedisCluster。
复制代码


采用 Gossip 协议(起源与病毒传播):


大概思想一个节点周期性的随机选取一个节点,把信息传播给它,收到消息的节点会做同样的操作
复制代码


slot:redis 采用槽的形式,把所有的物理节点映射到[0-16383]个 slot 上,基本上采用平均分配和连续分配。


为啥时16383个?根据作者博客回复,hash采用的是crc16算法,本来crc16 是有2^16 个数,因为redis cluster超过一千时就会有问题,所以16383已经完全够用了,而且还能减少信息传播时的信息大小。
复制代码


故障检查


集群中的每个节点都会定期地向集群中的其他节点发送PING命令,如果A在一定时间内,没有收到B节点的回应,则A将B标识为pfail,A在后续发送PING命令时则会带上B的pfail信息,通知其他节点,但B被超过集群的一半节点标识为pfail时,则B会被标识为fail,则A向整个集群广播,该节点下线。
复制代码


从节点选举


raft,每个节点都对自己的 master 复制数据的 offset,来设置选举时间,offset 越大(复制的数据越多)的从节点,选举时间越靠前,优先进行选举。


副本漂移


在集群中有一主一从时,但某个节点变为了一主 0 从时,会在集群中找到最多从节点的,把其中的一个从节点改为没有从节点的主节点的 slave。


cluster 注意问题:


mget 性能下降,可能会导致整个集群暂时不可用。


解决方案:


方案一:传统的串行 IO 操作,也就是说 N 个 key 分为 N 次取;


方案二:将 mget 要操作的 key,利用已知使用的 hash 计算出对应的节点,然后合并相同的 key,得到 map<node,keys>


方案三:在方案二的基础上,把合并后的取数据并行进行;


方案四:通过 rerdis 自带的 hashtag 功能,强制把一些 key 分配到某一台机器上()

实现:主服务器不需要特殊配置,修改从服务器 redis.conf


#repllicaof [主服务器ip 端口号] replicaof 127.0.0.1 6379
复制代码


作用:


1、读写分离 ,一主多从,提 redis 高性能和吞吐量


2、数据容灾,主机宕机,从机可读不可写,默认情况下从机不可变为主机,可利用哨兵机制,实现主从切换,实现高可用。
复制代码


原理与实现:


当客户端向从服务器发送主服务器ip 与端口时,从服务器将主机的ip 与端口保存到redisServer的moasterhost 和masterport中。
Struct redisServer{ char*masterhost;// 主服务器ip int masterport;// 主服务器端口}
复制代码


从服务器将向发送 SLAVEOF 命令的客户端返回 OK,表示复制命令以及被接收,而实际上复制工作是在 ok 返回之后进行。


建立 socket 连接


slave 与 master 建立 socket 连接,slave 关联文件事件处理器,第一次连接时接收 RDB 文件(全量复制),后面接收 master 传播来的写命令(增量复制)


实现方式


redis 的同步功能分为同步(sync)和命令传播(command propagate)。


1)同步操作


1、通过从服务器发送到 sync 命令给主服务器


2、主服务器生成 rdb 文件并发送给从服务器,同时发送保存所有写命令从服务器


3、从服务器清空以前的数据并执行 rdb 文件。


4、保持数据一致性(还需要命令传播过程才能操持一致)


2)命令传播操作


同步操作完成后,主服务器执行写命令,该命令发送给从服务器并执行,使主从一致。


缺点:


没有全部同步和增来给你同步的概念,从服务器在同步的时候每次都会清空以前的数据,主从断线了之后重新复制,主从服务器会重新生成新的 rdb 文件和重新记录缓存区的所有命令并且同步给从服务器。


新版 2.8 之后:


在 redis 2.8 之后使用 psync 命令,具备完整重同步和部分同步模式。


redis 主从同步,分为全量同步和增量同步,只有在第一次的时候是全量同步,断线之后可能会触发全量同步或者是增量同步(master 根据 runid 来判断)


全量同步分为三步:


一、同步快找 rdb 文件(master 创建并发送 rdb 文件给 slave,slave 载入并且解析,master 同时将此阶段所产生的写命令存储到缓存区)


二、同步写缓存区(master 向 slave 不同缓存区写操作命令)


三、同步增量阶段(master 向 slave 同步写操作命令)


增量同步


  • redis 增量同步主要指的是 slave 初始化完成之后,master 发生写操作时同步到 salve 的过程

  • 一般情况下 master 没执行一个写命令就会向 slave 发送相同的写命令,然后 slave 接收并执行。


二、哨兵模式


哨兵模式是 redis 的一种高可用解决方案,sentinel 监控主从,当主机宕机时,可以实现故障转移,把其中一个从服务器升级为主服务器(实现原理就是:修改所有的 sentinel 的 sentinel.conf 与主从的 redis.conf 配置文件内容实现把从服务器升级问主服务器)


配置:


sentinel 监控集群只需要需改


# 哨兵sentinel监控的redis主节点的 ip port # master-name 可以自己#命名的主节点名字 只能由字母A-z、数字0-9 、这三个字符".-_"组成。 #quorum 当这些quorum个数sentinel哨兵认为master主节点失联 那么这时 客观上认为主节点失联了 # sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2# 当在Redis实例中开启了requirepass foobared 授权密码 这样所有连接Redis实例的客户端都要提 供密码 # 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码 # sentinel auth-pass <master-name> <password> sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
复制代码


执行流程


1、启动初始化 sentinel,sentinel 时一个特殊的 redis 服务器,不会进行持久化,sentinel 实列启动后,每个 sentinel 会创建 2 个连向主服务器的网络连接;


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


订阅连接:用于订阅主服务器的一个—sentinel—:hello d��(频道。


2、sentinel 默认没 10 秒一次,向被监控的额主服务器发送 info 命令,获取主服务器和其下属服务器的信息。


3、获取从服务器的信息,当 sentinel 发现主服务器有新的从服务器出现时,sentinel 还会向从服务器建立命令里那句和订阅连接,在简练连接之后,sentinel 化石会默认 10s 一次,向从服务器发送 info 命令,并记录从服务器的信息。


4、向主服务器和从服务器发送消息(以订阅的方式)


默认情况下,sentinel 没 2s 一次,向所有被监控的主服务器和从服务器所订阅的—sentinel—:hello 频道上发送消息,消息中会携带 sentinel 自身的信息和主服务器的信息。


5、检测主管下线状态


sentinel 每秒钟一次向所有与它建立了命令里那句的实列(主服务器与从服务器和其他的 sentinel)发送 ping 命令,如果有实列在配置的时间捏返回无效回复或者是超时,sentinel 就会主观的认为该实列下线。


6、检查客观下线


当一个 sentinel 将一个主机判断为主管下线之后,sentinel 会向同时监控这个主服务器的所有其他的 sentinel 发送查询该主机的命令。当认为该主机下线了的 sentinel 数量达到 quorum 数量时,则该主机就会被判定为下线。


选举 leader sentinel


当要给主机被客观下线了之后,监控这个主服务器的所有 sentinel 就会通过选举算法(raft0,选举出一个 leader sentinel 去执行(failover)故障转移操作。


sentinel 的 leader 选举流程


1、当一个 sentinel 判断一个主机客观下线了之后,该 sentinel 会先看看自己有没有投过票,如果以及给其他的 sentinel 投过票了,在一定时间内自己就不会成为 leader 了;


2、当没有投过票时,那么二它就成为 candidate(候选者)


3、sentinel 需要做几件事情:


  • 更新故障转移状态为 start

  • 当前 epoch 加 1 相当于进入一个新的 term (选举任期)

  • 向其他节点发送 is-master-down-by-addr 命令请求投票,命令会带上自己的额 epoch

  • 给自己投一票


4、当其他的 sentinel 收到哨兵命令时,可以同意或者时拒绝它成为领导者(通过判断 epoch)


5、candidate 会不断的额统计自己的额票数,当它发现自己的票数超过一半并且超过配置的 quorum 时,这时它就成为了 leader


6、其他的 sentinel 等待 leader 从 slave 选举出 master 后,检测到新的 master 正常工作后,就会去掉客观下线的标识。


主服务器的选择:


去掉宕机的主服务器,在 salve 中选择 salve-priority 最高的,没有最高的就看偏移量最大的,没有则选择 run_id 最小的节点。


三、集群 cluster


分区


 分区是将数据分布到多台redis实实例上,以至于每个实例包含一部分数据。
复制代码


分区的意义:


  • 性能提升

  • 存储能力的横向扩展


分区方式


根据分区键(id)进行分区


  1. 优点:实现简单,迁移方便缺点:热点数据分布不均,性能损失


client 端分区


对应给定的一个 key,客户端直接选择确认正确的节点来进行读取,许多 redis 客户端都实现了客户端分区,如 JedisPool,也可以自行编程实现。


实现算法


hash 算法:直接使用 key 的 hash(key)%N;


优点:实现简单,热点数据分布均匀;
缺点:节点数固定,扩展的话需要重新计算
复制代码


一致性 hash:一致性 hash 是对 2^32(4294967296)取模,把 2^32 想象 4 成一个圆,就像一个钟表,总共有 0 到 2^32-1 数字,我们把这个想象的圆称为 hash 环。


 把服务器映射到hash环上,比如我们呢有ABC三个服务器时,这三台服务器根据ip地址的hash (ip)% 2^32 得到对应的位置,存数据时算出key的hash (key),在环上顺时针寻找,遇到的第一个服务器就是目标节点。
复制代码


存在 hash 环偏移的问题,解决方案就是添加虚拟节点。


优点:添加或者移除节点时,数据只需要做部分的迁移;
缺点:复杂度高,不易扩展(需要手动迁移部分key),
复制代码


官方 cluster 分区


   方案采用去中心化的方式,包括:sharding(分区),replication(复制),failover(故障转移),称为RedisCluster。
复制代码


采用 Gossip 协议(起源与病毒传播):


大概思想一个节点周期性的随机选取一个节点,把信息传播给它,收到消息的节点会做同样的操作
复制代码


slot:redis 采用槽的形式,把所有的物理节点映射到[0-16383]个 slot 上,基本上采用平均分配和连续分配。


为啥时16383个?根据作者博客回复,hash采用的是crc16算法,本来crc16 是有2^16 个数,因为redis cluster超过一千时就会有问题,所以16383已经完全够用了,而且还能减少信息传播时的信息大小。
复制代码


故障检查


集群中的每个节点都会定期地向集群中的其他节点发送PING命令,如果A在一定时间内,没有收到B节点的回应,则A将B标识为pfail,A在后续发送PING命令时则会带上B的pfail信息,通知其他节点,但B被超过集群的一半节点标识为pfail时,则B会被标识为fail,则A向整个集群广播,该节点下线。
复制代码


从节点选举


raft,每个节点都对自己的 master 复制数据的 offset,来设置选举时间,offset 越大(复制的数据越多)的从节点,选举时间越靠前,优先进行选举。


副本漂移


在集群中有一主一从时,但某个节点变为了一主 0 从时,会在集群中找到最多从节点的,把其中的一个从节点改为没有从节点的主节点的 slave。


cluster 注意问题:


mget 性能下降,可能会导致整个集群暂时不可用。


解决方案:


方案一:传统的串行 IO 操作,也就是说 N 个 key 分为 N 次取;


方案二:将 mget 要操作的 key,利用已知使用的 hash 计算出对应的节点,然后合并相同的 key,得到 map<node,keys>


方案三:在方案二的基础上,把合并后的取数据并行进行;


方案四:通过 rerdis 自带的 hashtag 功能,强制把一些 key 分配到某一台机器上()

用户头像

还未添加个人签名 2020-06-05 加入

还未添加个人简介

评论

发布
暂无评论
redis 集群_redis哨兵集群_想要飞的猪_InfoQ写作社区