前言

什么是ZooKeeper,你真的了解它吗。我们一起来看看吧~

一、什么是 ZooKeeper?

ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效、高可用的分布式协调服务,提供了诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知和分布式锁等分布式基础服务。由于 ZooKeeper 便捷的使用方式、卓越的性能和良好的稳定性,被广泛地应用于诸如 Hadoop、HBase、Kafka 和 Dubbo 等大型分布式系统中。

Zookeeper 有三种运行模式:单机模式、伪集群模式和集群模式。

单机模式:

这种模式一般适用于开发测试环境,一方面我们没有那么多机器资源,另外就是平时的开发调试并不需要极好的稳定性。

集群模式

一个 ZooKeeper 集群通常由一组机器组成,一般 3 台以上就可以组成一个可用的 ZooKeeper 集群了。组成 ZooKeeper 集群的每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都会互相保持通信。

伪集群模式:
这是一种特殊的集群模式,即集群的所有服务器都部署在一台机器上。当你手头上有一台比较好的机器,如果作为单机模式进行部署,就会浪费资源,这种情况下,ZooKeeper 允许你在一台机器上通过启动不同的端口来启动多个 ZooKeeper 服务实例,以此来以集群的特性来对外服务。

ZooKeeper 的相关知识

Zookeeper 中的角色:

领导者(leader):

负责进行投票的发起和决议,更新系统状态。

跟随者(follower):

用于接收客户端请求并给客户端返回结果,在选主过程中进行投票。

观察者(observer):

可以接受客户端连接,将写请求转发给 leader,但是observer 不参加投票的过程,只是为了扩展系统,提高读取的速度。

Zookeeper 的数据模型

1.层次化的目录结构,命名符合常规文件系统规范,类似于 Linux。

2.每个节点在 Zookeeper 中叫做 Znode,并且其有一个唯一的路径标识。

3.节点 Znode 可以包含数据和子节点,但是 EPHEMERAL 类型的节点不能有子节点。

4.Znode 中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本。

5.客户端应用可以在节点上设置监视器。

6.节点不支持部分读写,而是一次性完整读写。

ZooKeeper 的节点特性

ZooKeeper 节点是生命周期的,这取决于节点的类型。在 ZooKeeper 中,节点根据持续时间可以分为持久节点(PERSISTENT)、临时节点(EPHEMERAL),根据是否有序可以分为顺序节点(SEQUENTIAL)、和无序节点(默认是无序的)。

持久节点一旦被创建,除非主动移除,不然一直会保存在 Zookeeper 中(不会因为创建该节点的客户端的会话失效而消失)。

Zookeeper 的应用场景

ZooKeeper 是一个高可用的分布式数据管理与系统协调框架。基于对 Paxos 算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得 ZooKeeper 解决很多分布式问题。

值得注意的是,ZooKeeper 并非天生就是为这些应用场景设计的,都是后来众多开发者根据其框架的特性,利用其提供的一系列 API 接口(或者称为原语集),摸索出来的典型使用方法。

数据发布与订阅(配置中心)

发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到 ZooKeeper 节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。

应用中用到的一些配置信息放到 ZooKeeper 上进行集中管理。这类场景通常是这样:应用在启动的时候会主动来获取一次配置,同时在节点上注册一个 Watcher。这样一来,以后每次配置有更新的时候,都会实时通知到订阅的客户端,从来达到获取最新配置信息的目的。

分布式搜索服务中,索引的元信息和服务器集群机器的节点状态存放在 ZooKeeper 的一些指定节点,供各个客户端订阅使用。

分布式日志收集系统

这个系统的核心工作是收集分布在不同机器的日志。收集器通常是按照应用来分配收集任务单元,因此需要在 ZooKeeper 上创建一个以应用名作为 path 的节点 P,并将这个应用的所有机器 IP,以子节点的形式注册到节点 P 上。这样一来就能够实现机器变动的时候,能够实时通知到收集器调整任务分配。

系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息的发问。通常是暴露出接口,例如 JMX 接口,来获取一些运行时的信息。引入 ZooKeeper 之后,就不用自己实现一套方案了,只要将这些信息存放到指定的 ZooKeeper 节点上即可。

注意:
在上面提到的应用场景中,有个默认前提——数据量很小,但是数据更新可能会比较快的场景。

负载均衡

这里说的负载均衡是指软负载均衡。在分布式环境中,为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,达到对等服务。而消费者就须要在这些对等的服务器中选择一个来执行相关的业务逻辑,其中比较典型的是消息中间件中的生产者,消费者负载均衡。

