当前位置: 首页 > news >正文

中小学网站建设小程序开发费用是多少

中小学网站建设,小程序开发费用是多少,公司推广渠道,省规划建设发展局网站首页Redis集群是Redis提供的分布式数据库方案#xff0c;通过分片来进行数据共享#xff0c;实现复制和故障转移的功能。 1. Redis集群节点 一个Redis集群由多个节点组成#xff0c;多个节点可以通过命令实现连接#xff0c;由独立状态转为集群状态#xff0c;命令是cluster … Redis集群是Redis提供的分布式数据库方案通过分片来进行数据共享实现复制和故障转移的功能。 1. Redis集群节点 一个Redis集群由多个节点组成多个节点可以通过命令实现连接由独立状态转为集群状态命令是cluster meet ip port比如在A节点上执行此命令指定B节点的ip地址和端口号两个节点通过握手的方式A节点就加入到B节点所在的集群中。 每一个Redis服务器默认是运行在单机模式下的如果想开启集群模式需要在配置文件中开启配置cluster-enabled设置为yes。节点在开启集群模式后会继续使用单机模式中的服务器组件比如会继续执行serverCron函数、正常保存键值对数据进行持久化动作等等。除此之外单个节点还会继续使用Redis服务器的redisServer结构来保存服务器的状态使用redisClient来保存客户端的状态。至于跟集群相关的属性则使用了其他三种属性结构下面我们来看下这些结构。 1.1 clusterNode结构 clusterNode结构用来保存节点当前的状态信息每个节点都会有一个clusterNode结构来保存自身相关状态包含但不限于节点的创建时间、节点名称、配置纪元、ip和端口号等信息贴源码来看下 typedef struct clusterNode {// 节点创建时间mstime_t ctime; /* Node object creation time. */// 节点名称char name[CLUSTER_NAMELEN]; /* Node name, hex string, sha1-size */// 节点目前所处的状态信息int flags; /* CLUSTER_NODE_... */// 节点当前的配置纪元uint64_t configEpoch; /* Last configEpoch observed for this node */// 节点的ip地址char ip[NET_IP_STR_LEN]; /* Latest known IP address of this node */// 节点的端口号int port; /* Latest known clients port of this node */// 与当前节点的连接节点相关的信息如套接字描述符、输入和输出缓冲区clusterLink *link; /* TCP/IP link with this node */... } clusterNode;1.2 clusterLink结构 这个结构表示当前节点的关联节点保存了连接节点的有关信息重要的有套接字描述符、输入缓冲区和输出缓冲区等贴代码看下 typedef struct clusterLink {// 连接的创建时间mstime_t ctime; /* Link creation time */// 套接字描述符int fd; /* TCP socket file descriptor */// 输出缓冲区保存着等待发送给其他节点的消息sds sndbuf; /* Packet send buffer */// 输入缓冲区保存着从其他节点接收到的消息sds rcvbuf; /* Packet reception buffer */// 与这个链接相关联的节点如果没有就是空struct clusterNode *node; /* Node related to this link if any, or NULL */ } clusterLink;1.3 clusterState结构 这个结构记录了在当前节点的视角下集群所处的状态如集群是上线还是下线的状态、有多少个节点配置纪元等信息。先来贴代码看一下 typedef struct clusterState {// 指向代码自身的clusterNode节点clusterNode *myself; /* This node */// 集群当前的配置纪元uint64_t currentEpoch;// 集群当前状态上线还是下线int state; /* CLUSTER_OK, CLUSTER_FAIL, ... */// 集群中节点的数量int size; /* Num of master nodes with at least one slot */// 集群中的节点名单是包含了myselfdict *nodes; /* Hash table of name - clusterNode structures */... } clusterState;所以看一下clusterState和clusterNode属性结构的图示就如下图 1.4 cluster meet命令的实现 通过一个例子看下这个命令的执行步骤。比如我们现在向节点A发送命令CLUSTER MEET 127.0.0.1 6380。其中6380是B节点 首先A节点会创建一个代表B节点clusterNode键值对结构并加入到自己的clusterState.nodes字典中节点A向节点B(127.0.0.1:6380)发送一条meet消息节点B收到消息也会在自己这里创建一个代表A的clusterNode键值对结构并加入到自己的clusterState.nodes字典中节点B向节点A返回一条PONG消息节点A接收到PONG消息时确认节点B接收成功并向节点B返回一条PING消息节点B接收到节点A返回的PING消息双方通信成功握手动作完成。节点B会将节点A的信息传播给集群中的其他节点通过Gossip协议并依次与A节点握手最终A节点被集群中的所有节点所认识。 2. 槽指派 Redis集群通过分片的方式来保存数据集群中整个数据库状态是被拆分为16384个槽(slot)集群中每个节点都可以处理0~16384个槽位中的数据。需要注意的是数据库中16384个槽必须都有对应的节点处理时集群才处于上线的状态否则集群不可用。我们可以通过CLUSTER INFO这个命令来查看所有槽的信息。  我们现在通过cluster meet创建一个由三个结点组成的集群分别是: 127.0.0.1:7001127.0.0.1:7002127.0.0.1:7003 通过cluster nodes命令可以看到三个结点组成的集群情况如下 127.0.0.1:7003 cluster nodes fe75b9fa54c2d657fd9d02ff0bb4b1849 127.0.0.1:700317003 myself,master - 0 1671199866000 0 connected df5936d9fdc9079e1e79b5cc65850be45 127.0.0.1:700117001 master - 0 1671199868687 2 connected c91349f021123rbdd6849c33a9be75331 127.0.0.1:700217002 master - 0 1671199867654 1 connected我们再通过cluster info命令看一下这个集群的状态如下我们可以得出结论由于槽没有进行任何的指派所以集群当前是出于下线状态的cluster_state:fail。 127.0.0.1:7003 cluster info cluster_state:fail cluster_slots_assigned:0 cluster_slots_ok:0 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:0 cluster_current_epoch:2 cluster_my_epoch:0 cluster_stats_messages_ping_sent:146 cluster_stats_messages_pong_sent:138 cluster_stats_messages_meet_sent:1 cluster_stats_messages_sent:285 cluster_stats_messages_ping_received:138 cluster_stats_messages_pong_received:147 cluster_stats_messages_received:285下面我们通过cluster addslots命令把所有的槽分配给集群中的节点把0~5000的槽指派给7001节点把5001~10000的槽指派给7002节点把10001~16383的槽指派给7003节点。执行的命令是 $ redis-cli -p 7001 cluster addslots {0..5000} $ redis-cli -p 7002 cluster addslots {5001..10000} $ redis-cli -p 7003 cluster addslots {10001..16383} 现在在通过cluster nodes和cluster info来看下节点中槽的分配情况可以看到按照我们的指派所有槽都有了对应节点处理此时集群就处于上线的状态。如下 2.1 节点槽指派信息的记录 在节点中每个clusterNode结构有两个属性用于记录当前节点正在负责处理的槽代码 typedef struct clusterNode {// ...unsigned char slots[CLUSTER_SLOTS/8]; /* slots handled by this node */int numslots; /* Number of slots handled by this node */// ... } clusterNode;这里slots是一个二进制的位数组长度是16384占用2048个字节每个元素都是0或者1的取值1代表这个位的槽归属当前节点处理0表示不负责处理。numslots表示负责的槽的数量其实就是上面这个数组的长度。下面表示一个实例 2.2 槽指派信息的传播 一个节点除了记录自己的clusterNode负责的槽之外还会将自己负责的槽通过消息发送给集群中所有的节点通过此种方式集群中所有的节点就知道了其余节点负责的槽信息避免冲突。具体是这样的 比如节点A负责0~5000的槽节点B通过消息得知后会把自己clusterState.nodes字典中表示A节点的clusterNode找出来并保存或更新这个节点的slots信息。同理其他节点也会发送或者接受槽信息最终达到互相传播的目的。 2.3 记录集群中槽的分配情况 通过2.2我们其实已经知道了集群中所有节点负责的槽位但是redis还通过另一种方式记录了集群中槽位的指派情况是通过clusterState.slots这个数组来表示的。 typedef struct clusterState {...clusterNode *slots[CLUSTER_SLOTS];... } clusterState;这个slots数组每一项都是一个指针指向负责这个槽的clusterNode结构。 需要区别的是2.1中的slots数组是在clusterNode结构中而这里的slots数组是在clusterState结构中。那么为什么要重复记录这个槽指派信息呢因为仅仅通过2.1中的槽位数组想知道某个槽归哪个节点负责需要遍历所有的节点时间复杂度是O(N)而通过clusterState.slots时间复杂度是O(1)。 所以通过2.1和2.3中的数组我们了解到clusterState.slots记录了集群中所有槽的指派信息而clusterNode.slots记录了这个节点负责的槽指派信息。现在我们可以通过节点找到它负责的槽也可以通过槽找到负责它的节点时间复杂度都是O(1)。 其实cluster addslots命令可以指派槽也是通过这两个数组实现的首先把参数中的槽记录到clusterState.slots数组中然后再把对应的clusterNodes.slots节点数组中的槽从0→1最后再通过消息广播到集群中的其他节点。 3. 命令执行 当所有的槽位都有对应的节点处理后集群上线处于可用状态了。当客户端向集群中某个节点发送命令时此节点会计算键值对的key经过计算后是否由本节点处理计算公式 slot CRC16(KEY) 16383也就是经过CRC16算法计算key的校验和再与16383做位与运算。命令cluster keyslot key就是通过此函数计算某个key所属于哪个槽然后再查询clusterState.slots数组找对应的clusterNode节点。  这里计算出来的slot可能不属于当前节点处理那么节点会向客户端返回一个MOVED错误并引导客户端转向正确的节点从新发送命令类似于http的重定向。如果计算的slot属于当前节点处理会执行命令后返回。  MOVED错误命令的格式为MOVED slot ip : port其中slot是计算出来的键所在的槽Ip和port是负责处理此槽的节点。  集群节点和单机服务器在保存键值对及过期时间的方式是一样的唯一区别是节点只能使用0号数据库单机服务器没有此限制。此外节点还会使用clusterState.slots_to_key来保存键值对和槽位的对应关系使用跳跃表来实现。跳跃表的每个节点分值是槽号节点成员是数据库键值鉴于跳跃表分值可以重复的属性允许存在槽号相同键值对不同的情况。 typedef struct clusterState {...rax *slots_to_keys;... } clusterState;4. 重新分片 Redis集群的重新分片可以将指派给节点A的槽重新指派给其他节点并且槽所属的键值对也会做对应的迁移。这种操作可以在线(online)进行重新分片的过程中集群不需要下线迁移双方的节点都可以继续处理命令。 重新分片的操作由Redis集群的管理软件redis-trib负责执行redis-trib通过向源节点和目标节点发送命令来完成重新分片的动作。重新分片是通过clusterState结构的两个属性完成的看代码如下 typedef struct clusterState {...clusterNode *migrating_slots_to[CLUSTER_SLOTS];clusterNode *importing_slots_from[CLUSTER_SLOTS];... } clusterState;migrating_slots_to和importing_slots_from是两个指针数组长度都是16384数组中每一项都指向一个clusterNode结构。 migrating_slots_to表示当前节点作为源节点正在向其他节点迁移的槽数组中每一项要么指向null要么指向一个正在迁移的目标clusterNode结构。  importing_slots_from表示当前节点作为目标节点正在接受其他节点迁移的槽数组中的每一项要么指向null要么指向一个正在迁移的源clusterNode结构。 4.1 ASK错误 如果节点收到一个键值对的命令请求并且key对应的槽正好属于当前节点那么节点会在自己的数据库中查找key如果找到的话节点就会执行命令。 与之相反如果没能找到key节点会检查clusterState.migrating_slots_to[i]对应的槽是不是正在处于迁移的状态如果是会向客户端返回ASK的错误引导客户端到正在导入的目标节点去查找键key。 这里需要注意MOVED错误和ASK错误他们都会引导客户端转向其他节点但是MOVED表示当前key不属于当前节点的槽指派且集群没有进行重分片的操作而ASK错误是节点在进行重分配过程中的临时措施节点在找不到key且节点处于迁移槽的过程中向客户端返回ASK错误进行重定向的操作。 5. 复制与故障转移 Redis集群中的节点分为主节点和从节点其中主节点用来处理槽信息从节点用来复制主节点的数据且在主节点下线时进行故障转移代替主节点继续处理命令请求。 5.1 主从复制 向集群中一个节点发送命令cluster replicate node_id可以让此节点成为node_id指定节点的从节点。接受命令的节点会将clusterState.myself.slaveof设置为目标主节点。 typedef struct clusterNode {...struct clusterNode **slaves; /* pointers to slave nodes */struct clusterNode *slaveof; /* pointer to the master node. Note that it... } clusterNode;slaves 属性数组表示如果当前是主节点clusterNode.flagsREDIS_NODE_MASTER数组中的每一项都指向自己的从节点。slaveof 属性表示如果当前是从节点clusterNode.flagsREDIS_NODE_SLAVE指针指向自己跟随的主节点。 5.2 故障检测与转移 当主节点因某些原因下线后从节点经过选举升级为主节点开始接替原来主节点处理槽具体步骤如下 主节点下线从节点有一个会被选中为主节点从节点执行slave of no one升级为主节点新的主节点会撤销原主节点的槽指派并将这些槽指派给自己新的主节点会向集群中所有节点广播一个PONG消息集群中所有节点都将知道此从节点已升级为主节点。新的主节点开始接收和处理命令请求故障转移完成。 这里比较关键的一点是主节点下线后如何在众多的从节点中选举出一个合适的节点作为新的主节点。这里的选举机制和哨兵机制选举领头sentinel原理相似都是基于Raft算法来实现的。 集群中每个节点都会定期向其余节点发送 PING消息以此检测对方是否在线如果在指定时间内有节点没有回复PONG消息那么发送PING消息的节点就会将此节点设置为疑似下线。由于集群中每个节点都是通过互发消息来交换集群中所有节点的状态信息当一个主节点A感知到集群中一半以上的主节点都将某个主节点B置为疑似下线后A节点就会将B节点置为已下线并且向集群中广播一条节点B已下线的消息其余所有主节点都会将B节点标记已下线。 当从节点通过消息得知自己复制的主节点已经下线了此时故障转移就开始了。 从节点发现自己复制的主节点下线了会向集群中所有的主节点发送消息要求接收到消息的主节点将选举的票投给自己所有收到消息的主节点会检查在此纪元内自己有没有投过票。如果是首次投票就将此票投给第一个发送消息的从节点并且记录后面所有从节点要求投票的消息都会拒绝发送投票消息的从节点只要有一个首先收集到了 n/2 1 张票时就会升级为新的主节点本轮投票结束所有节点纪元 1。如果本轮投票所有从节点都没有收集到足够的票数会继续进行下一轮直到选举出新的主节点。
http://www.zqtcl.cn/news/732713/

