ZooKeeper项目起源
ZooKeeper起源于Yahoo的研究项目。研究人员发现,Yahoo内部很多大型系统需要依赖一个系统进行分布式协调,但这些系统往往都存在分布式单点问题。因此Yahoo研究人员试图研发一套通用的、无单点问题的分布式协调框架,以便研发人员将精力集中在业务逻辑上。
分布式系统概述:
分布式系统是跨越多个物理机器,独立运行的多个软件系统所组成大系统。分布式系统就比如一群人一起干活。人多力量大,每个服务器的算力是有限的,但是通过分布式系统,由n个服务器组成起来的集群,算力是可以无限扩张的。
为什么需要引入ZooKeeper?
分布式系统需要一个主控、协调或控制程序来管理在物理上分布的子进程(如状态、资源分配等),集群中的系统需要开发自主的协调程序,缺乏通用框架。ZooKeeper最为主要的使用场景,是分布式系统的分布协同服务。
ZooKeeper是分布式服务框架,是Apache Hadoop一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
ZooKeeper特点
ZooKeeper 作为一个分布式服务框架,主要用来解决分布式集群中应用系统一致性问题,它提供类似于文件系统的目录节点树方式的存储数据。但是 ZooKeeper 并不是用来专门存储数据的,它的核心作用主要是用来维护和监控你存储的数据的状态变化。
简单来说ZooKeeper = 文件系统 + 监听通知机制。
ZooKeeper基本原理
ZooKeeper 从设计模式角度来看,是一种基于观察者模式的分布式服务框架。ZooKeeper可以被当做注册中心。ZooKeeper存储和管理系统中都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,ZooKeeper就将负责通知已经注册的观察者。
Watcher(事件监听器,观察者监听器)
Watcher 节点监听是ZooKeeper 中一个很重要的特性。ZooKeeper允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去。该机制是 ZooKeeper 实现分布式协调服务的重要特性。
ZooKeeper应用场景
ZooKeeper 是一种典型的分布式环境下数据一致性的解决方案。分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、分布式锁和分布式队列等功能。
数据发布与订阅(配置中心)
命名服务
分布式协调服务/通知
分布式锁
ZooKeeper应用场景-命名服务
分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称又便于人识别和记住,通常情况下用树形的名称结构是一个理想的选择,树形的名称结构是一个有层次的目录结构。命名服务是 ZooKeeper 内置的基本功能,调用ZooKeeper的create接口很容易创建一个目录节点。
ZooKeeper应用场景-配置管理
配置管理在分布式环境中很常见。
假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到ZooKeeper上去,保存在 ZooKeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 ZooKeeper 的通知,然后从 ZooKeeper 获取新的配置信息应用到系统中。
例子:例如一个应用系统需要多台PC服务器运行,但是它们运行的某些配置项是相同的,如果要修改这些配置项,那么就必须同时修改每台运行这个系统的PC服务器,非常麻烦且容易出错。
像这样的配置信息可交给ZooKeeper管理。配置信息保存在ZooKeeper某个目录节点中,然后所有需要修改的PC监控配置信息状态,一旦配置信息发生变化,每台PC都会收到 ZooKeeper的通知,然后从ZooKeeper获取新的配置信息到自己系统中。
ZooKeeper应用-集群管理
在ZooKeeper中,节点分为两类,第一类同样是指构成集群的机器,我们称之为机器节点;第二类则是指数据模型中的数据单元,我们称之为数据节点一一ZNode。
ZooKeeper允许分布式进程通过共享的层次结构命名空间进行相互协调,这与标准文件系统类似。
Zoopkeeper提供一套分布式集群管理机制,基于层次型目录树的数据结构,对树中的节点进行有效管理,进而可设计出多种多样的分布式数据管理模型,而不仅仅局限于上面提到的几个常用应用场景。
ZooKeeper部署
ZooKeeper配置简单,每个节点的配置文件(zoo.cfg)都是一样的,只有 myid 文件不同。myid 的值必须是 zoo.cfg中server.{数值} 的{数值}部分。
ZooKeeper单点故障(容错)
ZooKeeper是一个分布式系统,只要半数以上节点存活,ZooKeeper就能正常服务,具备高可用性。只要集群中大部分机器可用,那么ZooKeeper本身仍然可用,能容忍一定比例的单点机器故障。
ZooKeeper节点
ZooKeeper的结构是一种树形结构。
ZooKeeper节点有两种类型,临时(ephemeral)和持久(persistent)节点概念。
创建临时节点的客户端会话一直保持活动,临时节点就一直存在,而当会话终结时,临时节点被删除。临时节点的生命周期跟客户端会话绑定,一旦客户端会话失效,那么客户端创建的所有临时节点都会被移除。
持久节点是指一旦这个树形节点被创建,除非主动对节点进行移除操作,否则节点将一直保存在ZooKeeper系统中。
ZooKeeper有四种类型的ZooKeeper节点:
PERSISTENT-持久化目录节点
客户端与ZooKeeper断开连接后,该节点依旧存在。
PERSISTENT_SEQUENTIAL:持久化顺序编号目录节点。
客户端与ZooKeeper断开连接后,该节点依旧存在,只是ZooKeeper给该节点名称进行顺序编号。
EPHEMERAL-临时目录节点
客户端与ZooKeeper断开连接后,该节点被删除。
EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点。
客户端与ZooKeeper断开连接后,该节点被删除,只是ZooKeeper给该节点名称进行顺序编号。
节点操作:
在ZooKeeper中,能改变ZooKeeper服务器状态的操作称为事务操作。一般包括数据节点
创建与删除、数据内容更新和客户端会话创建与失效等操作。对应每一个事务请求,ZooKeeper都会为其分配一个全局唯一的事务ID,用 ZXID 表示,通常是一个64位的数字。每一个 ZXID对应一次更新操作,从这些 ZXID 中可以间接地识别出 ZooKeeper 处理这些事务操作请求的全局顺序。
ZooKeeper数据操作
ZooKeeper数据操作原子性,一次数据更新要么成功,要么失败。
每一个Server代表一个安装ZooKeeper服务的服务器。组成ZooKeeper服务的集群都会在内存中维护当前服务器状态,并且每台服务器之间都互相保持着通信。
会话(Session)
Session是ZooKeeper服务器与客户端会话,ZooKeeper中的Session通过客户端和服务器之间的TCP 长连接实现。
客户端对ZooKeeper集群发送的请求,需要先和ZooKeeper集群建立会话。客户端提交给ZooKeeper的所有操作均存活在一个会话中。当一个会话终止时,会话期间创建的临时节点将会消失。若当前服务器的问题,无法继续通信时,会话将被透明的转移到另外一台ZooKeeper集群的服务器上。
客户端启动的时候,会与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期开始。
通过这条TCP连接,客户端通过心跳检测与服务器保持有效的会话,向ZooKeeper服务器发送请求或接受响应,同时还能通过该连接接收来自服务器的Watch事件通知。
Session的sessionTimeout值用来设置一个客户端会话的超时时间。
当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端TCP断开时,只要在sessionTimeout规定时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。
在为客户端创建会话之前,服务端会为每个客户端都分配一个sessionID。
由于sessionID是ZooKeeper会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 。