幼儿饰品瑜伽美体用品微软
投稿投诉
微软创意
爱情通信
用品婚姻
爱好看病
美体软件
影音星座
瑜伽周边
星座办公
饰品塑形
搞笑减肥
幼儿两性
智家潮品

浅谈集群的分类

  本文主要介绍集群部署相关的知识,介绍集群部署的基础,集群的分类、集群的负载均衡技术,集群的可用性以及集群的容错机制。随后介绍RedisCluster以及Mysql的架构以及主从复制原理。
  单台服务器本身会受到带宽、内存、处理器等多方面因素的影响,当通过垂直扩展已经无法提升系统性能时,我们就需要通过水平扩展,即以集群的方式来部署服务。集群在提升性能的同时,也可以减轻单机器的压力,提高系统的可用性。这就是我们常说的加机器,简单粗暴,但非常有效。
  提到集群,一定会想到分布式,不过要注意这两者的区别。集群强调的是服务的多个副本冗余部署;分布式强调的是将整个系统拆分成多个子系统独立开发、维护和运行,每个子系统仍然以集群的方式部署。RedisCluster就是典型的分布式系统,每个节点采用一主多从的集群方式部署。
  RedisCliuster架构图
  对于集群的分类,网上说最多的就是分成高性能集群、高可用集群、负载均衡集群,但我却不敢苟同。我认为三者之间是分不开的,你中有我,我中有你,比如通过负载均衡就可以实现高性能、高可用,或者说负载均衡是手段,高性能高可用是结果。所以我更倾向于将集群分成两种:即无状态服务的水平扩展集群和有状态的主从集群。
  无状态服务的水平扩展集群
  该方式实现的前提是服务本身是无状态的,举例来说,如果服务是一个Web应用,访问界面需要用户登录态,如果session是保留在本地服务器上,那么这个服务就是有状态的。如果用户的多次请求打到了不同的机器上,就会出现重复登录的问题。但如果session存储在中间件中,比如Redis,那么就是无状态的。
  通过机器的水平扩容,就构建了服务的集群,随后通过负载均衡的算法,将请求分散到不同的机器上。
  负载均衡几个比较重要的指标:负载均衡算法、容错机制以及健康检测。负载均衡算法
  1、随机算法
  思想:服务集群中的每个服务都配置一个权重weight,默认是100。如果所有权重相等,则随机选择一个;如果权重不等,即为加权随机算法。比如现在有两个服务A,B,权重分别是100,200,那么选取比例就是13,23。
  Dubbo实现算法:OverrideprotectedTInvokerTdoSelect(ListInvokerTinvokers,URLurl,Invocationinvocation){Numberofinvokersintlengthinvokers。size();Everyinvokerhasthesameweight?booleansameWeighttrue;theweightofeveryinvokersint〔〕weightsnewint〔length〕;thefirstinvokersweightintfirstWeightgetWeight(invokers。get(0),invocation);weights〔0〕firstWeight;ThesumofweightsinttotalWeightfirstWeight;for(inti1;ilength;i){intweightgetWeight(invokers。get(i),invocation);saveforlateruseweights〔i〕weight;SumtotalWeightweight;if(sameWeightweight!firstWeight){sameWeightfalse;}}if(totalWeight0!sameWeight){随机选取小于总权重的整数intoffsetThreadLocalRandom。current()。nextInt(totalWeight);这个是关键,如果减去总权重是负数,即为选中的Invokerfor(inti0;ilength;i){offsetweights〔i〕;if(offset0){returninvokers。get(i);}}}完全随机returninvokers。get(ThreadLocalRandom。current()。nextInt(length));}
  2、RoundRobin轮询
  最简单的轮询就是依次轮询,比如有N台服务器,编号从0到N1依次轮询执行,没有任何的复杂算法。
  下面是一个简单的实现:publicclassRoundRobinBalance{publicstaticfinalListIntegerselectListLists。newArrayList(1,2,3);privateintgetWeight(Integerinteger){returninteger;}privateAtomicIntegeratomicIntegernewAtomicInteger(1);publicintsimpleRoundRobin(){intindexatomicInteger。addAndGet(1);intlengthselectList。size();if(indexlength){indexatomicInteger。addAndGet(length);}returnselectList。get(index);}}
  但实际中,每台服务器可能配置不同,我们需要为不同的服务器增加不同的权重,部分服务器需要大概率被选中,权重就设置大一些,否则就设置小一些。带权重的轮询俗称WRR算法。
  WRR目前有两种实现方式,一种是Nginx实现的平滑最大权重,dubbo也是参考这种模式。二是LVS实现的算法,其优先选择权重最大的服务器。
  NginxDubbo:不同权重的服务器,每次选择权重最大的,选中后,该权重会减去总权重,随后会加上其初始值。
  类似下面的过程:Incaseof{5,1,1}weightsthisgivesthefollowingsequenceofcurrentweights:abc000(initialstate)511(aselected)211322(aselected)422133(bselected)143634(aselected)134425(cselected)422911(aselected)211700(aselected)000
  看一下dubbo的实现:publicclassRoundRobinLoadBalanceextendsAbstractLoadBalance{publicstaticfinalStringNAMEroundrobin;OverrideprotectedTInvokerTdoSelect(ListInvokerTinvokers,URLurl,Invocationinvocation){Stringkeyinvokers。get(0)。getUrl()。getServiceKey()。invocation。getMethodName();ConcurrentMapString,WeightedRoundRobinmapmethodWeightMap。get(key);if(mapnull){methodWeightMap。putIfAbsent(key,newConcurrentHashMapString,WeightedRoundRobin());mapmethodWeightMap。get(key);}inttotalWeight0;longmaxCurrentLong。MINVALUE;longnowSystem。currentTimeMillis();InvokerTselectedInvokernull;WeightedRoundRobinselectedWRRnull;找出当前权重最大的,并计算总权重。for(InvokerTinvoker:invokers){StringidentifyStringinvoker。getUrl()。toIdentityString();WeightedRoundRobinweightedRoundRobinmap。get(identifyString);intweightgetWeight(invoker,invocation);longcurweightedRoundRobin。increaseCurrent();weightedRoundRobin。setLastUpdate(now);找出权重最大的if(curmaxCurrent){maxCurrentcur;selectedInvokerinvoker;selectedWRRweightedRoundRobin;}totalWeightweight;}}if(selectedInvoker!null){对于选中的,会对其权重进行抵减,值为totalWeight。selectedWRR。sel(totalWeight);returnselectedInvoker;}}}
  LVS的加权轮询每次都会选择权重最大的,的wiki说明:SupposingthatthereisaserversetS{S0,S1,,Sn1};W(Si)indicatestheweightofSi;iindicatestheserverselectedlasttime,andiisinitializedwith1;cwisthecurrentweightinscheduling,andcwisinitializedwithzero;max(S)isthemaximumweightofalltheserversinS;gcd(S)isthegreatestcommonpisorofallserverweightsinS;while(true){i(i1)modn;if(i0){cwcwgcd(S);if(cw0){cwmax(S);if(cw0)returnNULL;}}if(W(Si)cw)returnSi;}
  Python版的实现:classStore:slots(index,weight)definit(self,index,weight):self。indexindexself。weightweightdefweighted(dataset):currentStore(index1,weight0)datasetlengthlen(dataset)datasetmaxweight0datasetgcdweight0for,weightindataset:ifdatasetmaxweightweight:datasetmaxweightweightdatasetgcdweightgcd(datasetgcdweight,weight)defgetnext():whileTrue:current。index(current。index1)datasetlengthifcurrent。index0:current。weightcurrent。weightdatasetgcdweightifcurrent。weight0:current。weightdatasetmaxweightifcurrent。weight0:returnNoneifdataset〔current。index〕〔1〕current。weight:returndataset〔current。index〕〔0〕returngetnext
  3、最少连接数均衡(LeastConnection)
  思想:对每一台服务器都会记录当前正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器。如果有多台服务器都满足最小连接数,就变成随机算法。此种均衡算法适合长时间处理的请求服务。感兴趣的可以看下Dubbo的实现:LeastActiveLoadBalance。
  4、处理能力均衡
  思想:把服务请求分配当前系统负载最小的服务器,由于考虑到了内部服务器的处理能力及当前网络运行状况,所以此种均衡算法相对来说更加精确。
  5、目标地址散列:
  思想:根据请求的目标IP地址,作为散列键(HashKey)从散列表找出对应的服务器。
  6、源地址散列:
  思想:根据请求的源IP地址,作为散列键(HashKey)散列表找出对应的服务器。
  7、一致性Hash
  相比较普通hash算法,一致性hash算法在扩缩容时,影响的数据范围比较小,方便客户端做路由缓存。针对该算法,在之前写的文章小米分库分表的实践中有过介绍。在使用时为了避免数据倾斜,如果服务器数量较少的情况,要使用虚拟节点。Dubbo的实现方式是默认增加160个虚拟节点。并对每个ipport后增加数字1,2,3。。。。。。一致性Hash的存储结构最好的是使用红黑树TreeMap,因为其实现完美满足一致性hash算法。
  容错机制
  dubbo客户端通过watch注册中心的节点实现动态变化,此外支持不同方式的集群容错:
  1)failover
  失败自动切换,自动重试其他机器,常用于读操作。注意这里强调的是读请求,对于写请求,最好不要使用该模式。举例,如果某个接口是扣减金额接口,因为出现死锁或其他问题,导致接口超时了,此时会继续调用其他的服务器,这就导致接口被调用了两次或者多次。如果接口没有设计幂等(哪位大牛会不考虑幂等呢),那问题就比较严重了。
  (2)failfast
  快速失败,一次调用失败就立即失败,常用于非幂等的写操作或者是对时延要求较高的场景。
  (3)failsafe
  调用异常时忽略异常,不报错。该模式多用于一些不是特别重要的接口调用,比如邮件通知、数据统计等等。
  (4)failback
  失败后自动记录请求,然后定时重发,比较适合于一些异步操作,比如发送消息。
  (5)forking
  并行调用多个provider,只要一个成功就立即返回。常用于实时性要求比较高的读操作,但是会浪费更多的服务资源,可通过forks2来设置最大的并行数
  (6)broadcacst
  逐个调用所有的provider,任何一个provider出错则报错。常用于通知所有提供者更新缓存或日志等本地资源信息。
  健康检测
  对于负载均衡的服务器,应该具备某种健康检测机制,确保如果某个服务器异常下线,需要将其从负载均衡列表中摘除。健康检测可以是被动检测,也可以是主动检测。
  被动检测思想类似于熔断,当多次调用超时或者失败,会在一定时间内不再访问对应服务器。下面是参考资料中的一个示意图,阐述得比较清晰。
  被动检测的最大问题就是对于异常的机器不能及时摘除,导致仍然会有请求分发到异常机器上。因此
  如Dubbonacos实现的负载均衡,nacos通过和客户端和服务端建立连接,每几秒都会检测目标机器是否异常,如果异常会从当前注册列表中摘除。不过在实际使用中要注意,摘除异常并不是实时的,是定时发生的,也就是说存在客户端依然会调用异常Ip的可能。
  负载均衡分类
  目前负载均衡的实现有很多种,从TCPIP协议栈的角度划分,包括四层负载均衡、七层负载均衡。
  四层负载均衡:即在传输层实现的负载均衡,如LVS,Nginx都支持四层负载均衡。
  七层负载均衡:即在应用层实现的负载均衡,如HTTP协议、DNS协议等,HTTP协议实现的负载均衡如Nginx,Dubbo等。
  从软硬件角度可划分出DNS负载均衡、软件负载均衡、硬件负载均衡。
  硬件负载均衡需要购买专门的硬件产品实现,而且都很昂贵,基本上是淘汰的,过时的。
  软件负载均衡是通过软件来实现的,价格比较便宜,性能也比较优越。如nginx,lvs都是优秀的负载均衡软件。
  在实际应用中,通常情况会结合着使用不同的负载均衡技术。如下图所示:
  七层负载均衡:NginxHTTP协议DNSDNS协议DubboHTTP协议
  四层负载均衡:
  Nginx
  LVS
  Nginx负载均衡
  nginx支持七层和四层负载均衡两种,不过四层负载均衡需要第三方插件的支持。
  Nginx七层负载均衡的配置非常简单。upstreamaccountbackend{server127。0。0。1:9090maxfails3failtimeout10sweight2;server127。0。0。2:9090maxfails3failtimeout10s;server127。0。0。3:9090maxfails3failtimeout10s;}
  当请求过来时,会根据某种算法选择某一个ip进行访问。Nginx默认使用加权轮询,权重默认是1。此外,Nginx还内置了iphash算法,通过对客户端ip进行hash选择一个服务器,通过该方法可保证同一用户的可只打到一个后端机器上。upstreamaccountbackend{iphash;server127。0。0。1:9090maxfails3failtimeout10s;server127。0。0。2:9090maxfails3failtimeout10s;server127。0。0。3:9090maxfails3failtimeout10s;}
  当后端服务器集群中某个挂掉了,Nginx会自动将请求转到其他节点上。但是它默认不会将该异常节点摘除,后续的请求还是可能打到异常机器上的。至于这点,可以看这篇文章,该文章详细介绍了该如何进行后端健康检测的:Nginx负载均衡中后端节点服务器健康检查运维笔记散尽浮华博客园,主要介绍了淘宝团队开发的nginx继承模块,通过主动检测实现自动剔除异常的server。
  DNS负载均衡
  DNS负载均衡实现的是广域网的全局负载均衡,通过为域名配置不同的A记录,实现将请求按照权重分散到不同的ip。这里的ip并不一定是实际的服务器ip,可以是nginx集群,也可以是lvs的vip。
  下面是腾讯云DNSPod的一个实操:
  优点近乎零成本,因为域名注册商的这种解析都是免费的;部署方便,除了网络拓扑的简单扩增,加服务器只需要在配置里加上相应ip。
  缺点健康检查,如果某台服务器宕机,DNS服务器是无法知晓的,仍旧会将访问分配到此服务器。修改DNS记录全部生效时间需要很久。缓存问题。一般低级DNS都会缓存域名IP映射关系,如果某个出现问题或者发生变化,不会及时更新。
  不知道大家听说过2009年的暴风影音事件,因为两家游戏公司恶意竞争,一个公司恶意攻击另外一家公司网站,导致DnsPod服务器受到Ddos攻击,再加上当时著名的暴风影音使用了免费的DnsPod服务器,也受到了影响,那时的暴风今非昔比,用户量巨大,导致大量域名解析请求达到了电信的DNS服务器,占用了典型机房的13的带宽,于是乎,被电信封掉了ip。这一封不要紧,直接导致使用DnsPod解析的网站全部无法访问,数量达到10万。有感兴趣的可以看看历史回顾,很精彩,DnsPod创始人很厉害,叫吴洪声,作为一个大专生,靠着爱好和坚持搭建了DnsPod,现在已经被腾讯收购了,妥妥的人生赢家。
  LVS负载均衡
  四层负载均衡是针对七层负载均衡的一个补充,当Nginx的并发超过上线时,就需要通过LVSNginx集群实现高并发。
  主要模式主要有以下几种:LVSNAT主要通过网络地址转换,修改目的IP实现。NetworkAddressTranslationLVSTUN主要封装一层IP头IPTunnelingLVSDR主要是修改目的MACDirectRoutingLVSFULLNAT这个是阿里研发的一种模式,主要是解决多vlan的场景,它会修改请求报文的(源目的)地址、(源目的)端口。
  先看几个LVS的名词定义:CIP:客户端ip
  Director:负载调度集群的主机,简称DR
  VIP:VirtualIP,向外提供服务的IP
  RIP:RealServerIP,内部真正提供服务的IP
  DIP:DR主机用于内部通信的IP
  1、LVSNAT
  流程示意图:
  其请求处理流程:
  1。客户端发送请求到LVS,目标IP地址为VIP
  2。LVS根据某种负载均衡算法选择一个Realserver,并记录连接信息到hash表中,然后修改客户端的request的目的IP地址为选择的RS(这个RIP只是内部通信用的),随后将请求发给RS,此时源IP为CIP,目的IP为RIP;
  3。RS收到request包后,发现目的IP是自己的IP,于是处理请求,然后发送reply给LVS,此时源IP为RIP,目的IP是CIP;
  4。LVS收到reply包后,修改reply包的的源地址为VIP,原端口为VIP端口;
  5。LVS将reply发送给客户端;
  6。客户端来的属于本次连接的包,查hash表,然后发给对应的RS;
  7。客户端发送完毕,此次连接结束时,LVS自动从hash表中删除此条记录;
  上面流程的特点是:
  1、DR和RS必须是在同一个网段内,RS的网关配置成DIP,RIP和DIP都是用于内网机器间通信的IP。我感觉说的直白点,DR就是局域网网关的角色;
  2、所有请求响应都要经过DR,这必然会导致DR会成为整个网络的瓶颈。
  2、LVSTUN
  1。客户端Client发送request包到LVS服务器,目标地址VIP;
  2。LVS按照算法选择后端的一个Realserver,并将记录一条消息到hash表中,然后将客户端的request包封装到一个新的IP包里,新IP包的目的IP是RIP,源IP是DIP,然后转发给RS;
  3。RS收到包后,解封装,取出客户端的request包,发现还有一个IP包,目的地址是VIP,而RS发现在自己的虚拟网卡tunl0上有这个IP地址,于是处理客户端的请求,处理完成通过虚拟网卡发送给eth0网口发送出去,此时源IP为VIP,目的地址是CIP;
  4。该客户端的后面的request包,LVS直接按照hash表中的记录直接转发给Realserver,当传输完毕或者连接超时,那么将删除hash表中的记录。
  该模式中:
  RIP,VIP,DIP都可以是公网地址,可以跨网段;
  请求报文都走DR,响应不走,直接由RS发送给Client。这个特点使得TUN的性能要相比NAT提升了几倍,且解决了跨网段问题,问题就在于其维护成本挺高的;
  3、LVSDR
  1、客户端Client发送request包到LVS服务器,目标地址VIP;
  2、LVS根据负载均衡算法选择一台Realserver,将此RIP所在网卡的mac地址作为目标mac地址,发送到局域网里,因为是在数据链路层,所以必须在同一局域网;
  3、RS在局域网中收到这个帧,拆开后发现目标IP不是自己的IP,正常来讲RS会抛弃的,但由于我们在loopback接口上配置了VIP,所以RS会接收该请求包并进行处理。
  4、处理后,RS直接经过网络发送给客户端,源IP为VIP,目的IP为CIP。
  LVSDR技术解决了NAT的DR瓶颈问题,提高性能,但其最大限制就是DR和RIP必须是同一网段的,不能解决跨网段的问题。
  4、LVSFULLNAT
  这个是阿里做的,LVS的DR和NAT模式要求RS和DR在同一个vlan中,导致部署成本过高;TUN模式虽然可以跨vlan,但RealServer上需要部署ipip隧道模块等,网络拓扑上需要连通外网,较复杂,不易运维。
  为了解决上述问题,开发出FULLNAT,该模式和NAT模式的区别是:数据包进入时,除了做DNAT,还做SNAT(用户ip内网ip),从而实现LVSRealServer间可以跨vlan通讯,RealServer只需要连接到内网。
  当客户端访问VIP后,DR会将源IP改成DIP,目的IP改成RIP。剩下的就是内网调用的事情了,可以是同网段,也可以是不同网段,至于不同Vlan如何通信,这个就不多说了,就是路由策略配置的问题了。
  FULLNAT相对于之前那三种方式,配置维护都很简单,可以跨网段。现在也是LVS主流的使用模式。
  LVS本身的部署有以下几种模式:
  1、单机模式,一个LVS对应多个Nginxserver;
  2、一主一备KeepAlived,提高可用性;
  3、集群模式。通过FullNATOSPFECMP,并使用一致性hash算法实现分流。
  目前最多的就是集群部署方式,其特点为:LVS和上联的三层交换机间运行OSPF协议。OSPF开放最短路径优先,是一种常用的路由协议。上联交换机通过ECMP等价路由,将数据流分发给LVS集群。ECMP充分应用在各大路由协议中,如OSPF,ISIS、EIGRP、BGP等。它可保证如果存在多条相等路径,会充分利用多条路由,从而实现基于流的负载均衡(如果不开ECMP,那么当选择一条路由后,或许都会一直使用该路由,其他相等路径都不会走)。LVS集群再转发给业务服务器。
  目前我们公司的所有服务几乎都用了LVS。即便时我开发的结算系统,虽然是ToB和内部财务使用,也同样用了LVS,用了两台RealServer,1台DIP,利用权重轮询。不过现在还把一台给停了,另外一台权重配置成100了,哈哈。
  有状态的需要存储数据的主从集群
  有些服务器为了实现高可用性,会冗余部署多台服务器,并设置主从关系。可以是一主多从,也可以是多主多从。对于这种类型的集群部署,重要的是完成数据的复制以及当主服务器down时,可以实现自动或者手动切换,某台slave可以自动切换成主服务器。其中最典型的例子就是Mysql主从以及Redis中的主从部署,本文主要是介绍这两种。
  Mysql高可用架构
  Mysql的高可用架构有很多中,有一主一从,一主多从,双主KeepAlive等。其中最常用的就是一主多从。通过水平扩展的方式可以实现Mysql数据库的高可用,同时实现流量分摊,并能够在某台master异常时,能够通过一定手段完成切换。
  引入集群的部署模式后,在带来高可用、高性能的同时也引入了新问题,比如如何保证主从数据库的数据一致性、如何解决主从延迟、如何完成流量的切换等问题。
  数据需要从主库同步到从数据库,从而保证数据的一致性,并通过不同的复制模式来实现强一致性、弱一致性、最终一致性等。先看一下Mysql主从复制的流程:主库将数据更改记录到binlog中;从库开启一个IO线程,并在主库开启一个特殊的binlogdump线程,将binlog数据拷贝到从库的relaylog中;从库并不是不断轮询去做同步操作。而是当主库有数据更改时,会给主库发送一个信号量。主库返回的信息不仅仅有binlog内容,还有新的binlog文件名,它以及下一个更新的binlog文件的位置。从库使用SQL线程读取relaylog中的数据,并将其写入到从库数据表。
  可以看一下slave的processlist:ysqlshowprocesslistG;1。rowId:4User:systemuserHost:db:NULLCommand:ConnectTime:5205State:WaitingformastertosendeventInfo:NULL2。rowId:5User:systemuserHost:db:NULLCommand:ConnectTime:5113State:Slavehasreadallrelaylog;waitingformoreupdatesInfo:NULL3。row
  上面就是从库的两个线程,一个IO线程,一个SQL线程。实际上在Mysql5。6之后,SQL线程不仅仅只有一个,可以是多SQL线程并发执行。
  传统的复制是根据文件位置开始进行的,但自从5。6之后引入了一个叫GTID的概念。GTID,globaltransactionidentifieds全局事务标识。这个标识是唯一的,它可保证一个事务只能被执行一次。
  在主从复制过程中,Master在更新数据时会生成一个GTID,并写在binlog中。从库的SQL线程在执行中继日志的过程中,会检查从库的binlog是否已经有了某个GTID记录,如果有就略过,如果没有就执行。
  我们可以查看当前Mysql是否已经开启了GTID。mysqlshowvariableslikegtidmode;VariablenameValuegtidmodeON
  Mysq复制方式主要包括异步复制、同步复制和半同步复制。
  异步复制:当master执行了相应的写操作,执行成功后直接返回客户端。随后异步得将数据同步到slave。这种好处就是在完成复制的同时,不会牺牲系统的响应速率,但最大的问题就是不能保证数据一致性;
  同步复制:当master在执行写操作时,必须要等到所有slave库的relaylog写完,才能够返回给客户端。该模式可以较好低保证数据一致性,但却严重影响系统性能,从库越多,性能越差;
  半同步复制:该复制模式是异步方式和同步复制的折中方案,只要slave中有一个成功写入relaylog,master就可直接返回,如果在一定时间内,没有slave写入成功,则复制模式变为异步复制。
  Mysql默认是采用异步复制的,可能其更看重的是系统性能,系统崩溃的概率还是比较低的,在实际中,我们可以根据自身使用场景来选择复制模式。
  binlog模式
  目前binlog的记录模式主要有三种,基于语句(statment),基于行(Row)模式,混合(mixed)模式。
  基于语句的模式就是binlog记录的是所有可能影响数据变化的sql语句。然后在从库中再完全相同地执行一遍。这种模式比较好的地方是只记录语句,不用记录每一行的变化,数据量相对不大,节省带宽。比如一条批量update,只需要传一条语句,不用传每个更改的数据。但这种模式的缺点就是虽然主从库执行的sql完全相同。但主从库的上下文环境是不同的,而sql可能是严格依赖于环境的,比如当前时间戳等等。
  基于行的模式,是记录被修改的数据,而不是sql语句。这种模式使得从库并不会因为环境不同,导致数据不能完全一致。但基于行的模式,可能会导致binlog的数据量特别大,就像上面说到的update,可能会在binlog产生更多的数据记录。这给复制造成了更大的开销。
  mix模式,该模式是上述两种模式的组合。Mysql会根据实际的sql来决定选择哪个模式进行写入。
  RedisCluster
  Redis的系统架构经过了多次的演进,最开始的架构模式是一主多从,但由于其无法实现故障自动切换,随后增加了sentinel哨兵机制,即在主从的基础上增加一个哨兵进行监控,从而实现master出现故障时可自动切换。
  从上面示意图可以看出,哨兵机制需要额外的机器节点来实现,完全和Redis无关,不存储数据,只用来监控,这在一定程度上造成了资源的浪费。基于此,Redis官方又开发出一套新的Redis架构,即RedisCluster,一个纯分布式的系统架构,示意图在文章最开始已经画出来了,这里再粘贴一下。
  多个master节点通过Gossip协议实现元信息的交互和通信,实现命令包括Meet,Ping,Pong,Fail等,本文对此不做过多阐述,只讲述每个master节点和其slave所构成的集群模式。
  RedisCluster的masterslave主要有以下几个作用:
  1、保持高可用;
  当某个master节点下线时,会自动切换到某个slave,slave会升级为新的master,从而实现故障的自动切换。具体流程是:
  1、通过Ping消息,master节点在一定的超时时间内没有响应,就被标记为疑似下线,如果有多个节点认为该master节点疑似下线,那么该master就标记为下线。
  2、master下的slave发起选举,其他的master节点会为相应的slave进行投票,根据Raft协议,选择出新的master节点;
  这里要注意两点。一是slave发起选举,二是master投票。
  Slave在认为master进入FAIL之后会delay一段时间才会发起选举,其原因是为了让master的FAIL状态在集群内广播。不同的slave的delay时间是不同的,从而避免一个master的多个slave在同一时间发起election。
  master投票的条件:Slave所属的master的状态为FAILSlave的currentEpoch大于等于master的currentEpochSlave的configEpoch大于等于master认为该slave所属master的configEpochMaster维护一个lastVoteEpoch字段,针对每一个epoch只会投票一次,一旦投票后就会拒绝所有更小的epoch投票就会回复ACK,否则就忽略
  3、slave选举为新的master节点后,会被分配旧master的哈希槽。
  2、实现读写分离;
  RedisCluster中的master节点对外提供写服务,slave可以对外提供读服务。
  如果要实现高可用和读写分离,前提是要实现主从复制,即保证主从节点的数据的一致性。Redis的主从复制主要包括两种全量复制和部分复制。其中全量复制通常发生在第一次同步过程或者在部分复制出现异常时。
  当在slave中使用slaveOf(Redi5。0之后使用replicaof),确定slave和master的关系。slaveofipport
  具体复制流程可见下图,来自小林coding:
  1、执行slaveof之后,主从服务器会建立一个长连接。随后从服务器向主服务器发送psync命令(早期版本是syncc),psync命令有两个参数,一个是runid,表示的是主服务器id;一个是offset,表示的是偏移量。第一次执行时,从服务器不知道主服务器的runId,所以参数是?,且没有读取任何数据,偏移量是1;
  2、主服务器收到命令后,会开始执行全量复制。首先会执行bgsave命令,生成RDB文件,随后将其发送给从服务器,slave收到RDB文件之后,会载入RDB文件数据。
  3、在上一步执行期间,有可能还会有写命令进入,而这些写命令执行结果并没有在RDB文件中,因此主服务器为了处理这部分数据,在执行间隙会将写命令写入到一个叫做replicationbuffer缓冲区中。当slave加载完RDB文件之后,主服务器会将缓冲区中的写命令发送给slave,随后slave继续执行这些写命令;
  4、完成第一次全量同步之后,后续只要主服务器有写命令产生,就会将写命令异步地同步给从服务器。
  5、如果某个slave网络断开之后恢复了。从服务器会给master发送psync命令,其中会传入主服务器的runid以及读偏移量。
  6、主服务器会判断从服务器要读取的偏移量数据是否在replbacklogbuffer中,如果在就执行增量复制;如果不在,则执行全量复制。
  本文主要讲述了两种不同的集群模式,一是无状态的集群;二是有状态,需做数据存储的集群两种。无状态集群介绍了负载均衡分类以及负载均衡算法;有状态集群介绍了主从复制的原理和流程。
  参考资料:
  深入浅出负载均衡SegmentFault思否
  〔万字长文〕吃透负载均衡高性能架构探索
  Dubbo一致性Hash负载均衡实现剖析ApacheDubboDUBBOLOGO
  Nginx负载均衡(仅学习)知乎
  千与千寻Mysql复制
  详解nginx的原生被动健康检查机制灾备使用(含测试)无影V随风的博客CSDN博客被动健康检查
  高并发场景LVS安装及高可用实现惨绿少年博客园
  Redis哨兵模式(sentinel)学习总结及部署记录(主从复制、读写分离、主从切换)散尽浮华博客园
  主从复制是怎么实现的?小林coding
  深度探索MySQL主从复制原理知乎

