大数据笔记之Zookeeper

概述

Zookeeper是一个开源的分布式的并且为分布式应用提供协调服务的 Apache 项目。

Zookeeper工作机制

大数据笔记之Zookeeper_第1张图片

功能

管理(存储、读取)用户提交的数据
为用户程序提供数据节点的监听服务

Zookeeper特点

  1. 一个leader,多个follower
  2. 集群中只要有半数以上节点存活,Zookeeper集群就能正常服务
  3. 全局一致性:每个Server保存一份相同的数据副本
  4. 更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行
  5. 数据更新原子性,一次数据更新要么成功,要么失败
  6. 实时性,在一定时间范围内,Client能读到最新数据

数据结构

1、层次化的目录结构,命名符合常规文件系统规范(见下图)
2、每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识
3、节点Znode可以包含数据(只能存储很小量的数据,<1M;最好是1k字节以内)和子节点(但是EPHEMERAL类型的节点不能有子节点)
4、客户端应用可以在节点上设置监视器
大数据笔记之Zookeeper_第2张图片

应用场景

提供的服务包括:

  1. 统一命名空间
  2. 统一配置管理
  3. 统一集群管理
  4. 服务器节点动态上下线
  5. 软负载均衡

内部原理

选举机制

半数机制: 集群中半数以上机器存活,集群可用。适合安装奇数台服务器。

Zookeeper 虽然在配置文件中没有指定 Master 和 Slave。但是只有一个节点为Leader,其他为Follower,Leader是通过内部的选举机制临时产生的。

以下以5台服务器描述整个选举过程:它们的 id 从1 - 5 ,同时它们都是最新启动的,也就是没有历史数据。假设这些服务器依序启动。

  1. 服务器 1 启动,此时只有一台服务器启动,它发出去的保温没有任何响应,所以它的选举状态一直是LOOKING状态。
  2. 服务器 2 启动,它与最开始启动的服务器1进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以id值较大的服务器 2 胜出,但未超过半数以上服务器都同意选举它,所以服务器 1,2 保持LOOKING状态。
  3. 服务器 3 启动,根据以上分析,服务器 3 成为服务器 1、2、3 的老大,此时已有3台服务器选举了它,所以服务器 3 成为Leader。
  4. 服务器 4 启动,由于前面已经选举了服务器 3 未Leader,所以它只能接收当follower
  5. 服务器 5 启动,同上

节点类型

持久: client 与 server 断开连接后,创建的节点不删除
短暂: client 与 server 断开连接后,创建的节点自己删除

  1. 持久目录节点:client 与 zookeeper断开连接后,该结点依旧存在
  2. 持久顺序编号目录节点:client 与 zookeeper断开连接后,该结点依旧存在,只是 Zookeeper 给该节点名称进行顺序编号
  3. 临时目录节点:client 与 Zookeeper 断开连接后,该的节点自己删除
  4. 临时顺序编号目录节点:client 与 Zookeeper 断开连接后,创建的节点自己删除,只是 Zookeeper 给该节点名称进行顺序编号

说明:创建 znode 是设置标识,znode 名称后会附加一个值,顺序是一个单调递增的计数器,有父节点维护。

注意:在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,着用客户端可以通过顺序号推断事件的顺序。

监听器原理

常见的监听

  1. 监听节点数据的变化:get path [watch]
  2. 监听子节点增减变化:ls path [watch]

监听原理详解

  1. 首先要有一个main()线程
  2. 在main()线程中创建ZkClient,此时会创建两个线程,一个负责网络连接通信,一个负责监听
  3. 通过 connect 线程将注册的监听事件发送给 Zookeeper
  4. 在 Zookeeper 的注册监听器列表中将注册的监听事件添加到列表中
  5. Zookeeper 监听到有数据或路径变化,就会把这个消息发送给 listener 线程
  6. listener 线程内部调用了 process() 方法

写数据流程

大数据笔记之Zookeeper_第3张图片

zk的分布式锁的实现

在我们自己的分布式业务系统中,可能会存在某种资源,需要被整个系统的各台服务器共享访问,但是只允许一台服务器同时访问

第一类实现:

  1. 先创建一个永久节点/ditribute_lock
  2. 所有客户端在/ditribute_lock节点下创建临时有序节点
  3. 编号最小的获得锁可以访问资源
  4. 资源访问结束后断开连接下一个编号成为了编号最小的获得锁
  5. 用完删除,依次执行

第二类实现

  1. 可以将zookeeper上的一个znode看做是一把锁,所有客户端都去创建相同名字的临时节点
  2. 最终创建成功的客户端就获得了锁,用完删除,然后所有的客户端再重新去创建

双namenode需要解决的问题

哪儿台机器是active namenode,哪儿台是standby namenode
standby namenode元数据的获取

  1. 元数据的管理方式需要改变
    把edits存放在一个共享存储中(qjournal和NFS两种实现)
  2. 主备切换(状态管理)
    1)需要监听每一个namendoe的健康状态
    2)一旦active namenode健康发生变化,立刻重新选举出新的active namenode
    3)然后切换状态

预防脑裂,一旦active namenode健康状态出现问题,切换前要将其杀死(可以使用免密码登录,然后kill掉,预防kill失败,写一个脚本程序去杀死进程)

你可能感兴趣的:(Zookeeper,Bigdata)