redis学习之集群

算法分
• 阅读 913

每个节点都会保存集群的数据信息,具体对象是clusterNode,这个对象里记录了每个节点创建时间、节点名、节点标识、节点IP、节点端口、负责的槽点等。

typedef struct clusterNode{
    //创建时间
    mstime_t ctime;
    //节点名
    char name[REDIS_CLUSTER_NAMELEN];
    //节点标识,可以表示节点主从角色及节点上下线状态
    int flags;
    //节点配置,用于故障转移
    uint64_t configEpoch;
    //节点ip地址
    char ip[REDIS_IP_STR_LEN];
    //节点端口
    int port;
    //节点相关信息
    clusterLink *link;
    //槽位
    unsigned char slots[16384/8];
    int numslots;
}clusterNode;

在集群中执行命令

客户端向节点发送命令时,节点会根据命令里的key先进行槽位的检查:

def CLUSTER_KEYSLOT(key):
    //计算槽位    
    slot = slot_number(key)
    //返回计算的槽位
    reply_client(slot)

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

这里的CRC16用于计算key的CRC_16校验和(可参考CRC 校验的原理及功用),& 16383(有的版本是%计算?)用于计算0到16383之间的整数(也就是槽位),计算出槽位后,节点会检查自己在clusterState.slots数组中的值,发现是自己负责的槽位后则执行客户端命令,如果发现不是自己负责处理的槽位则返回‘MOVED’错误,指引客户端正确节点。MOVED格式为:
MOVED <slot> <ip>:<port>

为什么是16384个槽位
注:哈希槽是通过一张bitmap的形式来保存

  1. 如果槽位很大,比如为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大
  2. redis的集群主节点数量很大(基本不可能超过1000个)的话可能会造成网络拥堵,集群规模过大时,Gossip 协议的效率会显著下降,通信成本剧增。
  3. 槽位越小,节点少的情况下,压缩比高

故障检测

集群中的每个节点都会定期向其它节点发送PING消息,以此来检测对方是否在线,如果某节点没在规定时间内响应PONG消息,那么发送检测信息的节点会将对方标记为疑似下线(PFAIL)状态并记录在clusterNode的flag里。一旦半数以上的节点将某个节点都标记为了疑似下线状态,那其它节点会将这个节点由疑似下线标记为下线(FAIL)。

故障转移

当一个从节点发现正在复制的主节点是下线状态后,从节点会进行故障转移:

  1. 在之前主节点的所有从节点里选举出新的主节点。
  2. 新的主节点会撤销所有对收己下线主节点的槽指派,将这些槽全部指派给自己。
  3. 新的主节点向集群广播一条PONG消息,让其它从节点知道自己已成了主节点。
  4. 新的主节点开始接收和自己负责处理的槽有关的命令请求,完成故障转移。

选举主节点

  1. 当某个主节点出现故障下线的时候,等延迟一段时间后(下面进行说明),它下面的从节点会向集群里广播一条要求其它主节点进行投票的消息。
  2. 在同一轮投票中,每个主节点都有一次投票的机会,在它收到投票要求且自己还没进行投票时,它就会发起一次投票。
  3. 当一个从节点收集到大于等于N/2+1的投票时,那这个从节点就成为了新的主节点;如果一轮投票里未能产生过半的投票则会进入下一轮的投票,直到主节点选举出。

为什么要进行一段时间的延迟以及怎样做到延迟呢?
节点之间互相进行通信是会一个先后,某个节点出现了故障下线并不是所有节点都会在同一时间知道,假设某个主节点下线了它下面的一个从节点马上发起投票,其它主节点可能并不知道这个主节点已下线而不进行投票。同时进行一个延迟还可以以免所有从节点同时发起投票而导致平票。做到延迟是通过下面公式来的:

DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

其中的SLAVE_RANK指的是此slave已经从master复制数据的总量的rank。rank越小代表已复制的数据越新。一般来说,持有最新数据的slave将会首先发起选举。

redis避免脑裂

通过两个参数预防:
min-slaves-to-write 3
min-slaves-max-lag 10
第一个参数表示连接到master的最少slave数量
第二个参数表示slave连接到master的最大延迟时间
按照上面的配置,要求至少3个slave节点,且数据复制和同步的延迟不能超过10秒,否则的话master就会拒绝写请求

本文参考的有:
黄健宏的《Redis设计与实现》一书

其它链接:
redis高可用

