zookeeper的灵魂37问

1 大数据的4V特征
  • 数据量大(volume);
  • 速度快(velocity),增长速度快,处理速度快;
  • 多样性(种类多(variety),有结构化,非结构化,半结构化);
  • 价值密度低(value)
2 什么是集群

一组计算机,它们作为一个整体向用户提供一组网络资源,这些单个的计算机系统就是集群的节点(node)。

3 集群的特性
  • (一) 可扩展性。

    • 集群的性能不限于单一的服务实体,新的服务实体可以动态的加入到集群,从而增强集群的性能。
  • (二) 高可用性。

    • 集群通过服务实体冗余使客户端免于轻易遭遇到“out of service”警告。当一台节点服务器发生故障的时候,这台服务器上所运行的应用程序将在另一节点服务器上被自动接管。消除单点故障对于增强数据可用性、可达性和可靠性是非常重要的。
  • (三) 负载均衡。

    • 负载均衡能把任务比较均匀的分布到集群环境下的计算和网络资源,以便提高数据吞吐量。
  • (四) 错误恢复。

    • 如果集群中的某一台服务器由于故障或者维护需要而无法使用,资源和应用程序将转移到可用的集群节点上。这种由于某个节点中的资源不能工作,另一个可用节点中的资源能够透明的接管并继续完成任务的过程叫做错误恢复。
4 分布式与集群的联系与区别
  • (一) 分布式是指将不同的业务分布在不同的地方。

  • (二) 而集群指的是将几台服务器集中在一起,实现同一业务。

  • (三) 分布式的每一个节点,都可以做集群,而集群并不一定就是分布式的。

    • 而分布式,从狭义上理解,也与集群差不多,但是它的组织比较松散
    • 不像集群,有一定组织性,一台服务器宕了,其他的服务器可以顶上来。
    • 分布式的每一个节点,都完成不同的业务,一个节点宕了,这个业务就不可访问了。
5 集群的类别
  • HA:高可用集群(High Availability Cluster)。
  • LBC:负载均衡集群/负载均衡系统(Load Balance Cluster)
  • HPC:科学计算集群(High Performance Computing Cluster)/高性能计算(High Performance Computing)集群。
6 zookeeper是什么
  • ZooKeeper是一个分布式应用程序协调服务的开源框架

  • 主要用来解决分布式集群中应用系统的一致性问题,例如怎样避免同时操作同一数据造成脏读的问题。

  • ZooKeeper 本质上是一个分布式的小文件存储系统。

    • 提供基于类似于文件系统的目录树方式的数据存储,并且可以对树中的节点进行有效管理。
    • 从而用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。
7 zookeeper的应用场景
  • 统一命名服务(dubbo)
  • 分布式配置管理(solr的配置集中管理)
  • 分布式消息队列(sub/pub)
  • 分布式锁
  • 分布式协调等功能。
8 简述zookeeper的架构
  • Leader:Zookeeper 集群工作的核心

    • 事务请求(写操作) 的唯一调度和处理者,保证集群事务处理的顺序性;
    • 集群内部各个服务器的调度者。
    • 对于 create, setData, delete 等有写操作的请求,则需要统一转发给leader 处理, leader 需要决定编号、执行操作,这个过程称为一个事务。
  • Follower:

    • 处理客户端非事务(读操作) 请求,
    • 转发事务请求给 Leader;
    • 参与集群 Leader 选举,投票 2n+1台可以做集群投票。
    • 此外,针对访问量比较大的 zookeeper 集群, 还可新增观察者角色。
  • Observer:观察者角色

    • 观察 Zookeeper 集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给 Leader服务器进行处理。
    • 不会参与任何形式的投票只提供非事务服务,通常用于在不影响集群事务
    • 处理能力的前提下提升集群的非事务处理能力。