命名服务(Naming Service)

命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,通过使用命名服务,客户端应用能够根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体通常可以是集群中的机器,提供的服务地址,远程对象等等——这些我们都可以统称它们为名字(Name)。其中较为常见的就是一些分布式服务框架中的服务地址列表。通过调用 ZooKeeper 提供的创建节点的 API,能够很容易创建一个全局唯一的path,这个 path 就可以作为一个名字。

阿里巴巴集团开源的分布式服务框架 Dubbo 中使用 ZooKeeper 来作为其命名服务,维护全局的服务地址列表。在 Dubbo 的实现中:

1.服务提供者在启动的时候,向 ZooKeeper 上的指定节点 /dubbo/${serviceName}/providers 目录下写入自己的 URL 地址,这个操作就完成了服务的发布。

2.服务消费者启动的时候,订阅 /dubbo/serviceName/providers目录下的提供者URL地址,并向/dubbo/{serviceName}/providers 目录下的提供者 URL 地址, 并向 /dubbo/serviceName/providers目录下的提供者URL地址,并向/dubbo/{serviceName} /consumers 目录下写入自己的 URL 地址。

注意:
所有向 ZooKeeper 上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。

另外,Dubbo 还有针对服务粒度的监控。方法是订阅 /dubbo/${serviceName} 目录下所有提供者和消费者的信息。

分布式通知/协调

ZooKeeper 中特有 Watcher 注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对 ZooKeeper 上同一个 Znode 进行注册,监听 Znode 的变化(包括 Znode 本身内容及子节点的),其中一个系统 Update 了 Znode,那么另一个系统能够收到通知,并作出相应处理。

另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过 ZooKeeper 上某个节点关联,大大减少系统耦合。

另一种系统调度模式:某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改了 ZooKeeper 上某些节点的状态,而 ZooKeeper 就把这些变化通知给它们注册 Watcher 的客户端,即推送系统。于是,作出相应的推送任务。

另一种工作汇报模式:一些类似于任务分发系统。子任务启动后,到 ZooKeeper 来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点)。这样任务管理者就能够实时知道任务进度。

分布式锁

分布式锁主要得益于 ZooKeeper 为我们保证了数据的强一致性。锁服务可以分为两类:一类是保持独占,另一类是控制时序。

所谓保持独占,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把 ZooKeeper 上的一个 Znode 看作是一把锁,通过 create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。

控制时序,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL 来指定)。ZooKeeper 的父节点(/distribute_lock)维持一份 sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。

1.由于同一节点下子节点名称不能相同,所以只要在某个节点下创建 Znode,创建成功即表明加锁成功。注册监听器监听此 Znode,只要删除此 Znode 就通知其他客户端来加锁。

2.创建临时顺序节点:在某个节点下创建节点,来一个请求则创建一个节点,由于是顺序的,所以序号最小的获得锁,当释放锁时,通知下一序号获得锁。

分布式队列

队列方面,简单来说有两种:一种是常规的先进先出队列,另一种是等队列的队员聚齐以后才按照顺序执行。对于第一种的队列和上面讲的分布式锁服务中控制时序的场景基本原理一致,这里就不赘述了。

第二种队列其实是在 FIFO 队列的基础上作了一个增强。通常可以在 /queue 这个 Znode 下预先建立一个 /queue/num 节点,并且赋值为 n(或者直接给 /queue 赋值 n)表示队列大小。之后每次有队列成员加入后,就判断下是否已经到达队列大小,决定是否可以开始执行了。

这种用法的典型场景是:分布式环境中,一个大任务 Task A,需要在很多子任务完成(或条件就绪)情况下才能进行。这个时候,凡是其中一个子任务完成(就绪),那么就去 /taskList 下建立自己的临时时序节点(CreateMode.EPHEMERAL_SEQUENTIAL)。当 /taskList 发现自己下面的子节点满足指定个数,就可以进行下一步按序进行处理了。

使用 dokcer-compose 搭建集群

上面我们介绍了关于 ZooKeeper 有这么多的应用场景,那么接下来就先学习如何搭建 ZooKeeper 集群然后再进行实战上面的应用场景。
文件的目录结构如下:

├── docker-compose.yml

编写 docker-compose.yml 文件

docker-compose.yml 文件内容如下:

version: '3.4'services:zoo1:image: zookeeperrestart: alwayshostname: zoo1ports:- 2181:2181environment:ZOO_MY_ID: 1ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181zoo2:image: zookeeperrestart: alwayshostname: zoo2ports:- 2182:2181environment:ZOO_MY_ID: 2ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zoo3:2888:3888;2181zoo3:image: zookeeperrestart: alwayshostname: zoo3ports:- 2183:2181environment:ZOO_MY_ID: 3ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181

在这个配置文件中,Docker 运行了 3 个 Zookeeper 镜像,通过 ports 字段分别将本地的 2181, 2182, 2183 端口绑定到对应容器的 2181 端口上。

ZOO_MY_ID 和 ZOO_SERVERS 是搭建 Zookeeper 集群需要的两个环境变量。ZOO_MY_ID 标识服务的 id,为 1-255 之间的整数,必须在集群中唯一。ZOO_SERVERS 是集群中的主机列表。

在 docker-compose.yml 所在目录下执行 docker-compose up,可以看到启动的日志。

连接 ZooKeeper

将集群启动起来以后我们可以连接 ZooKeeper 对其进行节点的相关操作。
1.首先需要下载 ZooKeeper。

2.将其解压。

3.进入其 conf/ 目录,将 zoo_sample .cfg 改成 zoo.cfg。

配置文件说明

# The number of milliseconds of each tick
# tickTime:CS通信心跳数
# Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。tickTime以毫秒为单位。
tickTime=2000# The number of ticks that the initial
# synchronization phase can take
# initLimit:LF初始通信时限
# 集群中的follower服务器(F)与leader服务器(L)之间初始连接时能容忍的最多心跳数(tickTime的数量)。
initLimit=5# The number of ticks that can pass between
# sending a request and getting an acknowledgement
# syncLimit:LF同步通信时限
# 集群中的follower服务器与leader服务器之间请求和应答之间能容忍的最多心跳数(tickTime的数量)。
syncLimit=2# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# dataDir:数据文件目录
# Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。
dataDir=/data/soft/zookeeper-3.4.12/data# dataLogDir:日志文件目录
# Zookeeper保存日志文件的目录。
dataLogDir=/data/soft/zookeeper-3.4.12/logs# the port at which the clients will connect
# clientPort:客户端连接端口
# 客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1# 服务器名称与地址:集群信息(服务器编号,服务器地址,LF通信端口,选举端口)
# 这个配置项的书写格式比较特殊,规则如下:
# server.N=YYY:A:B
# 其中N表示服务器编号,YYY表示服务器的IP地址,A为LF通信端口,表示该服务器与集群中的leader交换的信息的端口。B为选举端口,表示选举新leader时服务器间相互通信的端口(当leader挂掉时,其余服务器会相互通信,选择出新的leader)。一般来说,集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。但是当所采用的为伪集群时,IP地址都一样,只能时A端口和B端口不一样。

可以不修改 zoo.cfg,使用默认配置。接下来在解压后的 bin/ 目录中执行命令 ./zkCli.sh -server 127.0.0.1:2181 就能进行连接了。