点赞
收藏
评论区
推荐文章
java_wxid java_wxid
4年前
Zookeeper分布式锁?
客户端A要获取分布式锁的时候首先到locker下创建一个临时顺序节点(node_n),然后立即获取locker下的所有(一级)子节点。此时因为会有多个客户端同一时间争取锁,因此locker下的子节点数量就会大于1。对于顺序节点,特点是节点名称后面自动有一个数字编号,先创建的节点数字编号小于后创建的,因此可以将子节点按照节点名称后缀的数字顺序从小到大排序,这样
inode节点扩容
本文分享自天翼云开发者社区《》,作者:2m1.inode概述在Linux系统中,每个文件和目录都有一个对应的inode节点,用于存储文件或目录的元数据信息,如:文件大小、创建时间、修改时间、权限等。当文件或目录被创建时,系统会为其分配一个inode节点。然
Stella981 Stella981
4年前
Redis 集群之 Redis
Redis集群官方推荐方案RedisCluster集群rediscluster  通过分片实࣫容量扩展  通过主从复制实࣫节点的高可用  节点之间互相通信  每个节点都维护整个集群的节点信息  rediscluster把所有的物理节点映射到\016383\slotЇ,cluster负责维护node<sl
Wesley13 Wesley13
4年前
GoJS API学习
varnode{};node"key""节点Key";node"loc""00";//节点坐标node"text""节点名称";//添加节点通过按钮点击,添加新的节点到画布myDiagram.model.addNodeData(nod
Stella981 Stella981
4年前
Kubernetes集群部署之五node节点部署
Node节点是Kubernetes集群中的工作负载节点.每个node都会被master分配一些工作负载,每个node节点都运行以下关键服务进程.Kubelet:负责pod对应的容器的创建、启停等任务,同时与master节点密切协作,实现集群管理的基本功能.Kubeproxy:实现kubernetesservice的通信与负载均衡机制的重要
Stella981 Stella981
4年前
CentOS 7下 部署Redis
redis集群是一个无中心的分布式redis存储架构,可以在多个节点之间进行数据共享,解决了redis高可用、可扩展等问题,redis集群提供了以下两个好处:1)将数据自动切分(split)到多个节点2)当集群中的某一个节点故障时,redis还可以继续处理客户端的请求一个Redis集群包含16384个哈希槽(hashslot
Stella981 Stella981
4年前
JavaScript_DOM中的Model与Object
什么是Model  对象模型即创建对象时浏览器会将HTML文档抽象成树模型,比如一个节点对象就是模型中一个节点的实例,模型中相邻节点之间存在着关系,关系即父子、兄弟,每一个节单对象都保存着指示其他关系节点的“指针”,因此在操作节点对象时我们根据Model的定义可以在头脑里抽象出一个HTML的模型,作为操作节点的导航。下面是一个示例:!
Stella981 Stella981
4年前
Consistent hashing一致性算法原理
最近在整理redis分布式集群,首先就整理一下分布式算法原理。常见的分区规则有哈希分区和顺序分区两种,Redis采用的是哈希分区规则。节点取余分区使用特定的数据,如Redis的键或用户ID为key,节点数量为N,则:hash(key)%N,计算出哈希值,然后决定映射到哪个节点上,如节点数为4时,哈希值的结果可能为0、1、2,3.现假
Stella981 Stella981
4年前
Redis集群概述
原文:http://blog.java1234.com/blog/articles/325.htmlRedisCluster与Redis3.0.0同时发布,以此结束了Redis无官方集群方案的时代,目前,Redis已经发布了3.0.7版本。rediscluster是去中心化,去中间件的,也就是说,集群中的每个节点都是平等的关系,都是对等的,每个节
Stella981 Stella981
4年前
K8s StatfulSet使用总结
StatefulSet:在1.3以前K8s中StatefulSet叫PetSet(宠物集),由此也可看出StatefulSet是关注个体,而非群体。StatefulSet要满足以下几点:稳定且唯一的网络标识符;如:Redis集群,在Redis集群中,它是通过槽位来存储数据的,假如:第一个节点是0~1000,第二个节点是1
VictoriaMetrics常见性能问题排查
VM集群由以下子模块组成vmstorage:存储原始数据,并根据指定时间范围和标签过滤条件等返回查询数据集vminsert:接收数据写入,并根据指标名和标签按一致性hash分发至集群中vmstorage节点vmselect:执行查询请求,从数据所在的vmstorage节点获取数据每个模块可以独立扩缩容。其中vmstorage各节点之间不互相通信,属于sharenothing架构。如此可以增加集群可用性,也简化了集群维护、扩容。
算法分
算法分
Lv1
阶下青苔与红树,雨中寥落月中愁。
文章
2
粉丝
0
获赞
0