9 zookeeper的数据模型与文件系统目录树的区别
  • ZooKeeper 的数据模型,在结构上和标准文件系统的非常相似

    • 拥有一个层次的命名空间,都是采用树形层次结构
    • ZooKeeper 树中的每个节点被称为Znode。
    • 和文件系统的目录树一样,ZooKeeper 树中的每个节点可以拥有子节点。
  • 但也有不同之处:

    • Znode 兼具文件和目录两种特点。

      • 既像文件一样维护着数据、元信息、ACL、 时间戳等数据结构
      • 又像目录一样可以作为路径标识的一部分,并可以具有子Znode。
      • 用户对 Znode 具有增、删、改、查等操作(权限允许的情况下)。
    • Znode 具有原子性操作

      • 读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。
      • 另外,每一个节点都拥有自己的 ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。
    • Znode 存储数据大小有限制。

      • ZooKeeper 虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储
      • 相反的是,它用来管理调度数据,
      • 比如分布式应用中的配置文件信息、状态信息、汇集位置等等。
      • 这些数据的 共同特性就是它们都是很小的数据,通常以 KB 为大小单位。
      • ZooKeeper 的服 务器和客户端都被设计为严格检查并限制每个 Znode 的数据大小至多 1M,常规使用中应该远小于此值。
    • Znode 通过路径引用,如同 Unix 中的文件路径。

      • 路径必须是绝对的,因此他们必须由斜杠字符来开头。
      • 除此以外,他们必须是唯一的,也就是说每一个 路径只有一个表示,因此这些路径不能改变。
      • 在 ZooKeeper 中,路径由 Unicode 字符串组成,并且有一些限制。
      • 字符串"/zookeeper"用以保存管理 信息,比如关键配额信息。
10 为什么将znode的存储数据设置为1M这么少
  • 它是用来管理调度数据的

    • 比如分布式应用中的配置文件信息、状态信息、汇集位置等等。
    • 这些数据的 共同特性就是它们都是很小的数据,通常以 KB 为大小单位
  • 所以不需要设置太大的数据存储单位

11 简述znode数据结构的组成

每个节点称为一个 Znode,由 3 部分组成:

① stat:此为状态信息, 描述该 Znode 的版本, 权限等信息

② data:与该 Znode 关联的数据

③ children:该 Znode 下的子节点

12 znode的节点类型
  • Znode 有两种,分别为临时节点和永久节点。

    • 节点的类型在创建时即被确定,并且不能改变。
  • EPHEMERAL:临时节点:该节点的生命周期依赖于创建它们的会话。

    • 一旦会话结束,临时节点将被自动删除,当然可以也可以手动删除。
    • 临时节点不允许拥有子节点。
  • PERSISTENT:永久节点:该节点的生命周期不依赖于会话

    • 并且只有在客户端显示执行删除操作的时候,他们才能被删除。
  • Znode 还有一个序列化的特性

    • 如果创建的时候指定的话,该 Znode 的名字后面会自动追加一个不断增加的序列号。
    • 序列号对于此节点的父节点来说是唯一的,这样便会记录每个子节点创建的先后顺序。
    • 它的格式为“%10d”(10 位数字,没有数值的数位用 0 补充,例如“0000000001”)。
  • 以序列化创建的永久节点是PERSISTENT_SEQUENTIAL:永久节点、序列化

  • 以序列化创建的临时节点是EPHEMERAL_SEQUENTIAL:临时节点、序列化

13 zookeeper的特点

1)Zookeeper:一个领导者(leader),多个跟随者(follower)组成的集群。

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

3)Follower用于接收客户请求并向客户端返回结果,在选举Leader过程中参与投票

4)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。

5)全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的。

6)更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行。

7)数据更新原子性,一次数据更新要么成功,要么失败。

8)实时性,在一定时间范围内,client能读到最新数据。

14 简述zookeeper的选举机制并举例说明选举的过程
  • 1)半数机制:集群中半数以上机器存活,集群可用。

    • 所以zookeeper适合装在奇数台机器上。
  • 2)Zookeeper虽然在配置文件中并没有指定master和slave。

    • 但是,zookeeper工作时,是有一个节点为leader,其他则为follower
    • Leader是通过内部的选举机制临时产生的
    • 采用过半选举机制,从奇数台机器中选取票数最多的机器,作为leader
  • 以一个简单的例子来说明整个选举的过程。

  • 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。

    • (1)服务器1启动,此时只有它一台服务器启动了,它发出去的报没有任何响应,所以它的选举状态一直是LOOKING状态。
    • (2)服务器2启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器2胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是3),所以服务器1、2还是继续保持LOOKING状态。
    • (3)服务器3启动,根据前面的理论分析,服务器3成为服务器1、2、3中的老大,而与上面不同的是,此时有三台服务器选举了它,所以它成为了这次选举的leader。
    • (4)服务器4启动,根据前面的分析,理论上服务器4应该是服务器1、2、3、4中最大的,但是由于前面 已经有半数以上的服务器选举了服务器3,所以它只能接收当小弟的命了。
    • (5)服务器5启动,同4一样当小弟。