天冷贴膘,猪肉鸡肉靠边站,3种牛肉做法,不卤不炖几分钟上桌大家好,我是阿飞,天冷贴膘,猪肉鸡肉都不如牛肉。牛肉含有丰富的蛋白质,氨基酸组成比猪肉更接近人体需要,能提高机体抗病能力,增强免疫力,促进人体新陈代谢。今咱就分享几道好吃……为什么安卓都用曲面屏好几年了,苹果却还是坚持不用呢?文北桥校对北桥提起曲面屏这项技术,最开始还是2015年发布的三星S6Edge用上的,但是由于曲面屏初期的成本太高,并且那时候只有三星才拥有曲面屏的技术,因此曲面屏发展初期……热血传奇当年老玩家都不一定见过,什么戒指竟然价值20万天价哈喽大家好啊,玩过传奇的老玩家都知道啊,传奇这款游戏装备一直是玩家的梦想,但是由于缺少高级装备,每一款的价格都很高。这款游戏中的一些高级装备甚至可以卖出几十万的高价,尽管如此还……电视剧雪中悍刀行十大帅气男演员都有谁呢?现在俩看看吧随着电视剧《雪中悍刀行》的热播,在电视剧中不少演员又在互联网上有了一定的热度,特别是那些长相帅气的男演员更是备受瞩目,现在我们就看看这些男演员吧,看看你们喜欢谁的表现呢?……NBA季后赛没工资,为何球员还那么努力?普尔励志经历说明了一NBA季后赛火热进行中,16支季后赛球队都在不断努力,争取晋级下一轮系列赛。不过,有个问题很有意思,NBA季后赛没工资,为何球员还那么努力呢?其实,当球队进入季后赛之后,球员们……傲世龙城热血龙皇宫廷秘药怎么获得永恒屠龙一战称王宫廷秘药用法哈喽,大家好呀,我是爱玩游戏的软软呀,欢迎来到【爱玩游戏的软软】。今天来给小伙伴们讲讲三职业传奇手游傲世龙城的相关攻略吧。在传奇游戏中,回复血量可是很重要的,我们一起来看看宫廷……40岁谢娜浪姐3高调复出,含泪说出心里话感谢你们找我来当乘风发布人,我很感谢,你们没有觉得我生了孩子,状态会不好。在节目组和姐姐们在浪姐3的舞台上为谢娜庆生的时候,谢娜含泪说出了她的心里话。能明显感觉到,……2022毕业季易烊千玺与罗大佑隔空对话,并献唱毕业歌光阴的故2022毕业季来了,这个毕业季不简单。罗大佑制作,易烊千玺献唱《光阴的故事》。在演唱之前,这对隔了好几代的音乐人,对空交流,进行思想碰撞。易烊千玺:您毕业之后……华为新专利确定,两台手机可屏幕共享,有望从根本上改变体验作为全球知名的科技公司,华为在专利方面的申请还是非常积极的,在2021年华为曾经向EPO申请了3544项专利,排在专利申请数量企业的第一名。虽然华为的芯片生产受到了限制,但是在……LPL赛区迎来文艺复兴,冷门英雄频频出现,你最期待哪个?在最近的夏季赛比赛中,随着上单狗头的出现,LPL赛区正式迎来了文艺复兴,不仅是狗头上单,乌鸦中单还有天使上单的阵容也出现在了比赛中,不仅如此,上单猪女,辅助巴德这样的阵容也再次……6。23日大批活动上线,史诗皮免费拿,玲珑夺宝,碎片商店更新大家好我是指尖,s28赛季终于上线,本文来跟大家汇总一下新赛季会上线的福利活动,一起来看看吧。张良电竞皮肤这款皮肤26日即可在双平台提前购买,正式上线是在29日,买……美媒确定了,华为破冰了文C君科讯排版C君科讯头条号原创文章,禁止抄袭,违者必究从2019年开始,制约华为发展的主要有两个方面,其一就是,谷歌停止了GMS服务,并且对华为按下了安卓暂停更新……
52岁钟丽缇再传婚变!起因是50万的裙子,张伦硕气炸不怕犯法作为圈内姐弟恋的代表之一,52岁的钟丽缇和40岁的张伦硕之间的婚姻,一直受到外界的关注。虽然时有唱衰的声音传出,但夫妻俩还是经常大方秀恩爱,无惧流言。不过,这次一则……来了!辽宁再签一人,四川引进NBA榜眼秀,前广东冠军外援退役距离CBA新赛季开始越来越近了,各支球队也是在紧锣密鼓的准备着,希望能在新赛季打出一个好成绩!而在这个节骨眼上,CBA多支球队也是传来消息!辽宁再签一人,四川队得到NBA09年……看似毫无关系却做过队友的五对球员姚明和泰伦卢,麦迪和尤因NBA是一门生意,球员是流通的,除了超级巨星以外,其他球员根本没有选择和谁做队友的权利,他们可能被裁掉,也可以被当成筹码交易掉,这让一些看似毫无关系的球员产生交集,比如以下这五……从连亏20年到世界零售老大的贝佐斯什么才是长期主义?1。长期主义者,亚马逊的创始人贝佐斯绝对算一个。自公司1995年成立,1997年上市,一直亏。不,是坚持亏!2。股东的脸,由白变绿,由绿变蓝。而贝佐斯装没看见,始终坚持推……星链网络向全球开放,马斯克却偏偏拉黑中国一、简述马斯克在担任SpaceX的CEO之后,星链计划正式启动,至今已经成功发射了3108颗卫星进入太空轨道。近日马斯克在社交平台上宣称:星链网络将面向全球所有国家开放使……艰难抉择,华为mate40Pro和华为mate50Pro,认自从华为mate50系列发布之后,这款手机就应该是整个手机市场最火爆的手机了,但是有不少人都开始产生了一个矛盾,华为mate50Pro和华为mate40Pro该怎么选择?按理来……杨玉林府谷老家的院子老家的院子文杨玉林人老了,容易想家,特别容易想自己的老家。老家在哪里?老家是一个人血脉传承、精神寄托、魂牵梦绕、终生难忘的地方。我当兵后迁居了四个地方,搬过四……俄罗斯的猛犸象牙到底还能挖多久?猛犸象也叫长毛象,身上披有厚厚的长毛,皮下脂肪层的厚度更是达到了9厘米,这让它们拥有了很强的耐寒能力。通过化石得知,最大的猛犸象高达5。5米,体重约为15吨。猛犸象是在1……说说你心目中欧洲足坛现役最佳11人欧洲各国联赛和欧冠都打了一段时间了,从联赛和欧冠的表现来看,目前英超的曼城、西甲的皇家马德里、法甲的巴黎圣日耳曼、应该是状态最火热的球队。如果要选一套欧洲目前最佳阵容,你……尿素期货月报供需边际转好关注出口政策变化提示:因整体篇幅过长,此文只包含摘要部分,获取全部月报请私。7月尿素现货市场补跌,基差从前期高位回落至长期均衡区间。在现货价格跌至尿素煤制成本附近,供给快速调整,供需边际……湖人欢迎贝弗利,一天12消息,哈登生日快乐,莱昂纳德参加对抗感谢各位继续关注《NBA长草期》,和我一起了解NBA球星与球队最新动态。瓦妮莎获得1600万赔偿款,她随即将这笔钱全捐了,湖人与爵士官方宣布欢迎新援,哈登33岁生日依然在努力训……奢华级最美大三针正装表评比〔腕表之家钟表文化〕作为腕表最基础的一种风格,大三针简约且实用。它摒弃各种繁复的功能,回归钟表记录时间的本源,而这种简约典雅的设计也很好的契合了正装表所需。因此大三针正装表长期……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网