1.一致性协议1.1两阶段提交2PC:本身是一致强一致性算法,所以很适合用作数据库的分布式事务。其实数据库的经常用到的TCC本身就是一种2PC。
数据库事务:回顾下数据库的事务,对一条数据的修改操作首先写undo日志,记录的数据原来的样子,接下来执行事务修改操作,把数据写到redo日志里面,万一捅娄子,事务失败了,可从undo里面回复数据。
数据库通过undo与redo能保证数据的强一致性,要解决分布式事务的前提就是当个节点是支持事务的。在这个前提下,2PC将整个分布式事务分两节点:
1.第一阶段:为准备节点,事务的请求都发送给一个个资源,资源可以是数据库,也可以是其他支持事务的框架(比如zookeeper),他们会分别执行自己的事务,写日志到undo与redo,但不提交事务。2.第二阶段:当事务管理器收到了所以资源的反馈,事务都执行没报错后,事务管理器再发送commit指令让资源把事务提交,一旦发现任何一个资源在准备阶段没有执行成功,事务管理器会发送rollback,让所有的资源都回滚。强一致性是指:保证每个资源都成功,整个分布式事务才成功.
缺点:
1.同步阻塞.----------所有的节点都在等待其他节点的响应,无法进行其他操作。这种同步阻塞极大的限制了分布式系统的性能。2.单点问题.----------如果协调者在提交(commit)阶段出现问题,那么整个流程将无法运转。更重要的是,其他参与者将会处于一直锁定事务资源的状态中,而无法继续完成事务操作.3.数据不一致.-------若协调者即事务管理器未发送完所有commit请求自身崩溃,则导致一部分参与者未收到commit请求,导致数据不一致.4.容错性不好.----任何一个节点失败都会导致整个事务失败.1.2.三阶段提交 three-phase commit (3PC)
第一阶段:协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。第二阶段:如果所有服务都ok,可以接收事务请求,这一阶段就可以执行事务了,这时候也是每个资源都回写redo与undo日志,事务执行成功,返回ack(yes),否则返回no第三阶段:这阶段和前面说的2阶段提交大同小异,这个时候协调者发现所有提交者事务提交者事务都正常执行后,给所有资源发送commit指令。与2PC区别:第二阶段才写undo和redo事务日志第三阶段协调者出现异常或网络超时参与者也会commit
三阶段3PC优点:相对于2PC,3PC主要解决的单点故障问题,并减少阻塞,因为一旦参与者无法及时收到来自协调者的信息之后,会默认执行commit。而不会一直持有事务资源并处于阻塞状态。但是这种机制也会导致数据一致性问题,比如由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。
但回顾整个过程,不管是2pc,还是3pc,同步阻塞,单点故障,容错机制不完善这些问题都没本质上得到解决,尤其是前面说得数据一致性问题,反而更糟糕了。
所有数据库的分布式事务一般都是二阶段提交,而者三阶段的思想更多的被借鉴扩散成其他的算法
1.3.Paxos算法
paxos算法分为两个阶段,有2个角色,提议者和接受者。
关键是:1.少数服从多数2.角色轮换避免单点故障具体流程也没搞清楚~~先知道核心思想即可
2 zookeeper集群2.1 zookeeper集群特点
顺序一致性 :客户端的更新顺序与它们被发送的顺序相一致。原子性: 更新操作要么成功要么失败,没有第三种结果。单一视图: 无论客户端连接到哪一个服务器,客户端将看到相同的 ZooKeeper 视图。可靠性: 一旦一个更新操作被应用,那么在客户端再次更新它之前,它的值将不会改变。实时性: 连接上一个服务端数据修改,所以其他的服务端都会实时的跟新,不算完全的实时,有一点延时的角色轮换避免单点故障: 当leader出现问题的时候,会选举从follower中选举一个新的leader集群中的角色
Leader: 集群工作机制中的核心 事务请求的唯一调度和处理者,保证集群事务处理的顺序性, 集群内部个服务器的调度者(管理follower,数据同步)Follower: 集群工作机制中的跟随者处理非事务请求,转发事务请求给Leader, 参与事务请求proposal投票, 参与leader选举投票Observer: 观察者 3.30以上版本提供,和follower功能相同,但不参与任何形式投票 处理非事务请求,转发事务请求给Leader 提高集群非事务处理能力2.1 zookeeper集群搭建1.安装JDK,zookeeper。
2.配置环境变量vi /etc/profile
export JAVA_HOME=/usr/local/jdk1.8.0_211export ZOOKEEPER_HOME=/usr/local/zookeeperexport CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarexport PATH=$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$PATH
刷新profile文件source /etc/profile 关闭防火墙(命令视不同系统情况而定) 3.修改zk配置文件
mv zoo_sample.cfg zoo.cfg
修改conf: vi zoo.cfg 修改两处(1) dataDir=/usr/local/zookeeper/data(注意同时在zookeeper创建data目录)
dataDirLog=/usr/local/zookeeper/log 日志目录,并创建目录(2)最后面添加server.0=192.168.64.128:2888:3888(2888是集群内机器通讯端口,3888是选举leader使用)server.1=192.168.64.129:2888:3888server.2=192.168.64.130:2888:3888
注意:server.0,server.1中,0和1就是服务器标识4.创建服务器标识
在dataDir路径下data目录下创建myid文件,内容即为0/1/2,即上述配置的。
5.复制 /usr/local/zookeeper下所有文件到另外2个服务器上面,只修改myid的服务器标识即可。
...