CAP 理论
1、 一致性(Consistency )(C) ):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)2、 可用性(Availability )(A) ):在集群中一部分节点故障后,在一定时间内,集群整体是否 还能响应客户端的读写请求。(对数据更新具备高可用性)
3、 分区容错 性(Partition tolerance )(P) ):以实际效果而言,分区相当于对通信的时限要求。 系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在 C 和 A 之间做出选择。
ACID:
Automaticy 原子性
Consistency 一致性
Isolation 隔离性
Durability 持久性
CAP:
Consistency 最终一致性
Availability 可用性
Partition tolerance 分区容错性
BASE:
Basically Available 基本可用
Soft state 软状态
Eventually consistent 最终一致性
分布式事务:
2PC:Two-Phase Commit
阶段一:提交事务请求
阶段二:执行事务请求
3PC:Three-Phase Commit
阶段一:CanCommit
阶段二:PreCommit
阶段三:DoCommit
定理: 任何分布式 存储 系统只可同时满足二点,没法三者兼顾。
忠告:架构师不要将精力浪费在如何设计能满足三者的完美分布式系统,而是应该进行取舍。
原因总的来说就是:数据存在的节点越多,分区容错性(P)越高,但要复制更新的数据就越多,一致性(C)就越难保证。为了保证一致性,更新所有节点数据所需要的时间就越长,可用性(A)就会降低。
MySQL:满足 CA
ZooKeeper:满足 CP
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby一个开源的实现。它提供了简单原始的功能,分布式应用可以基于它实现更高级的服务,比如分布式同步,配置管理,集群管理,命名管理,队列管理。它被设计为易于编程,使用文件系统目录树作为数据模型。服务端跑在 java 上,提供 java 和 C 的客户端 API。
ZooKeeper 的命名空间就是 ZooKeeper 应用的文件系统,它和 linux 的文件系统很像,也是树状,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作。与linux文件系统不同的是,linux文件系统有目录和文件的区别,而ZooKeeper统一叫做znode,一个 znode 节点可以包含子 znode,同时也可以包含数据。znode 即是文件夹又是文件的概念,所以在 ZooKeeper 这里面就不叫文件文件也不叫文件夹,叫znode,每个znode有唯一的路径标识,既能存储数据,也能创建子znode。但是 znode 只适合存储非常小量的数据,不能超过 1M,最好小于 1K。
1、Znode 有两种类型:
短暂(ephemeral)(断开连接自己删除)
持久(persistent)(断开连接不删除)
2、Znode 有四种形式的目录节点(默认是 persistent )
PERSISTENT:持久化 znode 节点,一旦创建这个 znode 点存储的数据不会主动消失,除非是客户端主动的 delete。
PERSISTENT_SEQUENTIAL:自动增加顺序编号的 znode 节点,比如 ClientA 去 zk service 上建立一个 znode 名字叫做/zk/conf,指定了这种类型的节点后zk会创建/zk/conf0000000000,ClientB 再 去 创 建 就 是 创 建/zk/conf0000000001,ClientC 是创建/zk/conf0000000002,以后任意 Client 来创建这个 znode 都会得到一个比当前 zk 命名空间最大 znode 编号+1 的 znode,也就说任意一个 Client 去创建 znode都是保证得到的 znode 是递增的,而且是唯一的。
EPHEMERAL:临时 znode 节点,Client 连接到 zk service 的时候会建立一个session,之后用这个 zk 连接实例创建该类型的 znode,一旦 Client关闭了 zk 的连接,服务器就会清除 session,然后这个 session建立的 znode节点都会从命名空间消失。总结就是,这个类型的znode 的生命周期是和 Client 建立的连接一样的。比如 ClientA创建了一个 EPHEMERAL 的/zk/conf0000000011 的 znode 节点,一旦 ClientA 的 zk 连接关闭,这个 znode 节点就会消失。整个 zk service 命名空间里就会删除这个 znode 节点。
EPHEMERAL_SEQUENTIAL:临时自动编号节点,znode 节点编号会自动增加,但是会随session 消失而消失。
3、创建 znode 时设置顺序标识,znode 名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护。
4、在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序。
5、EPHEMERAL 类型的节点不能有子节点。
6、客户端可以在 znode 上设置监听器。
监听机制
客户端注册监听它关心的目录节点,当目录节点发生变化( 数据改变、 节点 删除、 子目录节点增加删除)时,ZooKeeper 会通知客户端。监听机制保证 ZooKeeper 保存的任何的数据的任何改变都能快速的响应到监听了该节点的应用程序。
监听器的工作机制,其实是在客户端会专门创建一个监听线程,在本机的一个端口上等待zk 集群发送过来事件。
监听只生效一次!
监听只生效一次!
监听只生效一次!
具体请看 ZooKeeper Shell 和 API 应用时的使用。
监听工作原理:
ZooKeeper 的 Watcher 机制主要包括:客户端线程、客户端 WatcherManager、Zookeeper服务器三部分。客户端在向 ZooKeeper 服务器注册的同时,会将 Watcher 对象存储在客户端的WatcherManager 当中。当 ZooKeeper 服务器触发 Watcher 事件后,会向客户端发送通知,客户端线程从 WatcherManager 中取出对应的 Watcher 对象来执行回调逻辑。
ZooKeeper 特点/设计目的
ZooKeeper 作为一个集群提供数据一致的协调服务,最好的方式就是在整个集群中的各服务节点进行数据的复制和同步。
数据复制的好处:
1、容错:一个节点出错,不至于让整个集群无法提供服务。
2、扩展性:通过增加服务器节点能提高 ZooKeeper 系统的负载能力,把负载分布到多个节点上。
3、高性能:客户端可访问本地 ZooKeeper 节点或者访问就近的节点,依次提高用户的访问速度。
从客户端读写访问的透明度来看,数据复制集群系统分下面两种:
1、写主:对数据修改的请求提交给主节点,对读数据请求没有限制,任何节点都能响应。
1 、最终一致性:client 不论连接到哪个 Server,展示给它都是同一个视图,这是 ZooKeeper最重要的性能。
2 、可靠性:具有简单、健壮、良好的性能,如果消息 m 被到一台服务器接受,那么它将被所有的服务器接受。
3 、实时性:ZooKeeper 保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,ZooKeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用 sync()接口。
4 、等待无关(wait-free) ):慢的或者失效的 client 不得干预快速的 client 的请求,使得每个client 都能有效的等待。
5 、原子性:更新只能成功或者失败,没有中间状态。
6 、顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息 a 在消息 b前发布,则在所有 Server 上消息 a 都将在消息 b 前被发布;偏序是指如果一个消息 b 在消息 a 后被同一个发送者发布,a 必将排在 b 前面。