分布式服务组件zookeeper

分布式系统是什么

分布式系统:一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统

这是分布式系统,在不同的硬件,不同的软件,不同的网络,不同的计算机上,仅仅通过消息来进行通讯与协调。

这是他的特点,更细致的看这些特点又可以有:分布性、对等性、并发性、缺乏全局时钟、故障随时会发生。

分布式系统带来的问题

如果把分布式系统和平时的交通系统进行对比,哪怕再稳健的交通系统也会有交通事故,分布式系统也有很多需要攻克的问题,比如:通讯异常,网络分区,三态,节点故障等。

网络分区就是所谓的脑裂,本来有一个交通警察,来管理整个片区的交通情况,一切井然有序,突然出现了停电,或者出现地震等自然灾难,某些道路接受不到交通警察的指令,可能在这种情况下,会出现一个零时工,片警零时来指挥交通。

三态就是成功,失败,超时这三种状态。

CAP理论

CAP其实就是一致性,可用性,分区容错性这三个词的缩写。
一致性:
一致性是事务ACID的一个特性【原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)】。

可用性:
可用性指系统提供服务必须一直处于可用状态,对于用户的操作请求总是能够在有限的时间内访问结果。

分区容错性:
分布式系统在遇到任何网络分区故障的时候,仍然需要能够对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。
不能出现脑裂的情况。

注意:一个分布式系统不可能同时满足一致性、可用性和分区容错性这三个基本需求,最多只能同时满足其中的两项。但是因为不可能将所有服务都用一个节点控制,所以P是一定要满足的,所以只能在C和A上考虑,但是单独放弃C和A也不可能,因此架构师的精力往往就花在怎么样根据业务场景在A和C之间寻求平衡。

BASE理论

BASE理论:即使无法做到强一致性,但分布式系统可以根据自己的业务特点,采用适当的方式来使系统达到最终的一致性;

基本可用:当分布式系统出现不可预见的故障时,允许损失部分可用性,保障系统的“基本可用”;体现在“时间上的损失”和“功能上的损失		”。例如:部分用户双十一高峰期淘宝页面卡顿或降级处理

软状态:既允许系统中的数据存在中间状态,既系统的不同节点的数据副本之间的数据同步过程存在延时,并认为这种延时不会影响系统		可用性。例如:12306网站卖火车票,请求会进入排队队列。

最终一致性:所有的数据在经过一段时间的数据同步后,最终能够达到一个一致的状态。例如:理财产品首页充值总金额短时不一致。

分布式系统的设计目标

1,简单的数据结构:共享的树形结构,类似文件系统,存储于内存;

2,可以构建集群:避免单点故障,3-5台机器就可以组成集群,超过半数正常工作就能对外提供服务;

3,顺序访问:对于每个读请求,zk会分配一个全局唯一的递增编号,利用这个特性可以实现高级协调服务;

4,高性能:基于内存操作,服务于非事务请求,适用于读操作为主的业务场景。3台zk集群能达到13w QPS;

哪些常见操作需要用到ZK

数据发布订阅
负载均衡
命名服务
Master选举
集群管理
配置管理
分布式队列
分布式锁

ZK数据模型

ZooKeeper的视图结构和标准的Unix文件系统类似,其中每个节点称为“数据节点”或ZNode,每个znode可以存储数据,还可以挂载子节点,因此可以称之为“树”
第二点需要注意的是,每一个znode都必须有值,如果没有值,节点是不能创建成功的。

会话

Zk客户端和服务端成功连接后,就创建了一次会话,ZK会话在整个运行期间的生命周期中,会在不同的会话状态之间切换,这些状态包括:
CONNECTING、CONNECTED、RECONNECTING、RECONNECTED、CLOSE

一旦客户端开始创建Zookeeper对象,那么客户端状态就会变成CONNECTING状态,同时客户端开始尝试连接服务端,连接成功后,客户端状态变为CONNECTED,通常情况下,由于断网或其他原因,客户端与服务端之间会出现断开情况,一旦碰到这种情况,Zookeeper客户端会自动进行重连服务,同时客户端状态再次变成CONNCTING,直到重新连上服务端后,状态又变为CONNECTED,在通常情况下,客户端的状态总是介于CONNECTING和CONNECTED之间。但是,如果出现诸如会话超时、权限检查或是客户端主动退出程序等情况,客户端的状态就会直接变更为CLOSE状态

