2.深入分布式缓存:从原理到实践 --- 分布式系统理论

1.分布式系统概论
	单就应用层次就涉及 分布式缓存,分布式存储,分布式文件系统,分布式锁,分布式事务,分布式调度任务,分布式调度计算,分布式消息,分布式采集等。

2.分布式系统概念
	1.进程与线程
		进程是具有一定独立功能的程序关于某个数据集合的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。线程是进程的一个实体,是cpu
	  调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,
	  一组寄存器和栈),但是它可与同一个进程的其他线程共享进程所拥有的全部资源。

	2.并发

	3.锁
		锁是用于保持临界区的一种机制。
		避免或规避锁争用的几种策略:
			1.分拆锁
			2.分离锁
			3.避免共享变量缓存
			4.使用并发容器如Amino
			5.使用Immutable数据和ThreadLocal中的数据
		如果一个锁守护多个相互独立的状态变量,你可能能够通过分拆锁,使每一个锁守护不同的变量,从而改进可伸缩性。通过这样的改变,使每一个锁被请求的
	  概率都变小了。分拆锁对于中等竞争强度的锁,能够有效把它们大部分转化为非竞争的锁,使性能和可伸缩性都得到提高。分拆锁有时候可以被扩展,分成若干
	  锁块的集合,并且它们归属于互相独立的对象,这样的情况就是分离锁。

	4.并行
		当系统有一个以上的cpu时,则线程的操作有可能非并发。当一个cpu执行一个线程,另一个cpu执行另外一个线程,两个线程互补抢占cpu资源,可以同时进行。
	  这种方式我们称之为并行。
	    和并发的区别:并发和并行即使相似又有区别的概念,并行是指两个或者多个时间在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。

	5.集群
		集群是一组互相独立的,通过高速网络互连的计算机,它们构成了一个组,并以单一系统的模式加以管理。

	6.状态特性
		在大部分应用中都提倡服务无状态,分布式环境中的任何节点也是无状态的.无状态是指不保存存储状态,可以随意重启和替代,便于做扩展。
		对于缓存失效/缓存服务器不可用解决方案:如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间
	  比较短,最长不超过5分钟。大多数系统设计者考虑用加锁或队列的方式保证缓存的单线程(单进程)写,从而避免失效时大量的并发请求落到底层存储上。

	7.系统重发与幂等性
		幂等性就是调用1次和调用N次要返回一样的结果。

	8.硬件异常
		1.服务器宕机
		2.网络异常
		3.磁盘故障
		4.机房级异常

