zookeeper技术总结

概要

  • ZooKeeper概述
  • ZooKeeper的基本概念
  • ZooKeeper环境搭建(单机,伪集群,集群)

ZooKeeper概述

背景

    随着互联网技术的高速发展,企业对计算机系统的计算、存储能力要求越来越高,诸如高并发、海量存储这样的词汇耳熟能详。在这样的背景下,单纯依靠少量高性能主机计算能力已经满足不了企业快速增长的业务需求,系统架构逐步从集中式向分布式过渡。所谓的分布式是指:把一个计算任务分解成若干计算单元,并分派任务给不同的计算机去执行,再汇总各个机器的结果的过程。这个思想可能比较抽象,但是学过多线程的同学就相对比较容易理解分布式原理,比如:多线程从数据库读数据,各线程分别把自己负责的数据块写入子文件,再把子文件合并到最终文件,这个过程和分布式是一个道理,只不过一个是单机,一个是集群而已。

    分布式系统中,怎么组织这么多计算机协同完成一个相对复杂耗时的计算任务,或者通俗一点说就是一个复杂的实际业务流程。比如一个公司有了新的任务,需要一个主管负责人带领团队来完成,那么这个主管需要做一个统筹规划组织各个部门员工分,各自完成自己的任务。其间主管会把控每个人的进度,协调资源来保证任务高效进行下去,最后将任务汇总出结果,任务完成。这个过程避免不了人事变动、员工离职,尤其是这个主管负责人不能再继续领导团队,这时公司内部就要选举一位新的领导来接替他的工作,直到完成任务。那么类似这种分工协调的工作机制,就是ZooKeeper在分布式系统中所起到的作用。

ZooKeeper是什么

ZooKeeper是源代码开放的分布式协调服务,由雅虎公司创建,是Google Chubby(主要解决分布式锁相关问题)的开源实现。ZooKeeper是一个高性能的分布式一致性解决方案,它将那些复杂的、容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并提供一系列简单易用的接口给用户使用。

具有以下特点:

1、源代码开放
    免费试用、代码开源,可以深入到代码层面学习ZooKeeper,甚至可以自己的业务修改代码,定制功能来扩展ZooKeeper
2、是分布式协调服务,它解决分布式数据一致性问题
    A:顺序一致性
         客户端发起的请求会严格的按顺序应用到ZooKeeper里。
    B:原子性
        所有事务请求的处理结果在整个ZooKeeper集群里的所有机器的执行结果都是一致的
    C:单一视图
        客户端无论连接的是ZooKeeper集群的那个服务器,所看到的结果都是一致的
    D:可靠性
        ZooKeeper服务端一旦执行了一个事务并完成了对客户端的响应,那么服务端的状态变更就会永久的保留下来,直到处理下一次事务才会发生变化
    E:实时性
        ZooKeeper可以保证一段时间内客户端一定可以从服务端读取到最新的数据状态
3、高性能
    具有很高的吞吐量,三台服务器的ZooKeeper集群可以处理12~13万qps级别的请求压力
4、我们可以通过调用ZooKeeper提供的接口来解决分布式应用中的实际问题

ZooKeeper的典型应用场景

1、数据发布/订阅
    数据发布/订阅就是一方把数据发布出来,另一方通过某种手段可以得到这些数据。
    通常数据订阅有两种方式:推模式和拉模式,推模式是服务器主动向客户端推送消息,拉模式是客户端主动去服务器获取数据(通常采用定时轮询的方式)。
    zk采用两种方式相结合的方式。发布者者将数据发布到zk集群节点上,订阅者通过一定的方法告诉服务器,我对哪个节点数据感兴趣,那服务器在这些节点的数据发生变化时,通知客户端,客户端得到通知后可以去服务器获取数据信息。

2、负载均衡
    首先DB在启动的时候先把自己在zk上注册成一个临时节点,zk的节点在以后讲到会有两种:永久节点、临时节点。 临时节点是在服务器出现问题的时候,节点会会被zk删除,这样就保证了zk上的服务器列表是最新的可用列表
    客户端在需要读写数据库的时候首先去zk得到所有可用DB的连接信息(一张列表)
    客户端随机选择一个DB与之建立连接
    当客户端发现连接不可用的时候可再次从zk上获得可用的DB连接信息,当然也可以在刚获得的那个列表里移除掉不可用的连接后再随机选择一个DB与之建立连接。
    这样可以保证客户端随机的去选择DB读写,单个DB处理请求的压力会减小很多,zk从中就起到了负载均衡的作用。

3、命名服务
    顾名思义,就是提供名称的服务,例如数据表ID,一般用的比较多的有两种ID,一种是自动增长的ID,一种是UUID(9291d71a-0354-4de8-acd8-64f739c64ae),两种ID各自都是有缺陷的,自动增长ID局限在单库单表中使用,不能在分布式中使用,UUID可以在分布式中使用但是由于ID没有规律难于理解不好使用,我们可以借助zk来生成一个顺序增长的,可以在集群环境下使用的,命名易于理解的ID

