自己主机做网站服务器,网站建设的实施方式,平板电脑可以做淘宝网站吗,网站设计 字体引言
相比于Codis#xff0c;Redis Cluster是Redis官方提供的解决方案。相比于Codis的不同#xff0c;他是去中心化的#xff0c;如图所示#xff0c;该集群有三个Redis节点组成#xff0c;每个节点负责整个集群的一部分数据#xff0c;每个节点负责的数据多少可能不一样…引言
相比于CodisRedis Cluster是Redis官方提供的解决方案。相比于Codis的不同他是去中心化的如图所示该集群有三个Redis节点组成每个节点负责整个集群的一部分数据每个节点负责的数据多少可能不一样。三个节点相互连接组成一个对等的集群他们之间通过一种特殊的二进制协议Gossip相互交互集群信息。
Redis Cluster 将所有数据划分成16384个slots相比Codis的1024个槽划分的更为精细每个节点负责其中一部分槽位。槽位的信息存储于每个节点中他不像Codis他不需要另外的分布式存储来存储节点槽位信息。
当Redis Cluster的客户端来连接集群时他也会得到一份集群的槽位配置信息。这样当客户端要查找某个key时可以直接定位到目标节点。
槽位定位算法
Cluster默认会对key值使用crc32算法进行hash得到一个整数值然后用这个整数值对16384进行取模来得到具体槽位。
跳转
当客户端向一个错误的节点发出了指令该节点会发现指令的key所在的槽位并不归自己管理这时他会向客户端发送一个特殊的跳转指令携带目标操作的节点地址告诉客户端去连这个节点去获取数据。
Get x - MOVED 3999 127.0.0.1:6381MOVED 指令的第一个参数3999 是key对应的槽位编号后面是目标节点地址。 MOVED 前面有一个 - 表示该指令是一个错误消息。
客户端收到MOVED指令后会立即纠正本地的槽位映射表。后续所有key将使用新的槽位映射表。
迁移
迁移过程 Redis迁移单位是槽Redis是一个槽一个槽进行迁移当一个槽正在迁移时这个槽就处于中间过渡状态。这个槽在原节点的状态为migrating在目标节点的状态为importing表示数据正在从源流向目标。
迁移工具redis-trib首先 1. 会在源和目标节点设置好中间过渡状态然后 2. 一次性获取源节点槽位的所有key列表keysinslot指令可以部分获取在挨个key进行迁移。每个key的迁移过程是以原节点作为目标节点的客户端。3. 原节点对当前的key执行dump指令得到序列化的内容然后向目标节点发送指令restore携带序列化的内容作为参数目标节点在进行反序列化就可以将内容恢复到目标节点的内存中4. 原节点收到目标节点的ok响应后就把当前节点的key删除掉就完成了单个key迁移的整个过程。
从源节点获取内容 存到目标节点 从源节点删除内容
这里的迁移过程是同步的在目标节点执行restore指令到原节点删除key之间原节点的主线程会处于阻塞状态直到key删除成功。
如果迁移过程中突然出现网络故障整个slot的迁移只进行了一半这时两个节点依旧处于中间过渡状态待下一次迁移工具重新连上时会继续进行迁移。
在迁移过程中如果每个key的内容都很小migrate指令执行会很快就不会影响客户端的正常访问。如果key的内容很大因为migrate指令是阻塞指令会同时导致原节点和目标节点卡顿影响集群稳定性。所以 在集群环境下业务逻辑要尽可能避免大key的产生。
Asking
在迁移过程中客户端访问的流程会有很大的变化。
首先新旧两个节点对应的槽位都存在部分key数据客户端先尝试访问旧节点如果对应得数据还在旧节点里面那么旧节点正常处理。如果对应的数据不在旧节点里面那么有两种可能要么该数据在新节点里要么根本不存在。旧节点不知道属于哪种情况所以他会向客户端返回一个-ASK targetNodeAddr重定向指令客户端收到这个重定向指令后先向目标节点执行一个不带任何参数的asking指令然后在目标节点在重新执行原先的操作指令。
容错
Redis Cluster可以为每个主节点设置若干个从节点单主节点故障时集群会自动将其中某个从节点提升为主节点。如果某个主节点没有从节点那么当他发生故障时集群将完全处于不可用状态。
网络抖动
Redis Cluster提供了一种选项 cluster-node-timeout表示当某个节点持续timeout的时间失联时才可以认定该节点出现故障需要进行主从切换。如果没有这个选项网络抖动会导致主从频繁切换。
可能下线与确定下线
因为Redis Cluster是去中心化的一个节点认为某个节点失联了并不代表所有节点都认为他失联。所以集群还得经过一次协商的过程只有当大多数节点都认定了某个节点失联了集群才认为该节点需要进行主从切换来容错。
Redis集群节点采用Gossip协议来广播自己的状态以及自己对整个集群认知的改变。比如一个节点发现某个节点失联了他会将这条信息向整个集群广播其他节点也就可以收到这条失联信息。如果一个节点收到了某个节点失联的数量已经达到了集群的大多数就可以标记该节点为确定下线状态然后向整个集群广播强迫其他节点也接受该节点已经下线的事实并立即对该失联节点进行主从切换。
槽位迁移感知
如果Cluster中某个槽位正在迁移或者已经迁移完了client如何能感知到槽位的变化客户端保存了槽位和节点的映射关系表他需要即时得到更新才可以正常的将某条指令发到正确的节点中。
前面所述两个特殊的error指令一个是moved一个是asking。
第一个moved是用来纠正槽位的如果我们将指令发送到了错误的节点该节点发现对应的指令槽位不归自己管理就会将目标节点的地址随同moved指令回复给客户端通知客户端去目标节点去访问。这个时候客户端就会刷新自己的槽位关系表然后重试指令后续所有打在该槽位的指令都会转到目标节点。
第二个asking指令和moved不一样他是用来临时纠正槽位的。如果当前槽位正处于迁移中指令会先被发送到槽位所在的旧节点如果旧节点存在数据那就直接返回结果如果不存在那么他可能真的不存在也可能被迁移到其他节点上。所以旧节点会通知客户端去新节点尝试拿数据看看新节点有没有这时候就会给客户端返回一个asking error携带上目标节点的地址。客户端收到这个asking error后就会去目标节点尝试客户端不会刷新槽位映射关系表因为他只是临时纠正该指令的槽位信息。
集群变更感知
当服务器节点变更时客户端应该及时得到通知以实时刷新自己的节点关系表。客户端如何得到通知需要分成以下2种情况 目标节点挂掉了客户端会抛出一个ConnectionError紧接着会随机挑一个节点来重试这时被重试的节点会通过moved error告知目标槽位被分配到的新的节点地址。 运维手动修改了配置信息将master切换到其他节点并将旧的master移除集群。这时打在旧节点上的指令会收到一个ClusterDown的错误告知当前节点所在集群不可用。这时客户端会关闭所有连接清空槽位映射关系表然后向上层抛出错误。待下一条指令过来时就会重新尝试初始化节点信息。