15 znode的watch机制
  • ZooKeeper 提供了分布式数据发布/订阅功能

    • 一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。
  • ZooKeeper 中,引入了 Watcher 机制来实现这种分布式的通知功能 。

  • ZooKeeper 允许客户端向服务端注册一个 Watcher 监听

    • 当服务端的一些事件触发了这个 Watcher
    • 那么就会向指定客户端发送一个事件通知,来实现分布式的通知功能。
  • 触发事件种类很多,如:节点创建,节点删除,节点改变,子节点改变等。

  • 总的来说可以概括 Watcher 为以下三个过程:

    • 客户端向服务端注册 Watcher
    • 服务端事件发生触发 Watcher
    • 客户端回调 Watcher 得到触发事件情况
16 watch机制的特点
  • 一次性触发

    • 事件发生触发监听,一个 watcher event 就会被发送到设置监听的客户端,
    • 这种效果是一次性的,后续再次发生同样的事件,不会再次触发。
  • 事件封装

    • ZooKeeper 使用 WatchedEvent 对象来封装服务端事件并传递。
    • WatchedEvent 包含了每一个事件的三个基本属性:
    • 通知状态(keeperState),事件类型(EventType)和节点路径(path)
  • event 异步发送

    • watcher 的通知事件从服务端发送到客户端是异步的。
  • 先注册再触发

    • Zookeeper 中的 watch 机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端。
17 客户端对Zookeeper的ServerList的轮询机制
  • 随机,客户端在初始化(new ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) )的过程中,将所有Server保存在一个List中,然后随机打散,形成一个环。

    • 之后从0号位开始一个一个使用。
  • 两个注意点:

    • Server地址能够重复配置,这样能够弥补客户端无法设置Server权重的缺陷,但是也会加大风险。(比如: 192.168.1.1:2181,192.168.1.1:2181,192.168.1.2:2181).
    • 如果客户端在进行Server切换过程中耗时过长,那么将会收到SESSION_EXPIRED. 这也是上面第1点中的加大风险之处。
18 客户端如何正确处理CONNECTIONLOSS(连接断开) 和 SESSIONEXPIRED(Session 过期)两类连接异常
  • 在ZooKeeper中,服务器和客户端之间维持的是一个长连接

    • 在 SESSION_TIMEOUT 时间内,服务器会确定客户端是否正常连接(客户端会定时向服务器发送heart_beat),服务器重置下次SESSION_TIMEOUT时间。
    • 因此,在正常情况下,Session一直有效,并且zk集群所有机器上都保存这个Session信息。
    • 在出现问题的情况下,客户端与服务器之间连接断了(客户端所连接的那台zk机器挂了,或是其它原因的网络闪断),这个时候客户端会主动在地址列表(初始化的时候传入构造方法的那个参数connectString)中选择新的地址进行连接。
  • 以上即为服务器与客户端之间维持长连接的过程,在这个过程中,用户可能会看到两类异常CONNECTIONLOSS(连接断开) 和SESSIONEXPIRED(Session 过期)。

  • 发生CONNECTIONLOSS后,此时用户不需要关心我的会话是否可用

  • 应用所要做的就是等待客户端帮我们自动连接上新的zk机器,一旦成功连接上新的zk机器后,确认之前的操作是否执行成功了。

19 一个客户端修改了某个节点的数据,其他客户端能够马上获取到这个最新数据吗
  • ZooKeeper不能确保任何客户端能够获取(即Read Request)到一样的数据

    • 除非客户端自己要求,方法是客户端在获取数据之前调用org.apache.zookeeper.AsyncCallbac k.VoidCallback, java.lang.Object) sync。
  • 通常情况下

    • 这里所说的通常情况满足:

        1. 对获取的数据是否是最新版本不敏感
        1. 一个客户端修改了数据,其它客户端是否需要立即能够获取最新数据
    • 通常情况下,可以不关心这点。

  • 在其它情况下,最清晰的场景是这样:

    • ZK客户端A对 /my_test 的内容从 v1->v2,
    • 但是ZK客户端B对 /my_test 的内容获取,依然得到的是 v1. 请注意,这个是实际存在的现象,当然延时很短。
    • 解决的方法是客户端B先调用 sync(), 再调用 getData()。