相关文章:

  • 网站开发项目可行性分析单位logo设计
  • 做最好的美食分享网站网站源码网站
  • 宝塔搭建app教程360优化大师下载
  • 杭州网站制作 乐云践新开发公司竣工员工奖励计划
  • 绍兴市越城区建设局网站网站策划运营方案书
  • 怎么查网站备案信息查询wordpress 新安装 慢
  • 做一个卖东西的网站深圳市住房和建设局网站变更
  • 一个公司做几个网站绵阳房产网
  • 广州做网站服务怎样做网站反链
  • 淘宝客网站制作视频教程flash做网站的论文
  • wordpress keywords 用逗号 区分关键字南昌网站优化方案
  • 清华大学网站建设方案郑州建网站企业
  • 闸北网站优化公司网站表格代码
  • 网站里面如何做下载的app深圳企业社保登录入口
  • 中国网站建设哪家公司好网站开头flash怎么做
  • 南磨房做网站公司黑马程序员就业情况
  • 电子商务网站运营方案建设银行网站查询密码设置
  • 网站服务器哪些好用php做的录入成绩的网站
  • 网站建设需要哪些信息vi设计什么意思
  • 苏州吴中区专业做网站玉树市公司网站建设
  • wordpress 不换行沈阳网站制作优化
  • 要维护公司的网站该怎么做怎么联系创意设计网站
  • 阿里云wordpress搭建网站网站如何做app
  • 做微商哪个网站比较好wordpress5.0.2运行慢
  • 中牟高端网站建设建自己的个人网站
  • 网站前台架构WordPress 分类 调用
  • 腾讯用户体验网站哈尔滨百姓网
  • 上海品质网站建设深圳自适应网站制作
  • gta5此网站正在建设更换wordpress后台登陆地址
  • 做花馍网站怎么做自己的简历网站