4、分布式协调/通知
    心跳检测
    在分布式系统中,我们常常需要知道某个机器是否可用,传统的开发中,可以通过ping某个主机来实现,ping得通说明对方是可用的,相反是不可用的,zk中我们让所有的机器都注册一个临时节点,我们判断一个机器是否可用,我们只需要判断这个节点在zk中是否存在就可以了,不需要直接去连接需要检查的机器,降低系统的复杂度

ZooKeeper的优势

    1、源代码开放
    2、已经被证实是高性能,易用稳定的工业级产品
    3、有着广泛的应用:Hadoop、HBase、Storm、Solr

 
   

ZooKeeper 基本概念

集群角色

Leader、Follower、Observer

Leader服务器是整个ZooKeeper集群工作机制中的核心
Follower服务器是ZooKeeper集群状态的跟随者
Observer服务器充当一个观察者的角色

Leader/Follower 设计模式
Observer 观察者设计模式

会话

会话是指客户端和ZooKeeper服务器的链接,ZooKeeper中的会话叫Session,客户端靠与服务器建立一个TCP的长连接来维持一个Session,客户端在启动的时候首先会与服务器建立一个TCP连接,通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能向zk服务器发送请求并获得响应。

数据节点

ZooKeeper中的节点有两类
1、集群中的一台机器称为一个节点
2、数据模型中的数据单元Znode,分为持久节点和临时节点
ZooKeeper的数据模型是一颗树(文件目录结构),树的节点就是Znode,Znode中可以保存信息
我们看下图

其实大多数的ZooKeeper开发是和这些数据节点打交道,来读写数据节点,完成任务

版本

如图:
版本类型 说明
version 当前数据节点数据内容的版本号
cversion 当前数据节点子节点的版本号
aversion 当前数据节点ACL变更版本号
悲观锁和乐观锁    
悲观锁又叫悲观并发锁,是数据库中一种非常严格的锁策略,具有强烈的排他性,能够避免不同事务对统一数据并发更新造成的数据不一致,在上一个事务没有完成之前,下一个事务不能访问相同的资源,适合数据更新竞争非常激烈的场景
    相比悲观锁,乐观锁的使用场景更多,悲观锁认为事务访问相同数据的时候一定会出现相互干扰,所以简单粗暴的使用排他访问的方式,而乐观锁认为不同的事务访问相同资源是很少出现相互干扰的情况,因此在事务处理期间不需要进行并发控制,当然乐观锁也是锁,它还是会有并发的控制!对于数据库我们通常的做法是在每个表中加一个version版本字段,事务修改数据之前先读出数据,当然版本号也顺势读取出来,update xx表 set xx字段 = xx值, version = 2 where id = 1 and version = 1,那如果更新失败了说明以后其他事务已经修改过数据了,那系统需要抛出异常给客户端,让客户端自行处理,客户端可以选择重试

watcher

事件监听器
    ZooKeeper允许客户端用户在指定节点上注册一些Watcher,当数据节点发生变化的时候,ZooKeeper会把这个变化的通知发送给感兴趣的客户端。

如图:

ACL权限控制

ACL是Access Controller Lists(访问控制列表)的简写,ZooKeeper采用ACL策略来进行权限控制,有以下权限:
    CREATE:创建节点数据和子节点列表的权限
    READ:获取节点数据和子节点列表的权限
    WRITE:更新节点数据的权限
    DELETE:删除子节点的权限
    ADMIN:设置节点ACL的权限

ZooKeeper 环境搭建

如果是集群就要启动三个虚拟机,并分别在虚拟机里安装三个Linux系统。Linux系统里分别做如下操作:
1、下载ZooKeeper [zookeeper-3.4.10](http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.10/)
2、解压复制到 /opt/zookeeper 里
    伪集群搭建,复制出三分ZooKeeper
3、修改zoo.cfg
    如果是伪集群搭建,只需要一台机器就可以,第3步修改zoo.cfg文件里的三个服务ip用相同的本机ip、不同的Follower port和Observer port就ok了,但dataDir要配置成不同路径。下面是伪集群配置
tickTime=2000

initLimit=10

syncLimit=5

dataDir=/var/zookeeper1

clientPort=2181
#配置集群时,由于在不同的服务器,只需保持ip不同就行
#server.1=ip1:2888:3888
#server.2=ip2:2888:3888
#server.3=ip3:2888:3888

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
tickTime=2000

initLimit=10

syncLimit=5

dataDir=/var/zookeeper2

clientPort=2182

#配置集群时,由于在不同的服务器,只需保持ip不同就行
#server.1=ip1:2888:3888
#server.2=ip2:2888:3888
#server.3=ip3:2888:3888

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
tickTime=2000

initLimit=10

syncLimit=5

dataDir=/var/zookeeper3/

clientPort=2183

#配置集群时,由于在不同的服务器,只需保持ip不同就行
#server.1=ip1:2888:3888
#server.2=ip2:2888:3888
#server.3=ip3:2888:3888

server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
单机配置文件可以不用修改

也可以参照 http://blog.csdn.net/shirdrn/article/details/7183503 来配置


你可能感兴趣的:(zookeeper)