20 ZooKeeper对节点的watch监听是永久的吗?为什么?
  • 不是。

  • 官方声明:

    • 一个Watch事件是一个一次性的触发器
    • 当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
  • 为什么不是永久的

    • 举个例子,如果服务端变动频繁
    • 而监听的客户端很多情况下,每次变动都要通知到所有的客户端,这太消耗性能了。
    • 一般是客户端执行getData(“/节点A”,true)
    • 如果节点A发生了变更或删除,客户端会得到它的watch事件
    • 但是在之后节点A又发生了变更,而客户端又没有设置watch事件,就不再给客户端发送。
  • 在实际应用中,很多情况下,我们的客户端不需要知道服务端的每一次变动,我只要最新的数据即可。

21 ZooKeeper中使用watch的注意事项有哪些
  • 使用watch需要注意的几点:

    • ① Watches通知是一次性的,必须重复注册.

    • ② 发生CONNECTIONLOSS之后

      • 只要在session_timeout之内再次连接上(即不发生SESSIONEXPIRED)
      • 那么这个连接注册的watches依然在。
    • ③ 节点数据的版本变化会触发NodeDataChanged

      • 注意,这里特意说明了是版本变化。
      • 存在这样的情况,只要成功执行了setData()方法
      • 无论内容是否和之前一致,都会触发NodeDataChanged。
    • ④ 对某个节点注册了watch,但是节点被删除了

      • 那么注册在这个节点上的watches都会被移除。
    • ⑤ 同一个zk客户端对某一个节点注册相同的watch,只会收到一次通知。

    • ⑥ Watcher对象只会保存在客户端,不会传递到服务端。

22 client能否收到每次节点变化的通知
  • 如果节点数据的更新频率很高的话,不能。

  • 原因在于:

    • 当一次数据修改,通知客户端,客户端再次注册watch
    • 在这个过程中,可能数据已经发生了许多次数据修改
    • 因此,千万不要做这样的测试:”数据被修改了n次,一定会收到n次通知”来测试server是否正常工作。
23 能否为临时节点创建子节点
  • ZooKeeper中不能为临时节点创建子节点

  • 因为,临时节点依赖于会话,当这次会话结束就会消失,而子节点的消失与否也会是一个很大的问题

    • 所以,zk中不允许临时节点创建子节点
  • 如果需要创建子节点,应该将要创建子节点的节点创建为永久性节点。

24 是否可以拒绝单个IP对ZooKeeper的访问?如何实现?
  • ZK本身不提供这样的功能,它仅仅提供了对单个IP的连接数的限制。
  • 你可以通过修改iptables来实现对单个ip的限制。
25 在getChildren(String path, boolean watch)是注册了对节点子节点的变化,那么子节点的子节点变化能通知吗?
  • 不能通知。
26 创建的临时节点什么时候会被删除,是连接一断就删除吗?延时是多少?
  • 连接断了之后,ZK不会马上移除临时数据
  • 只有当SESSIONEXPIRED之后,才会把这个会话建立的临时数据移除。
  • 因此,用户需要谨慎设置Session_TimeOut。
27 ZooKeeper是否支持动态进行机器扩容?如果目前不支持,那么要如何扩容呢?
  • ZooKeeper中的动态扩容其实就是水平扩容

    • Zookeeper对这方面的支持不太好
  • 目前有两种方式:

    • 全部重启:关闭所有Zookeeper服务,修改配置之后启动,不影响之前客户端的会话。
    • 逐个重启:这是比较常用的方式。
28 ZooKeeper集群中服务器之间是怎样通信的
  • Leader服务器会和每一个Follower/Observer服务器都建立TCP连接,同时为每个F/O都创建一个叫做LearnerHandler的实体。
  • LearnerHandler主要负责Leader和F/O之间的网络通讯,包括数据同步,请求转发和Proposal提议的投票等。
  • Leader服务器保存了所有F/O的LearnerHandler。
29 ZooKeeper是否会自动进行日志清理?如何进行日志清理?
  • zk自己不会进行日志清理,需要运维人员进行日志清理。