3.分布式系统理论
	CAP理论提出了一致性,可用性,分区容错性的取舍问题。Paxos,Raft,2PC,3PC分别给出了一致性的解决方案;Lease 机制主要针对网络拥塞或瞬断的情况下,出现
  双主情况的解法;Quorum NWR 和 MVCC 主要解决分布式存储领域的一致性问题;Gossip 是一种去中心化,容错而又最终一致性的算法。

	1.CAP 理论
		1.一致性
		2.可用性
		3.分区容错

		高可用,数据一致是很多系统的设计目标,但是分区又是不可避免的事情,由此引出几种选择:
		1.CA without P
			如果不要求P(不允许分区),则C和A是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。
		  典型放弃分区容忍的例子有关系型数据库,LDAP等。
		2.CP without A
			如果不要求A(可用性),相当于每个请求都需要在Server之间强一致,而P会导致同步时间无限长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于
		  这种模式,分布式锁也属于此种情况。
		3.AP without C
			要求高可用并允许分区,则需要放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据
		  不一致。现在的众多NoSQL都属于这一类。

		该理论由 brewer 提出,Lynch和其他人证明。但是,她只是证明了 CAP 三者不能同时满足,并没有证明任意二者都可满足。采用的是反证法,如果三者都满足,则
	  因为允许P的存在,一定存在Server之间丢包,如此不能保证C。
	    Lynch 对CAP 的定义:
	    C : 一致性被称为原子对象,任何的读写都应该看起来是'原子'的,或串行的。写后面的读一定能读到前面写的内容。所有的读写请求都好像被全局排序。 
	    A : 对任何非失败节点都应该在有限时间内给出请求的回应。(请求的可终止性)
	    P : 允许节点之间丢失任意多的消息,当网络分区发生时,节点之间的消息可能会完全丢失。

	2.CAP 理论澄清
		1.'三选二'是一个伪命题 : https://www.cnblogs.com/shanyou/archive/2012/06/11/2545536.html
			不是为了P,要在A和C之间选择一个。分区很少出现,CAP在大多数时候允许完美的C和A。但当分区存在或可感知其影响的情况下,就要预备一种策略去探知分区并
		  显式处理其影响。这样的策略应分为3个步骤:探知分区发生,进入显式的分区模式以限制某些操作,启动恢复过程以恢复数据一致性并补偿分区期间发生的错误。
		    ’一致性的作用范围‘ 其实反映了这样一种观念,即在一定的边界内状态是一致的,但超出了边界就无从谈起。比如在一个主分区内可以保证完备的一致性和可用性,
		  而在分区外服务是不可用的。Paxos算法和原子性多播系统一般符合这样的场景。像Google的一般做法是将主分区归属在单个数据中心里面,然后交给Paxos算法去
		  解决跨分区的问题,一方面保证全局协商一致如Chubby,一方面实现高可用的持久性存储如Megastore。

		最终一致性:
			1.给定足够长的一段时间,不再发送更新,则认为所有更新最终会传播到整个系统,且所有的副本都会达到一致。
			2.当存在持续更新,一个被接受的更新要么达到副本,要么在到达副本的路上。

	3.Paxos
		1.Paxos 是什么
		Paxos 协议是一个解决分布式系统中,多个节点之间就某个值(提案)达成一致(决议)的通信协议。它能够处理在少数节点离线的情况下,剩余的多数节点仍然能够
	  达成一致。

	  	2.Paxos 协议简介
	  		Paxos 是一个两阶段协议,分为Prepare阶段和 Accept 阶段。该协议涉及两个参与者角色:Proposer 和 Acceptor。Proposer 是提议提案的服务器,
	  	  而 Acceptor 是批准提案的服务器。两者在物理上可以是同一台服务器。

	  	  Prepare 阶段
	  	  	1.Prepare 阶段1:Proposer 发送 Prepare
	  	  		Proposer 生成全局唯一且递增的提案ID,向Paxos集群的所有机器发送请求,这里无需携带提案内容,只携带提案ID即可。
	  	  	2.Prepare 阶段2:Acceptor 应答 Prepare
	  	  		Acceptor收到提案请求后,做出以下约定:
	  	  			1.不再应答<=Pn 的Prepare请求
	  	  			2.对于 <Pn 的Accept 请求亦不处理。
	  	  		Acceptor做的处理包括:
	  	  			1.应答之前要在本地持久化当前提案ID
	  	  			2.如果现在的请求ID --- Pn 大于之前存放的 ProposalID,则做以下逻辑:
	  	  				if Pn > proposalID then proposalID = Pn
	  	  			如果该 Acceptor Accept 过的提案,则返回提案中 proposalID 最大的那个提案的内容,否则返回空值。
	  	 
	  	  Accept 阶段
	  	  	1.Proposal 发送 Accept
	  	  		Proposer 收集到多数派应答(这里的多数派,就是超过 n/2 + 1)Prepare阶段的返回值,从中选择 proposalID 最大的提案内容,作为要发起Accept
	  	  	  的提案,如果整个提案为空,则可以自己随意决定提案内容。然后携带上 proposalID,向 Paxos 集群的所有机器发送Accept请求。

	  	  	2.Acceptor 发送 Accept
	  	  		Acceptor收到Accept请求后,检查不违背自己之前作出约定的情况下,持久化当前Proposal ID 和提案内容。最后Proposer收集到多数派应答Accept
	  	  	  回复后,形成决议。

	4.2PC	
		包括2个阶段:
			1.提交请求阶段或者投票阶段
				该阶段的任务是确定相关参与者对事务处理是否准备就绪。
			2.提交阶段
				基于投票结果,由协调器决定提交事务或退出事务处理;各事务参与者遵守指示,对本地事务资源做出需要的动作。
		2PC 最大的不足是提交协议是阻塞性协议。

	5.3PC
		1.canCommit
		2.preCommit
		3.doCommit

		3PC 是在 2PC 的基础上增加了一次交互,也就是 preCommit(又称预提交)。只要预提交都成功,则一定要保证 doCommit 提交成功,即使协调器下一阶段不可用,
	  或者调用超时。这是协议的基本思想,在工业环境中,一般是通过重试补偿的策略来保证 doCommit 提交成功的。

	6.Raft
		Raft 提供了和Paxos 算法相同的功能和特性,但是它的算法结构和Paxos不同。Raft算法更加容易理解并且更容易构建实际的系统。为了提升可理解性,Raft将一致性
	  算法分解成了几个关键性模块,如领导人选举,日志复制和安全性。同时它通过实施一个更强的一致性来减少需要考虑的状态的数量。Raft算法还包括一个新的机制来允许
	  集群成员的动态改变,它利用重叠的大多数来保证安全性。
	    Paxos 和 Raft 都是为了实现一致性这个目标,这个过程如同选举一样,参选者需要说服大多数选民(服务器)投票给他,一旦选定后就跟随其操作。Paxos和 Raft的区别
	  在于选举的具体过程不同。
	    在Raft中,任何时候一个服务器可以扮演如下角色:
	    1.领导者:处理所有客户端交互,日志复制等动作,一般一次只有一个领导者
	    2.选民:类似选民,完全被动的角色,这样的服务器等待被通知投票
	    3.候选人:候选人就是在选举过程中提名自己的实体,一旦选举成功,则称为领导者。

	    Raft 算法分为2个阶段,首先是选举过程,然后在选举出来的领导人带领进行正常操作,比如日志复制等。过程如下:
	    1.任何一个服务器都可以成为一个候选者,它向其他服务器(选民)发出要求选举自己的请求
	    2.如果其他服务器统一了,回复OK指令。如果此时有一个Follower服务器宕机,没有收到请求选举的要求,则只要达到半数以上的选票,候选人还是可以成为领导者的。
	    3.这样,这个候选人就成为领导者,它可以向选民们发出要执行具体操作动作的指令,比如进行日志复制等。
	    4.如果一旦这个leader宕机崩溃了,那么Follower中会有一个成为候选者,发出邀票选举,相当于再执行1,2步骤。
	    总结:1,2是选举过程,3是具体协同执行指令操作的过程。

	7.Lease 机制
		Lease 英文含义是 '租期','承若'。在分布式环境中,此机制描述为:Lease 是由授权者授予分布式环境一段时间内的承若。

	8.解决'脑裂'问题
		脑裂,指在一个高可用系统中,当联系着的两个节点断开联系时,本来作为一个整体的系统,分裂为两个独立的节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,
	  数据损坏。
	    心跳检测的不确定性是发生脑裂问题的一个非常重要的原因。
	    如何解决这个问题?有一种做法Wie设置仲裁机制,如设置第三方检测服务器(Monitor),当slave确定接管Master时,让Monitor也ping一下master,如果没有通讯,则
	  判断其'死亡';同时master在对外提供服务时,每隔一段时间比如10s 由master服务器ping slave 服务器和 Monitor,如果均出现异常,则暂停业务操作,重试。重试
	  多次后则退出程序执行或者执行服务器重启操作。
	    当然,这里有新的问题,比如Monitor的高可用保障。
	    通过Lease机制也可以进一步处理双主脑裂问题。我们假设slave已经在提高服务,对应的server服务器则获得slave颁发的Lease。假设老的master仍然提高服务,则Lease
	  必然是过期的,因此请求失败,老master请求频繁失败的情况下,可以通过配置监控点触发报警,以人工介入让老Master放弃身份,转为slave。

	9.Quorum NWR
		NWR 是一种在分布式存储系统中用于控制一致性级别的一种策略。三个字母的含义:
		1.N : 同一份数据的拷贝份数
		2.W : 是更新一个数据对象的时候需要确保成功更新的份数
		3.R : 读取一个数据需要读取的拷贝的份数
		具体策略通过2个公式计算:
			W > N/2
			W + R > N
		N 至少要达到3,大于3则付出更高的成本。小于3无法保证高可用。一般采取 N=3,R=2,W=2的配置。W=2,可以保证大多数写成功,而R=2,则能保障读到大多数一致的最新版本。
	  由于不同节点都在提高W和R,而W未必等于N,则一定存在数据不一致的情况。

	10.MVCC
		MVCC 多版本并发控制。人们一般把基于锁的并发控制称为悲观机制,而把MVCC机制称为乐观机制。由于MVCC是一种宽松的设计,读写互补阻塞,可以获得较高的并发性能。
		不同数据库对于mvcc的具体实现有差异。mysql的 InnoDB 是这样做的:
		1.引擎给每张表都增加2个字段,分别叫做 create version 和 delete version
		2.插入操作时:记录的创建版本号就是事务版本号
		3.更新操作时:采用的是先标记旧的哪行记录为已删除,并且删除版本号是事务版本号,然后插入一行新记录的方式
		4.删除操作时:就把事务版本号作为删除版本号
		那么当我们做查询操作的时候,要符合下面2个条件的记录才能被事务查询出来:
		1.delete version > 当前版本号,就是说删除操作是在当前事务启动之后做的
		2.create version <= 当前事务版本号

	11.Gossip
		对于分布式系统而言,由于状态分散在集群中的各个节点上,集群的状态同步面临着集中式系统所不具备的问题:
		1.其中的每一个节点如何较快的得知集群状态全集的某些特征
		2.如何避免多个节点就某个状态发生分歧,使得集群的状态实时或最终一致
		分布式系统中的各个节点通过一定的交互方式(分布式协议)解决上述问题。
		Gossip 就是一种去中心化思路的分布式协议,解决状态在集群中的传播和状态一致性的保证2个问题。因为其实现比较简单,具有较高的容错性和性能,成为分布式系统最广泛使用
	  的状态同步协议之一。
	    1.状态的传播
	    	以 Gossip 协议同步状态的思路类似于流言的传播。
	    	A节点率先知道了某个流言(msg),它首先将此信息传播到集群中的部分节点(比如相连的两个节点)B和C,后者再将其传递到它们所选择的'部分'节点,例如B选择了D和E,C选择了
	      B和F。以此类推,最终来自A的这条流言在3轮交互后别传播到了集群中的所有节点。
	        在分布式的实践中,这个'流言'可能是:某个节点感知到的关于其他节点是否宕机的认识;也可能是数据水平拆分的缓存集群中,关于哪些hash桶分布在哪些节点上的信息。每个
	      节点期初只掌握部分状态信息,不断的从其他节点收到Gossip信息,每个节点逐渐掌握到了整个集群的状态信息。因此解决了状态同步的第一个问题:全集状态的获取。

	    2.状态的一致
	    	状态同步的第二个问题:对于同一个状态信息,不同的节点可能掌握的值不同,也能通过Gossip通信思路构建的协议包版本得到解决。比如水平拆分的redis缓存集群,初始状态下
	      hash桶在各个节点的分布。
	        D分担了C的某个hash 桶,此时C/D和集群中的其他节点就C所拥有哪些hash这件事发生了分歧:A/B 认为C目前有6/7/8 3个桶。此时通过Gossip消息体引入版本号,使得关于C
	      的最新状态消息(只有6/7 2个桶)在全集群达到了一致。例如,B收到来自A和C的Gossip消息时会将版本号更新的消息(来自C的V2)更新到自己的本地副本。

	        各个节点的本地副本保存的集群全量状态也可能是用来表示各个节点的存活状态。
	        例如A和C的网络断开,但A和C本身都正常运行,此时A和C互相无法通信,C会将A标记为不可用状态。对于中心化思路的协议,如果C恰好是中心节点,那么A不可用的信息将会
	      同步到集群的所有节点上,使得这些节点将其实可用的A也标记为宕机。而基于Gossip这类去中心化的协议进行接收到消息后的实现逻辑扩展(例如只有当接收到大多数的节点关于
	      A已经宕机的消息时,才更新A的状态),最终保证A不被误认为宕机。

	    3.特性总结
	    	Gossip的核心是在去中心化的结构下,通信消息的部分传递,达到全集群的状态消息传播,传播的时间收敛在 O(Log(N))以内,其中N是节点的数量。同时基于Gossip协议,
	      可以构建出状态一致的各种解决方案。