Welcome to ZooKeeper!
2020-06-01 15:03:52,512 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1025] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
JLine support is enabled
2020-06-01 15:03:52,576 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@879] - Socket connection established to localhost/127.0.0.1:2181, initiating session
2020-06-01 15:03:52,599 [myid:] - INFO  [main-SendThread(localhost:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x100001140080000, negotiated timeout = 30000
WATCHER::WatchedEvent state:SyncConnected type:None path:null
[zk: 127.0.0.1:2181(CONNECTED) 0]

接下来可以使用命令查看节点:
使用 ls 命令查看当前 ZooKeeper 中所包含的内容。命令:ls /

[zk: 127.0.0.1:2181(CONNECTED) 10] ls /
[zookeeper]

创建了一个新的 znode 节点 zk 以及与它关联的字符串。命令:create /zk myData

[zk: 127.0.0.1:2181(CONNECTED) 11] create /zk myData
Created /zk
[zk: 127.0.0.1:2181(CONNECTED) 12] ls /
[zk, zookeeper]
[zk: 127.0.0.1:2181(CONNECTED) 13]

获取 znode 节点 zk。命令:get /zk

[zk: 127.0.0.1:2181(CONNECTED) 13] get /zk
myData
cZxid = 0x400000008
ctime = Mon Jun 01 15:07:50 CST 2020
mZxid = 0x400000008
mtime = Mon Jun 01 15:07:50 CST 2020
pZxid = 0x400000008
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

删除 znode 节点 zk。命令:delete /zk

[zk: 127.0.0.1:2181(CONNECTED) 14] delete /zk
[zk: 127.0.0.1:2181(CONNECTED) 15] ls /
[zookeeper]

由于篇幅有限,在接下来的文章中会根据上面提到的 ZooKeeper 应用场景逐一进行用代码进行实现。
大家可以直接从 GitHub 拉取项目,启动只需要两步:
1.从 GitHub 上面拉取项目。
2.在 ZooKeeper 文件夹中执行 docker-compose up 命令。

大家可以直接从 GitHub 拉取项目,启动只需要两步:

1.从 GitHub 上面拉取项目。

2.在 ZooKeeper 文件夹中执行 docker-compose up 命令。

看到这里,是不是更加了解了呢,接下来我们说说ZooKeeper分布式事务详解

上面我们了解了zookeeper到底是什么,现在重点来看Zookeeper当初到底面临什么问题。
而Zookeeper又是如何解决这些问题的?
实际上Zookeeper主要就是解决分布式环境下的一致性问题。那么解决这个问题到底有哪些难点呢?我们一步一步来阐述和推理这个过程。

分布式事务

我们首先考虑一致性的特殊情况,即分布式事务的情况。分布式事务对于一致性的要求是强一致性,因此对于我们后续讨论有一定的借鉴意义。这里我们用到一个经典的例子:bob给smith转账,强一致性的要求一定是需要对外来说bob减钱的同时smith加钱。

单机环境下是这样的:

简单讲就是有关bob的减钱和smith的加钱都转同一个库来做,可以采用数据库的事务特性轻松支持。保证bob给smith转账的安全性。

而分布式环境就变这样了:

假设应用服务器是A,bob端的数据库是B,smith端的数据是C,那么A做成一个转账,需要B事务成功提交,并且C事务成功提交。然而因为网络的影响,可能出现两种情况

如果bob扣款成功,而网络通知smith失败了,则会出现bob的钱减了,smith的钱没加

如果bob扣款不成功,而smith加钱成功了,则会出现smith钱增加了,但是bob的钱也没减少

2PC

这种不一致的问题困扰着大家。任意一边出错想要回滚另一边都不是简单的数据库回滚的事情( 因为此时已经成功提交),而是需要做业务的逆向操作,而不同业务的逆操作都不同,导致复杂性增加。考虑数据库事务的执行实际上是先将执行操作写入binlog,等到最后通过一个commit指令将binlog的内容一次更新到表中,或者写到一半通过一个rollback指令将binlog中的内容回滚。于是乎,可以想到使用2个阶段来执行这个过程,第一阶段,写入binlog;第二阶段执行commit或者rollback。这就是著名的两阶段提交协议(2PC)。如果仔细考虑,会发现两阶段协议并没有解决问题,只不过降低了出错的概率而已,因为第二阶段同样存在上面的两种情况。注意最终状态是多台机器的状态&&的 结果。以下是两阶段协议的时序图:

1.考虑prepare阶段的响应(因为请求阶段和执行阶段都可以在最后响应中体现出来),对于分布式环境中,任意时刻考虑3种状态:成功、失败、超时。

a.成功。不必处理,执行后续行为commit。

b.失败。这是执行阶段出错,执行后续行为rollback。

c.超时。这可能是执行阶段太慢,也可能是网络阶段太慢或丢包,但是保守处理,超时可以当做出错。

可以看出,prepare阶段的问题能够完全避免。

2.考虑commit阶段,同样考虑成功失败超时3种状态。

a. 成功。整个事务成功执行。

b. 失败。提交出错,假设此时前面的B已经提交成功了,则同样面临需要回滚B却无法回滚的问题,因为B已经提交成功了。

c. 超时。同上。

还有一种例外情况,即prepare阶段完成后A挂了,则B,C即进入不知所措的状态。
可以看出,在2PC中事务无法做到像单机一样安全,只不过降低了出问题的概率。

3PC

针对如何解决2PC中的例外情况,出现了3阶段提交协议。3阶段的主要改进是把2阶段的prepare再分为canCommit和preCommit两个阶段。

1.考虑cancommit阶段的响应。

a.成功。不必处理,执行后续行为precommit。

b.失败。说明无法执行,无须后续提交或回滚行为。

c.超时。保守处理,超时可以当做失败。

2.考虑precommit阶段的响应。

a.成功。不必处理,执行后续行为docommit。

b.失败。执行阶段出错,执行后续行为rollback。

c.超时。执行阶段太慢,也可能是网络阶段太慢或丢包,但是保守处理,超时可以当做出错。

3.考虑cancommit阶段的响应。

a.成功。整个事务成功执行。

b.失败。提交出错,假设此时前面的B已经提交成功了,则同样面临无法回滚的问题。

c.超时。保守处理,超时可以当做失败。

例外情况,即自cancommit返回成功后的任意阶段A挂掉了,那么BC同样能够知道这个事务正在发生(因为cancommit已经提交了足够信息让BC知晓此事),于是BC可以在无A的情况下继续执行后续的阶段(比如BC投票启动新的A’,并提供A’足够信息)。于是3PC正好解决了2PC的例外情况。

但是3PC仍然存在类似2PC的问题,即最后阶段失败或超时同样有可能出现数据不一致的问题。所以3PC仍然只是降低了发生概率,并没有真正解决问题。

XTS

工业界的对分布式事务的应用是如何呢?可以参考某宝的知名分布式框架XTS。

XTS本质上是2PC(实际上如果引入3PC会多2n次网络交互,在量大时反而更加不安全)。XTS引入协调者A的server部分,实际上是一个大集群,以配置的方式接入各种需要分布式事务的业务,集群由专门的团队维护,保证其可用性和性能;而协调者A的client部分则通过发起方调用,prepare阶段时,先通过client将本次事务信息发送到server,落库,然后即时推送prepare请求到B和C,当收到B,C的响应时把他们状态入库,如果正常,则做commit提交;否则会用定时任务去推送未完成的状态直到完成。上文提到的prepare之后协调者A挂了这种情况,在server集群的保证下,几乎很少会发生。而上文提到的所有超时的情况,都可以通过定时任务推送拿到一个确定的状态而不是盲目的选择回滚或者提交。另外由于B和C都是集群,很少会发生多次请求过去无响应的情况。直到最后一种情况就是commit时B成功了C失败了,或者反过来B失败C成功,这种情况成为悬挂事务,最终等待人工来解决,据说每天都有几笔到几十笔。

无疑XTS作为2PC在工业界的应用,是相当了不起的设计,通过各种方式规避了各种可能的不一致性,在性能,效率等方面做到了平衡。

TCC(Try/Confirm/Cancel)

业务补偿类型,其基本思想是对每一个业务操作做一个逆操作,一旦成功了,就做正向业务,一旦失败了就做业务的逆操作。通常在业务逻辑简单并且正逆操作清晰的时候用比较好。

查询补偿

典型的场景是向银行发送了转账请求未得到明确的成功失败返回码,此时先做业务结果的查询,根据结果做相应处理,比如查询结果成功,则置状态为成功,查询结果失败,则做相应的业务补偿,查询结果为未知,则继续查询。

消息事务及消息重试

事务消息及消息重试本质上都是将一些通用的事务交给消息中间件,通过消息中间件来保证消息的最终一致性。

事实上,消息事务解决了这类问题,即本地事务和消息应当有一致性,解决这个一致性比较麻烦,比如消息中间件和业务同时实现XA;或者采用一些更加复杂的方式,比如将消息表与业务表放同库,利用数据库的事务来保证一致性,而消息系统只需要轮训该消息表即可;当然,也有消息的二阶段提交+补偿的方式。消息事务解决了消息发起方,即生产者与消息中间件之间的一致性问题。

try{  //数据库操作  //消息投递  }catch(Exception e){  //回滚  }

消息中间件与消费者之间的一致性问题则需要通过重试+幂等来解决。消息重试中主要考虑重试次数以及重试时间的阈值变化。

最后

我这边整理了一份:Zookeeper相关资料,Java核心知识点(包括Spring全家桶系列、面试专题和20年最新的互联网真题、电子书等)有需要的朋友可以点击这里获取资料。

什么是ZooKeeper?可以做什么?ZooKeeper分布式事务详解篇相关推荐

  1. 事务超时时间无效_什么是ZooKeeper?ZooKeeper分布式事务详解

    前言 zookeeper当初到底面临什么问题?而zookeeper又是如何解决这些问题的? 实际上zookeeper主要就是解决分布式环境下的一致性问题.那么解决这个问题到底有哪些难点呢?我们一步一步 ...

  2. 分布式事务详解(看完不懂我当场认做你哥)

    分布式事务 1 基础概念 1.1 什么是事务 什么是事务?举个生活中的例子:你去小卖铺买东西,"一手交钱,一手交货"就是一个事务的例子,交钱和交货必 须全部成功,事务才算成功,任一 ...

  3. 分布式事务详解【分布式事务的几种解决方案】彻底搞懂分布式事务

    文章目录 一.基本概念 什么是事务 本地事务 分布式事务 分布式事务产生的场景 二.分布式事务基础理论 CAP理论 CP - Consistency/Partition Tolerance AP - ...

  4. 分布式事务详解、理论分析、及强一致性(2PC、3PC)剖析

    一. 简介 1. 什么是本地事务? 基于关系型数据库的事务,叫做本地事务,也叫做数据库事务. 本地事务通常是应用和数据库在一个服务器上,利用数据库本身的事务特性,从而实现本地事务. 数据库事务的特性: ...

  5. 七种常见分布式事务详解(2PC、3PC、TCC、Saga、本地事务表、MQ事务消息、最大努力通知)

    分布式事务:在分布式系统中一次操作需要由多个服务协同完成,这种由不同的服务之间通过网络协同完成的事务称为分布式事务 一.2PC: 2PC,两阶段提交,将事务的提交过程分为资源准备和资源提交两个阶段,并 ...

  6. ShardingSphere分库分表核心原理精讲第十一节 分布式事务详解

    27 分布式事务:如何理解 ShardingSphere 中对分布式事务的抽象过程? 从今天开始,我们将进入一个全新模块,即ShardingSphere 分布式事务.这是一个非常重要的主题,我们将通过 ...

  7. ShardingShpere分库分表5-ShardingSphere分布式事务详解

    文章目录 一.ShardingJDBC分布式事务快速上手 LOCAL本地事务 XA事务快速上手 BASE柔性事务快速上手 seata部署方式: 客户端使用Base事务 二.分布式事务原理详解 XA事务 ...

  8. 【微服务入门】分布式事务详解及seata的使用

    一文读懂分布式事务 微服务中的分布式事务问题 1 分布式事务介绍 1.1 什么是事务 1.2 本地事务 1.3 什么是分布式事务 1.3.0 假如没有分布式事务 1.4 分布式事务系统架构 1.4.1 ...

  9. Java开发 - 不知道算不算详细的分布式事务详解

    前言 前日对JUC进行了一个深度总结,不过现在博主能记得的也不多了,只是这东西,不是看几遍写几遍就能完全记住的,功夫在平时,很多知识点都需要反复的看,不光要看,还要用,这样才能了解其原理,掌握其原理, ...

最新文章

  1. 【Netty】NIO 缓冲区 ( Buffer ) 分散 Scattering 与 聚合 Gathering 操作
  2. java设计模式3--单例模式(Singleton)
  3. 某银行省级数据中心IT运维服务体系建设完整思路
  4. Spring中类路径下文件读取方式
  5. php多态性和继承是什么意思,封装 继承 多态的区别
  6. php面试编程题_PHP程序员面试题(经典汇总,mysql为主)
  7. 如何选择最佳云托管服务提供商
  8. 树莓派3连接ps4无线手柄
  9. Tableau 网站流量分析案例汇总
  10. NVIDIA Jetson TK1学习与开发(四):一些细节问题
  11. css b加粗怎么用,CSS去掉b加粗和strong加粗标签样式.doc
  12. 无代码开发+MES管理系统双向奔赴,MES进化新方向
  13. python中pygame背景颜色为啥没生效_如何更改pygame中的背景图像?
  14. PDF文件如何另存为
  15. 求e的近似值 (15 分)
  16. 【学算法的辅助练习1】北大POJ2388:Who‘s in the Middle
  17. 无心剑英译李白诗32首
  18. java中什么是值传递
  19. 【读书笔记】《认知觉醒》- 周岭
  20. android全屏与非全屏切换时Toolbar的显示,仿微信漂流瓶效果

热门文章

  1. 【译】微软如何进行代码审查
  2. 如何将jpg图片做成gif?教你简单三步快速做gif
  3. t420i升级固态硬盘提升_科赋CRAS C710 M.2固态硬盘评测:经典再升级
  4. js数组转对象,对象转数组
  5. 师范英语和计算机哪个好,广西大学怎么样啊?桂林科大,广西师范大学 哪个大学比较好啊 ,比如说报考计算机专业 或者英语专业...
  6. SQL Server 视图创建点滴 (转http://www.cnblogs.com/fineboy/archive/2008/05/10/236731.html#1191527)...
  7. Android布局分析工具Layout Inspector(解决布局产生的性能问题)
  8. 利用Spiking神经网络进行基于脑电图的情绪分类
  9. 互动性可视化 打通大数据最后一公里
  10. 电子闹钟(atmega16)