zk节点的参数

Conf目录为配置文件存放的目录,zoo.cfg为核心的配置文件
clientPort:参数无默认值,必须配置,用于配置当前服务器对外的服务端口,客户端必须使用这端口才能进行连接
dataDir:用于存放内存数据库快照的文件夹,同时用于集群的myid文件也存在这个文件夹里(注意:一个配置文件只能包含一个dataDir字样,即使它被注释掉了。)
dataLogDir:用于单独设置transaction log的目录,transaction log分离可以避免和普通log还有快照的竞争
tickTime:心跳时间,为了确保连接存在的,以毫秒为单位,最小超时时间为两个心跳时间
initLimit:多少个心跳时间内,允许其他server连接并初始化数据,如果ZooKeeper管理的数据较大,则应相应增大这个值
syncLimit:多少个tickTime内,允许follower同步,如果follower落后太多,则会被丢弃。

注意:dataDir:新安装zk这文件夹里面是没有文件的,可以通过snapCount参数配置产生快照的时机

节点类型

1,Znode有两种类型:

	短暂(ephemeral)(create -e /app1/test1 “test1” 客户端断开连接zk删除ephemeral类型节点) 
	持久(persistent) (create -s /app1/test2 “test2” 客户端断开连接zk不删除persistent类型节点)

2,Znode有四种形式的目录节点(默认是persistent ):
PERSISTENT
PERSISTENT_SEQUENTIAL(持久序列/test0000000019 )
EPHEMERAL
EPHEMERAL_SEQUENTIAL

3,创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护

4,在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序

ACL保障数据的安全

ACL机制,表示为scheme?permissions,第一个字段表示采用哪一种机制,第二个id表示用户,permissions表示相关权限(如只读,读写,管理等)。

zookeeper提供了如下几种机制(scheme):
world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的

auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos来进行authencation, 也支持username/password形式的authentication)

digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
密文密码可以通过 DigestAuthenticationProvider.generateDigest(“username:passowrd”)获取。

ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段

Zookeeper的ACL(Access Control List),分为三个维度:scheme、id、permission
	通常表示为:scheme:id:permission
		schema:代表授权策略
			world:
				默认方式,相当于全世界都能访问
			auth:
				代表已经认证通过的用户(可以通过addauth digest user:pwd 来添加授权用户)
			digest:
				即用户名:密码这种方式认证,这也是业务系统中最常用的
			ip:
				使用Ip地址认证

		id:代表用户
		permission:代表权限
			CREATE、READ、WRITE、DELETE、ADMIN也就是增、删、改、查、管理权限,这5种权限简写为crwda(即:每个单词的首字符缩写)
			CREATE(c):创建子节点的权限 
			DELETE(d):删除节点的权限 
			READ(r):读取节点数据的权限 
			WRITE(w):修改节点数据的权限 
			ADMIN(a):设置子节点权限的权限

分布式事务的一致性算法(BASE理论的实现)

2PC:2PC,二阶段提交协议,即将事务的提交过程分为两个阶段来进行处理:准备阶段和提交阶段。事务的发起者称协调者,事务的执行者称参与者。其实数据库的经常用到的TCC本身就是一种2PC。

阶段1:准备阶段

1、协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。
  2、各参与者执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。
Redo,顾名思义就,重做。以恢复操作为目的,重现操作。
Undo,意为取消,以撤销操作为目的,返回上一个状态,类似备份。
  3、如参与者执行成功,给协调者反馈YES,即可以提交;如执行失败,给协调者反馈NO,即不可提交。

阶段2:提交阶段

