2019 年 03 月 - 10 文章

ZooKeeper源码分析(四) - Leader选举

  |   0 评论   |   0 浏览

前面几篇文章讲了服务器启动的流程,对于选举过程是一笔带过,这篇文章主要讲述Leader选举的实现细节。 Leader 选举是ZooKeeper中最重要的技术之一,也是保证分布式数据一致性的关键所在。我们从选举算法概述、服务器启动Leader选举、服务器运行期间Leader选举三个方面探讨实现细节。 1. 选举算法概述 服务器启动期间Leader选举 选举的条件是集群中至少有两台机器。主要流程如下: 每个server发出一个投票 接收各个服务器的投票消息 处理投票 统计投票 改变服务器状态 服务器运行期间的Leader选举 ZooKeeper集群在正常运行过程中,是不会进行leader选举过程的,只有当Leader机器挂掉之后,才会进行新一轮的Leader选举。选举过程和服务器启动期间Leader选举是一致的。 变更状态 每个server发出一个投票 接收来自各个服务器的投票 处理投票 统计投票 改变服务器状态 QuorumPeer.OrderState定义了服务器的四种状态,分表是: LOOKING: 寻找Leader状态,服务器处于该状态时,表示集群中没有leader,需要进入lea....

CentOS 7下 Docker容器安装

  |   0 评论   |   0 浏览
  1. 环境检查 1. 1 前提条件 目前,CentOS 仅发行版本中的内核支持 Docker。 Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。 Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。 1.2. 系统版本检查 通过uname -r查看当前系统内核版本,我的机器内核版本如下: [root@iZ94ixkobxaZ ~]# uname -r 3.10.0-514.21.1.el7.x86_64 2. yum安装(CentOS 7) 2.1. 旧版本移除(可选) sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux ....