4.分布式系统设计策略
	分布式系统本质是通过低廉的硬件攒在一起以获得更好的吞吐量,性能以及可用性等。一台设备坏了,可以通过负载均衡和路由到其他设备上。分布式系统有一些通用的设计策略,首先
  要解决心跳问题。一台服务器判断存活状态,才能执行任务,否则不能。在分布式环境下,有几个问题需要关心,我们称之为设计策略:
  		如何检测你还活着
  		如何保证高可用
  		容错处理
  		重试机制
  		负载均衡

	1.心跳检测
		如何判断某个节点无法工作?传统的方法是用心跳检测。
		当server 没有收到节点3发送的心跳时,server认为node3失联。失联代表并不确定是否node3故障,有可能是node3处于繁忙状态,导致调用检测超时;也有可能是server与
	  节点c之间的链路出现故障或者闪断。所以心跳不是万能的,收到心跳可以确定节点正常,但是收不到心跳却不能确认该节点已经宣告'死亡'。
	    没有返回不代表宕机,有一些具体的做法来帮助我们做决定,一般分为2类:周期性的心跳检测机制,累计失效检测机制。
	    server 每隔t秒向node集群发起监测请求,设定超时时间,如果超过超时时间,则判断'死亡'。这里的超时时间设置带有随意性,容易误判。进一步,可以统计实际检测node的
	  返回时间,包括得到一定周期内的最长时间。那么可以根据现有没有正确返回的时间在历史统计的分布中计算得到'死亡'的概率,同时对于宣告濒临死亡的节点可以发起有限次数的
	  重试,以进一步判断。心跳检测本身也是有效资源利用和成本之间的一种权衡,如果迟迟不能判断节点是否'死亡',会影响业务逻辑的处理。通过周期性检测心跳机制,累计失效
	  检测机制可以帮助判断节点是否'死亡',如果判断'死亡',可以把节点踢出集群。

	2.高可用设计
		系统高可用性的常用设计模式包括3种:主备(master-slave),互备(active-active)和集群(cluster)。

		1.主备模式
			主备模式就是 active-standby 模式,当主机宕机时,备机接管主机的一切工作,待主机恢复正常后,按使用者的设定以自动(热备)或手动(冷备)方式将服务器切换到主机
		  上运行。
		2.互备模式
			互备模式是指两台主机同时运行各自的服务工作且相互监测情况。
		3.集群
			集群模式是指有多个节点在运行,同时可以通过主控节点分担服务请求,比如zookeeper。集群模式哟啊特别解决主控节点本身的高可用问题。

	3.容错性
		顾名思义就是IT系统对错误的包容能力,这里的容错确切的说是容故障(Fault),而并非容错误(error)。
		容错的处理是保障分布式环境下相应系统的高可用或健壮性,一个典型的案例就是对缓存失效雪崩问题的解决方案。
		我们在项目中使用缓存通常是先检查缓存是否存在,如果存在直接返回,如果不存在就查询db然后再缓存结果返回。这个时候如果我们查询的某一个数据在缓存中一直不存在,就会
	  造成每一次请求都查询db,这样缓存就失去了意义,在流量大的时候,可能db就挂掉了。
	    一个比较巧妙的方法是,可以将这个不存在的key预先设定一个值,比如, key='&&'。在返回这个&&的值的时候,我们的应用就认为这是不存在的key,那我们的应用就可以决定
	  是否继续等待继续访问,还是放弃掉这次操作。如果继续等待访问,过一个时间轮询点后,再次请求这个key,如果取得的值不再是&&,则可以认为这个时候key有值了,从而避免透传
	  到db,把大量的请求挡在了缓冲之中。

	4.负载均衡
		负载均衡集群:其关键在于使用多台集群服务器共同分担计算任务,把网络请求及计算分配到集群可用服务器上,从而达到可用性以及较好的用户体验操作。
		负载均衡有硬件解决方案(F5),也有软件解决方案(LVS,HAProxy,Nginx等)。
		Nginx负载均衡策略:
			1.轮询
			2.最少连接
			3.IP地址哈希
			4.基于权重的负载均衡