此阶段分两种情况:所有参与者均反馈YES、或任何一个参与者反馈NO。
  所有参与者均反馈YES时,即提交事务。
  任何一个参与者反馈NO时,即中断事务。
 提交事务:(所有参与者均反馈YES)
  1、协调者向所有参与者发出正式提交事务的请求(即Commit请求)。
  2、参与者执行Commit请求,并释放整个事务期间占用的资源。
  3、各参与者向协调者反馈Ack完成的消息。
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
中断事务:(任何一个参与者反馈NO)
  1、协调者向所有参与者发出回滚请求(即Rollback请求)。
  2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
  3、各参与者向协调者反馈Ack完成的消息。
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
2PC的缺陷:
  1、同步阻塞:最大的问题即同步阻塞,即:所有参与事务的逻辑均处于阻塞状态。
  2、单点:协调者存在单点问题,如果协调者出现故障,参与者将一直处于锁定状态。
  3、脑裂:在阶段2中,如果只有部分参与者接收并执行了Commit请求,会导致节点数据不一致。
  由于2PC存在如上同步阻塞、单点、脑裂问题,因此又出现了2PC的改进方案,即3PC。

tcc

TCC将事务提交分为 Try - Confirm - Cancel 3个操作。
	Try:预留业务资源/数据效验
	Confirm:确认执行业务操作
	Cancel:取消执行业务操作
	TCC事务处理流程和 2PC 二阶段提交类似,不过 2PC通常都是在跨库的DB层面,而TCC本质就是一个应用层面的2PC。
事务补偿型(TCC事务):
	TCC型事务(Try/Confirm/Cancel)可以归为补偿型。
	补偿型的例子,在一个长事务( long-running )中 ,一个由两台服务器一起参与的事务,服务器A发起事务,服务器B参与事务,B的事务需要人工参与,所以处理时间可能很长。如果按照ACID的原则,要保持事务的隔离性、一致性,服务器A中发起的事务中使用到的事务资源将会被锁定,不允许其他应用访问到事务过程中的中间结果,直到整个事务被提交或者回滚。这就造成事务A中的资源被长时间锁定,系统的可用性将不可接受。
	WS-BusinessActivity提供了一种基于补偿的long-running的事务处理模型。还是上面的例子,服务器A的事务如果执行顺利,那么事务A就先行提交,如果事务B也执行顺利,则事务B也提交,整个事务就算完成。但是如果事务B执行失败,事务B本身回滚,这时事务A已经被提交,所以需要执行一个补偿操作,将已经提交的事务A执行的操作作反操作,恢复到未执行前事务A的状态。这样的SAGA事务模型,是牺牲了一定的隔离性和一致性的,但是提高了long-running事务的可用性。
TCC优点:
	让应用自己定义数据库操作的粒度,使得降低锁冲突、提高吞吐量成为可能。
TCC不足之处:
	对应用的侵入性强。业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
	实现难度较大。需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略。为了满足一致性的要求,confirm和cancel接口必须实现幂等。

tcc和2PC的区别:
TCC属于业务上的分段提交,Try,confirm,cancel都是对应的一段业务逻辑的操作,先预留资源,预留成功后进行确认,不成功就取消,例如转账先冻结资金,进行一系列的余额各方面的检查,发现符合条件就对账户对应的资金状态改为冻结,确认阶段修改状态为扣除,取消的话就把冻结的资金加回原账户,其对应的数据库的操作每段都是一个完整的事物;2PC是属于数据库层面的,先进行prepare,然后逐个进行commit或者rollback,不和具体业务逻辑挂钩,TCC的应用范围更广,不一定是事物关系数据库,也可能操作的KV数据库,文档数据库,粒度也可以随着具体业务灵活调整,性能更好。

3PC

3PC,三阶段提交协议,是2PC的改进版本,即将事务的提交过程分为CanCommit、PreCommit、doCommit三个阶段来进行处理。

阶段1:CanCommit

1、协调者向所有参与者发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复。
  2、参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态,否则反馈NO。

阶段2:PreCommit

此阶段分两种情况:
  1、所有参与者均反馈YES,即执行事务预提交。
  2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。
  事务预提交:(所有参与者均反馈YES时)
  1、协调者向所有参与者发出PreCommit请求,进入准备阶段。
  2、参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务)。
  3、各参与者向协调者反馈Ack响应或No响应,并等待最终指令。

  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
  1、协调者向所有参与者发出abort请求。
  2、无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。
阶段3:doCommit