ZooKeeper源码分析(三)—服务端启动之单机模式

  |   0 评论   |   0 浏览
  1. 预启动 1.1. QuorumPeerMain作为启动入口 跟集群模式一样,启动入口也是在 QuorumPeerMainmain方法中。 1.2. 解析配置文件 zoo.cfg 配置文件包含了zk运行时需要的基本参数,比如tickTime、dataDir和clientPort。解析的主要逻辑如下: try { File configFile = (new VerifyingFileFactory.Builder(LOG) .warnForRelativePath() .failForNonExistingPath() .build()).create(path); Properties cfg = new Properties(); FileInputStream in = new FileInputStream(configFile); try { // 文件加载 cfg.load(in); configFileStr = path; } finally { in.close(); } // 解析配置文件 parseProperties(cfg); } catch (IOExc....

ZooKeeper源码分析(二)—服务端启动之集群模式

  |   0 评论   |   0 浏览
  1. 启动入口 ZooKeeper服务端启动入口在 QuorumPeerMain这个类中,主要逻辑在 initializeAndRun方法中。主要逻辑为: 解析zk配置(console 是否输入了配置文件名称) 启动负责清理工作的schedule(利用Java Timer实现的定时任务,清理过期文件快照) 启动过程(根据配置信息判断走集群模式还是单机模式) 1.1 解析zoo.cfg文件 try { File configFile = (new VerifyingFileFactory.Builder(LOG) .warnForRelativePath() .failForNonExistingPath() .build()).create(path); Properties cfg = new Properties(); FileInputStream in = new FileInputStream(configFile); try { // 加载文件 cfg.load(in); configFileStr = path; } finally { in.close(); } // ....

ZooKeeper源码分析(一)—会话创建之客户端

  |   0 评论   |   0 浏览

开发人员主要使用zk的客户端,所以我们先来了解zk客户端的创建过程原理。 1. 概述 zk客户端的核心组件如下: ZooKeeper实例 :客户端入口 ClientWatcherManager :客户端Watcher管理器 HostProvider:客户端地址列表管理器 ClientCnxn:客户端核心线程。包含两个线程,即SendThread和EventThread。前者是一个I/O线程,主要负责ZooKeeper客户端和服务端之间的网络I/O通信,后者是一个事件线程,主要负责对服务端事件进行处理。 类图说明: ZooKeeper客户端的初始化与启动环节,实际上就是ZooKeeper对象的实例化过程,分析一个zk客户端的构造方法: public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolean canBeReadOnly, HostProvider aHostProvider, ZKClientConfi....

Zookeeper应用场景之分布式队列

  |   0 评论   |   0 浏览

业界存在不少消息中间件产品,实现各不相同。这篇文章主要介绍基于ZooKeeper实现的分布式队列。分布式队列,简单来说分为两大类,一种是常规的先入先出队列,另一种是要等到所有元素集聚之后才能统一安排执行的Barrier模型。 1. FIFO:先入先出 FIFO队列是一种非常典型的按序执行的队列模型:先进入队列的请求操作完成后,才会开始处理后面的请求。 使用zk实现FIFO队列,和zk对于共享锁的实现类似。FIFO队列就类似于一个全局的共享锁模型。所有客户端都会到一个节点(比如queue_fifo)下创建一个临时顺序节点。 创建完节点,根据如下四个步骤确定执行顺序。 1.通过调用getChildren() 接口来获取 /queue_fifo节点下的所有子节点,即获取队列中的所有元素。 2.确定自己的节点序号在所有子节点中的顺序 3.如果自己不是序号最小的子节点,那么就需要进入等待,同时向比自己序号小的最后一个节点注册Watcher监听 4.接收到Watcher通知后,重复步骤1 整个通过流程如下图所示: 2. Barrier:分布式屏障 Barrier在分布式系统中特指系统之间的一个协....

Zookeeper应用场景之分布式锁

  |   0 评论   |   0 浏览

本文章先概述一下zk的主要应用场景,然后重点讲述其分布式锁的实现。 1.应用场景概述 1.1.数据发布/订阅 数据发布/订阅系统,即所谓的配置中心。意思就是发布者将数据发布到zk的n个节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理和数据的动态更新。 1.2.负载均衡 zk作为路由,client从zk那里拿到可用的server地址(最好做个缓存),通过自己的负载均衡算法得到要连接的地址,client去连接指定server。server要做的是,当server启动后去zk注册自己(创建临时文件),子节点变化时(比如当某台server宕机),server与zk的链接会断掉,zk会自动删除该临时文件。 1.3.命名服务 命名服务是分布式系统中最基本的公共服务之一。要命名的对象包括集群中的机器列表,服务名称等。zk实现命名服务的方式:通过调用zk节点创建的API接口创建一个顺序节点,并且在API返回值中返回这个节点的完整名字。 1.4.分布式协调/通知 zk中特有的Watcher注册与异步通知机制,能够很好的实现分布式环境下不同机器,甚至是不同系统之间的协调与....

ZooKeeper之ZAB协议详解

  |   0 评论   |   0 浏览
  1. 协议概述 ZAB协议是为分布式协调服务zk专门设计的一种支持崩溃恢复的原子广播协议,在协议设计之初并没有要求其具有很好的扩展性,最初只是为雅虎公司内部哪些高吞吐量、低延迟、健壮、简单的分布式系统场景设计的。zk文档中也指出,ZAB协议并不像Paxos算法那样,是一种通用的分布式一致性算法,它是一种特别为zk设计的崩溃可恢复的原子消息广播算法 zk中,主要依赖ZAB协议来实现分布式数据一致性,基于该协议,zk实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。具体实现是: zk使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用ZAB的原子广播协议,将服务器数据的状态变更以事务的形式广播到所有的副本进程上去。ZAB协议的这个主备模型架构保证了同一时刻集群中只能有一个主进程来广播服务器的状态变更,因此能够很好地处理客户端的大量的并发请求。另外,考虑到在分布式环境中,顺序执行的一些状态变更其前后存在一定的依赖关系,有些状态变更必须依赖于比它早生成的那些状态变更,例如变更C需要依赖变更A和变更B。这样的依赖关系也对ZAB协议提出了一个要求:ZAB协议必须能够保证一个全....

ZooKeeper之基本概念

  |   0 评论   |   0 浏览
  1. 来源 Apache ZooKeeper由Apache Hadoop的子项目发展而来,为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名服务,配置管理和分布式锁等分布式的基础服务。由雅虎创建,是Google Chubby的开源实现。在解决分布式数据一致性方面,并没有采用Paxos算法,而是采用了ZAB(ZooKeeper Atomic Broadcase)的一致性协议 2. 特性 顺序一致性 从同一客户端发起的请求,之中将会严格的按照其发起的顺序被应用到ZooKeeper中去 原子性 所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的。 单一视图 无论客户端连接的是哪个ZooKeeper服务器,其看到的服务端数据模型都是一致的 可靠性 一旦服务端成功的应用了一个事务,并完成了对客户端的响应,那么该事务所引起的服务端状态变更将会被一直保留下来,除非有另一个事务又对其进行了变更 实时性 ZooKeeper能保证在一定的时间段内,客户端最终一定能够从服务端上读取到最新的数据状态,并不能保证实时的 3. 设计目标 ZooKeeper致力于提供一个高性能、高可用,且....

分布式一致性协议-Paxos详解

  |   0 评论   |   0 浏览

paxos算法是莱利斯·兰伯特于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。是目前公认的解决分布式一致性问题最有效的算法之一。在常见的分布式系统中,总会发生机器宕机或者网络异常等情况。paxos算法就是要解决就是如果在一个会发生上述异常的分布式系统中,快速且正确的在集群内部对某个数据的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。 1. 历史故事 1982年,lamport与另外两人共同发表了论文The Byzantine Generals Problem,提出了一种计算机容错理论。在理论描述过程中,为了能更加形象的表达,lamport设想了下面一种场景: 拜占庭帝国有多支军队,不同军队的将军之间要指定统一的行动计划,从而选择做出进攻或者撤退的决定,同时,各个将军在地理上都是被隔离开来的,只能依靠军队的通讯员进行通信。然而在所有的通讯员中可能会存在叛徒,这些叛徒可以任意篡改消息,从而达到欺骗将军的目的。 这就是著名的拜占庭将军问题,从理论上来说,在分布式计算领域,试图在异步系统和不可靠的信道上达成一致状态是不可能的,所以在研究的过程中,往往假....