5.分布式系统设计实践
	1.全局ID生成
		1.UUID
			UUID 由以下几部分组成:
				1.当前日期和时间,UUID的第一个部分与时间有关,如果你生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
				2.时钟序列
				3.全局唯一的IEEE机器识别码,如果有网卡,从网卡MAC地址获取,没有网卡以其他方式获得。
			优势:API简单,易用
			不足:占用空间大,字符串本身无法加工,可读写不强。

		2.ID生成表模式
			使用id生成表,比较经典的是Flicker的案例,Flicker在解决全局ID生成方案里就采用了mysql自增长的id机制。先是创建单独的数据库,然后创建一个表:
			create table `Tickets64` (
				`id` bigint(20) unsigned not null auto_increment,
				`stub` char(1) not null default '',
				unique key `stub`(`stub`)
			) engine=myisam;
			在我们的应用端需要做下面2个操作,在一个事务会话里提交:
			replace into Tickets64(stub) values('a');
			select last_insert_id();
			这样我们就能拿到不断增长且不重复的id了,到上面为止,我们只是在单台数据库上生成id,从高可用角度看,需要解决单点问题,Flicker的方案是启用两台
		  数据库服务来生成id,通过区分auto_increment 的起始值和步长来生成奇偶数的id。
		    这个方案的优势是简单,也有一定的高可用,不足是使用了mysql数据库的独特语法 replace into。

		3.Snowflake
			Twitter 把存储系统从mysql迁移到 Cassandra 的过程由于 Cassandra 没有顺序ID生成机制,于是自己开发了一套全局唯一id生成服务:Snowflake。
			snowflake 系统生成64位的id,由3个部分组成:
				1.41位的时间序列(精确到毫秒,41位的长度可使用69年)
				2.10位的机器标识(10位的长度最多支持部署1024个节点)
				3.12位的技术顺序号(12位的计数顺序号支持每个节点每毫秒产生4096个id序号)
			优点:高性能,低延迟;独立的应用;按时间有序
			缺点:需要独立的开发和部署

		4.结合缓存方案
			可以采用id生成表模式成批获取id比如1000放到本地缓存,这样client使用的时候可以进一步提升性能。
			优点:高性能,低延迟
			缺点:id不连贯

	2.哈希取模
		哈希方式是最常见的数据分布方式,实现方式是通过可以描述记录的业务的id或key,通过Hash函数的计算求余。余数作为处理该数据的服务器索引编号处理。
		这样的好处是只需要通过计算就可以映射出数据和处理节点的关系,不需要存储映射,难点就是如果id分布不均匀可能出现计算,存储倾斜的问题,在某个节点
	  上分布过重。另外在调整数据存储,比如把2个库扩展成4个库,数据迁移是一个比较麻烦的事情。
	    分布式缓存:
	    	假设有3台server提供缓存服务,假设数据基本均衡,则每台机器缓存1/3的数据。如果增加2台服务器,算法变成Hash(key)/5,大部分数据都会出现不能
	      命中的情况。
	    拆分数据库:	
	    	也存在扩容问题,解决方法是预先设定足够大的逻辑库,比如100个,随着物理负载的增加,把对应的逻辑库迁移到新增的物理库上即可,对于应用透明,
	      相当于再应用和物理数据库之间增加了一层映射关系。

	3.一致性哈希
		一致性哈希算法是1997年麻省理工学院提出的一种分布式哈希(DHT)实现算法。主要解决单调性(Monotonicity)和分散性(Spread)的问题。单调性简单描述的是
	  哈希的结果应能够保证原有已分配的内容可以被映射到原有的缓冲中去,避免在节点增减过程中导致不能命中。
	    按照常用的hash算法来将对应的key哈希到一个具有2^32次方个桶中,即 0~(2^32)-1的数字空间中。现在我们可以将这些数字头尾相连,想象成一个闭合的环形。
	    在一致性哈希算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间的数据,
	  其他不会受到影响。
	    一致性哈希的优点在于可以任意动态添加,删除节点,每次添加,删除一个节点仅影响一致性哈希环上相邻的节点。为了尽可能均匀的分布节点和数据,一种常见的
	  改进算法是引入虚节点的概念,系统会创建很多虚节点,个数远大于当前节点的个数,均匀的分布到一致性哈希值域环上。这种增强型方案主要解决平衡性问题,所谓
	  平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。

	4.路由表
		什么情况下走到路由表模式,一般在于需要全局计算的节点。由于在高并发环境下比较单行记录热点,则对预算进行了拆分,并且拆分到不同逻辑数据库中去。
		采用路由表存在一个风险,就是数据是集中式管理的,存在单点风险。如果数据规模小,而数据库本身有备份机制或者 failover 能力,是可行的。

	5.数据拆分
		Cobar 是一个著名的阿里巴巴的分布式数据库中间件。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值