此阶段也存在两种情况:
  1、所有参与者均反馈Ack响应,即执行真正的事务提交。
  2、任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务。

   提交事务:(所有参与者均反馈Ack响应时)
  1、如果协调者处于工作状态,则向所有参与者发出do Commit请求。
  2、参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源。
  3、各参与者向协调者反馈Ack完成的消息。
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
 
  中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
  1、如果协调者处于工作状态,向所有参与者发出abort请求。
  2、参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源。
  3、各参与者向协调者反馈Ack完成的消息。
  4、协调者收到所有参与者反馈的Ack消息后,即完成事务中断。

注意:进入阶段三后,无论协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的doCommit请求或abort请求。此时,参与者都会在等待超时之后,继续执行事务提交。无论2PC或3PC,均无法彻底解决分布式一致性问题。解决一致性问题,唯有Paxos。

3PC的优点和缺陷:
  优点:降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时,参与者会继续提交事务。
  缺陷:脑裂问题依然存在,即在参与者收到PreCommit请求后等待最终指令,如果此时协调者无法与参与者正常通信,会导致参与者继续提交事务,造成数据不一致。

Paxos:

在paxos算法中,分为4种角色:
	  Proposer :提议者
	  Acceptor:决策者
	  Client:产生议题者
	  Learner:最终决策学习者
提议者和决策者是很重要的,其他的2个角色在整个算法中应该算做打酱油的,Proposer就像Client的使者,由Proposer使者拿着Client的议题去向Acceptor提议,让Acceptor来决策。这里上面出现了个新名词:最终决策。现在来系统的介绍一下paxos算法中所有的行为:
		1,Proposer提出议题
		2,Acceptor初步接受 或者 Acceptor初步不接受
		3,如果上一步Acceptor初步接受则Proposer再次向Acceptor确认是否最终接受
		4,Acceptor 最终接受 或者Acceptor 最终不接受
		注意:Acceptor必须是最少大于等于3个,并且必须是奇数个,因为要形成多数派嘛,如果是偶数个,比如4个,2个接受2个不接受,各执己见,没法搞下去了。
举例:
阶段一:
		1.现在需要对一项议题来进行paxos过程,议题是“A项目我要中标!”,这里的“我”指每个带着他的秘书Proposer的Client老板。
		2.Proposer当然听老板的话了,赶紧带着议题和现金去找Acceptor政府官员。
		3.作为政府官员,当然想谁给的钱多就把项目给谁。
		4.Proposer-1小姐带着现金同时找到了Acceptor-1~Acceptor-3官员,1与2号官员分别收取了10比特币,找到第3号官员时,没想到遭到了3号官员的鄙视,3号官员告诉她,Proposer-2给了11比特币。不过没关系,Proposer-1已经得到了1,2两个官员的认可,形成了多数派(如果没有形成多数派,Proposer-1会去银行提款在来找官员们给每人20比特币,这个过程一直重复每次+10比特币,直到多数派的形成),满意的找老板复命去了,但是此时Proposer-2保镖找到了1,2号官员,分别给了他们11比特币,1,2号官员的态度立刻转变,都说Proposer-2的老板懂事,这下子Proposer-2放心了,搞定了3个官员,找老板复命去了,当然这个过程是第一阶段提交,只是官员们初步接受贿赂而已。故事中的比特币是编号,议题是value。
阶段二:
		5. 现在进入第二阶段提交,现在proposer-1小姐使用分身术(多线程并发)分了3个自己分别去找3位官员,最先找到了1号官员签合同,遭到了1号官员的鄙视,1号官员告诉他proposer-2先生给了他11比特币,因为上一条规则的性质proposer-1小姐知道proposer-2第一阶段在她之后又形成了多数派(至少有2位官员的赃款被更新了);此时她赶紧去提款准备重新贿赂这3个官员(重新进入第一阶段),每人20比特币。刚给1号官员20比特币,1号官员很高兴初步接受了议题,还没来得及见到2,3号官员的时候
		这时proposer-2先生也使用分身术分别找3位官员(注意这里是proposer-2的第二阶段),被第1号官员拒绝了告诉他收到了20比特币,第2,3号官员顺利签了合同,这时2,3号官员记录client-2老板用了11比特币中标,因为形成了多数派,所以最终接受了Client2老板中标这个议题,对于proposer-2先生已经出色的完成了工作;
		这时proposer-1小姐找到了2号官员,官员告诉她合同已经签了,将合同给她看,proposer-1小姐是一个没有什么职业操守的聪明人,觉得跟Client1老板混没什么前途,所以将自己的议题修改为“Client2老板中标”,并且给了2号官员20比特币,这样形成了一个多数派。顺利的再次进入第二阶段。由于此时没有人竞争了,顺利的找3位官员签合同,3位官员看到议题与上次一次的合同是一致的,所以最终接受了,形成了多数派,proposer-1小姐跳槽到Client2老板的公司去了。