30 谈谈你对ZooKeeper的理解
  • Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题。

    • ZooKeeper提供的服务包括:

      • 分布式消息同步和协调机制
      • 服务器节点动态上下线
      • 统一配置管理
      • 负载均衡
      • 集群管理等。
  • ZooKeeper提供基于类似于Linux文件系统的目录节点树方式的数据存储,即分层命名空间。

    • Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化,通过监控这些数据状态的变化,从而可以达到基于数据的集群管理
    • ZooKeeper节点的数据上限是1MB。
  • 我们可以认为Zookeeper=文件系统+通知机制

  • 对于ZooKeeper的数据结构

    • 每个子目录项如 NameService 都被称作为 znode
    • 这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1;
    • znode 可以有子节点目录,并且每个 znode 可以存储数据
    • 注意 EPHEMERAL 类型的目录节点不能有子节点目录(因为它是临时节点);
  • znode 是有版本的,每个 znode 中存储的数据可以有多个版本

    • 也就是一个访问路径中可以存储多份数据;
  • znode 可以是临时节点

    • 一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除
  • Zookeeper 的客户端和服务器通信采用长连接方式

    • 每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session
    • 如果 znode 是临时节点,这个 session 失效,znode 也就删除了;
  • znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2;

  • znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的,后面在典型的应用场景中会有实例介绍。

31 说明ZooKeeper的通知机制
  • ZooKeeper选择了基于通知(notification)的机制

    • 即:客户端向ZooKeeper注册需要接受通知的znode
    • 通过znode设置监控点(watch)来接受通知。
    • 监视点是一个单次触发的操作,意即监视点会触发一个通知。
    • 为了接收多个通知,客户端必须在每次通知后设置一个新的监视点。
32 ZooKeeper的监听原理
  • 在应用程序中,mian()方法首先会创建zkClient

  • 创建zkClient的同时就会产生两个进程

    • 即Listener进程(监听进程)和connect进程(网络连接/传输进程)
  • 当zkClient调用getChildren()等方法注册监视器时,connect进程向ZooKeeper注册监听器

    • 注册后的监听器位于ZooKeeper的监听器列表中
  • 监听器列表中记录了zkClient的IP,端口号以及要监控的路径

  • 一旦目标文件发生变化,ZooKeeper就会把这条消息发送给对应的zkClient的Listener()进程,Listener进程接收到后,就会执行process()方法

    • 在process()方法中针对发生的事件进行处理。
33 ZooKeeper使用到的各个端口的作用
  • 2888:Follower与Leader交换信息的端口。
  • 3888:万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
34 ZooKeeper的部署方式有哪几种?集群中的角色有哪些?集群最少需要几台机器?
  • ZooKeeper的部署方式有单机模式和集群模式
  • 集群中的角色有Leader和Follower,集群最少3(2N+1)台,根据选举算法,应保证奇数。
35 ZooKeeper集群如果有3台机器,挂掉一台是否还能工作?挂掉两台呢?
  • zookeeper采取的是过半存活机制
  • 当集群是三台,挂掉一台还能正常工作,但是挂掉俩台就不行了!
36 ZooKeeper使用的ZAB协议与Paxo算法的异同
  • Paxos算法是分布式选举算法,Zookeeper使用的 ZAB协议(Zookeeper原子广播)

  • 两者的异同如下:

    • ① 相同之处:

      • 比如都有一个Leader,用来协调N个Follower的运行;
      • Leader要等待超半数的Follower做出正确反馈之后才进行提案;
      • 二者都有一个值来代表Leader的周期。
    • ② 不同之处:

      • ZAB用来构建高可用的分布式数据主备系统(Zookeeper)
      • Paxos是用来构建分布式一致性状态机系统。
37 谈谈ZooKeeper对事务性的支持
  • ZooKeeper对于事务性的支持主要依赖于四个函数

    • zoo_create_op_init
    • zoo_delete_op_init
    • zoo_set_op_init
    • zoo_check_op_init
  • 每一个函数都会在客户端初始化一个operation,客户端程序有义务保留这些operations。

    • 当准备好一个事务中的所有操作后,可以使用zoo_multi来提交所有的操作
    • 由zookeeper服务来保证这一系列操作的原子性。
    • 也就是说只要其中有一个操作失败了,相当于此次提交的任何一个操作都没有对服务端的数据造成影响。
    • Zoo_multi的返回值是第一个失败操作的状态信号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值