总结:Paxos过程结束了,这样,一致性得到了保证,算法运行到最后所有的proposer都投“client2中标”所有的acceptor都接受这个议题,也就是说在最初的第二阶段,议题是先入为主的,谁先占了先机,后面的proposer在第一阶段就会学习到这个议题而修改自己本身的议题,因为这样没职业操守,才能让一致性得到保证,这就是paxos算法的一个过程。原来paxos算法里的角色都是这样的不靠谱,不过没关系,结果靠谱就可以了。该算法就是为了追求结果的一致性。
扩展:拜将庭问题。

缺点:
	Paxos算法虽然通用,可靠,但终归效率太低。Paxos算法在出现竞争的情况下,其收敛速度很慢,甚至可能出现活锁的情况,例如当有三个及三个以上的proposer在发送prepare请求后,很难有一个proposer收到半数以上的回复而不断地执行第一阶段的协议。因此,为了避免竞争,加快收敛的速度,在算法中引入了一个Leader这个角色,在正常情况下同时应该最多只能有一个参与者扮演Leader角色,而其它的参与者则扮演Acceptor的角色。

zab:

ZAB协议包括两种基本的模式:崩溃恢复和消息广播,可以解决脑裂。
当整个服务框架在启动过程中,或是当Leader服务器出现网络中断崩溃退出与重启等异常情况时,ZAB就会进入恢复模式并选举产生新的Leader服务器。
当选举产生了新的Leader服务器,同时集群中已经有过半的机器与该Leader服务器完成了状态同步之后,ZAB协议就会退出崩溃恢复模式,进入消息广播模式。
当有新的服务器加入到集群中去,如果此时集群中已经存在一个Leader服务器在负责进行消息广播,那么新加入的服务器会自动进入数据恢复模式,找到Leader服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。
以上其实大致经历了三个步骤:
1.崩溃恢复:主要就是Leader重新选举过程,注意这里是根据myid和ZXID(事务id)投票,优先投ZXID大的,因为ZXID大表示事务最近发				生,也能保证数据是最新的,保证数据的不丢失和一致性。
2.数据同步:Leader服务器与其他服务器进行数据同步,并且询问是否可以提交事务。
3.消息广播:Leader服务器将数据发送给其他follower服务器,并提交事务。

分布式锁

1,使用没有顺序的Lock节点实现。
思路:
1,创建一个Lock接口,定义获取锁和释放锁的方法,然后具体实现。
2,获取锁的思路是,创建一个lock的节点,然后添加一个监听,监听当前节点是否被删除,如果存在当前节点,就证明有进程获取到了锁,其他进程需要等待,如果这个节点被删除了,就让其他进程竞争这把锁。
3,释放锁即是删除这个lock节点。
缺点:
1,性能差,会出现频繁的创建和删除节点,适合于10个服务器集群之内。
2,当出现大量进程竞争的时候,容易出现羊群效应,如果一旦同一时间有多个节点挂了,服务端就要给客户端发送大量通知,这样就是羊群效应。

2,使用有顺序的Lock节点实现。
思路:
1,创建一个Lock接口,定义获取锁和释放锁的方法,然后具体实现。
2,获取锁的思路是,创建一个有顺序的lock的节点,获取所有节点并排序,判断当前节点是否是节点列表中的第一个,如果是就获取成功锁,如果不是,则添加一个监听,监听前一个节点是否被删除。
3,释放锁即是删除这个前一个lock节点。
注意:这种方式解决了上一种的羊群问题,当多个节点挂了的时候,只需要通知第二个节点即可。
缺点:排队,效率低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值