一篇文章粗浅了解Apache zookeeper

2024-08-22 14:58

本文主要是介绍一篇文章粗浅了解Apache zookeeper,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一篇文章粗浅了解Apache zookeeper

前言

Zookeeper是一个分布式应用程序协调服务,提供了简单易用的接口和性能高效、功能稳定的系统让用户可以很轻松解决分布式应用程序下面的出现的协调服务,确保避免出现竞态条件或者死锁等错误。其设计目标是减轻分布式应用从零开始实现分布式协调服务的压力。本篇文章将会在以下几个方面来介绍zookeeper

  • zookeeper是什么
    • zookeeper的数据模型(znode)
      • znode结构
      • 数据存储
      • 节点类型
      • 节点操作
      • 监视器
    • zookeeper的集群架构
    • zookeeper的功能
      • 命名服务
      • 配置管理
      • 集群管理
      • 分布式锁
      • 队列管理
  • zookeeper简单部署使用
    • 部署zookeeper集群。
    • 基于zookeeper的分布式锁简单实现。

本文参考官方网站以及其他一些博客文章,连接会在文章后面贴出。

zookeeper是什么

引用官方文档的一话来说明zookeeper是什么东西

zookeeper是一个高性能分布式应用协作服务,它提供了基本功能,包括 命名空间。配置管理,集群管理和组同步。提供了一些简单的API,而不必要从头再实现他们,你可以使用它来实现同步,集群管理,选举和出席协议,你可以根据自己特定的需求构建服务。

zookeeper非常快速且非常简单,由于其目标是构建更复杂到的服务的基础,因此他提供了一组保证。

  • 顺序一致性:客户端的更新将按照他们发送的顺序进行应用
  • 原子性:更新成功或失败,没有部分更新
  • 单一性:无论客户端连接到那个服务器,都会看到同一个视图
  • 可靠性:一旦客户端进行了修改,他会保持知道一个客户端修改了它
  • 及时性:客户端会在一个确定时间内得到最新的数据。
zookeeper 的数据模型:

zookeeper允许分布式进程通过一个共享的被组织成类似一个标准文件系统的命名空间相互协作,这些命名空间可以保存数据,称之为znode,在zookeeper的设定中,它类似于文件和目录但是区别于典型的文件系统,因为他被设计数据保存在内存中,这意味着zookeeper可以实现高吞吐量和低延迟。

znode结构

zookeeper命名空间中的znode,兼具文件和目录两种特点,既像文件一样维护者数据,元信息,ACL,时间戳等数据结构,又可以像目录一样作为标识路径的一部分。每个znode由三部分组成。

  • stat:状态信息,描述该znode的版本,权限等信息
  • data:与该znode关联的数据
  • children:该znode下的子节点

zookeeper可以关联一些数据,但是没有被设计为常规的数据库或者大数据存储,它用于管理调度数据,比如分布式应用中的配置文件,状态信息等等。zookeeper节点数据被严格控制在1M之内

znode通过路径引用,如同Unix的文件绝对路径,所以路径是由/开始的,除此之外,他们必须是唯一的,也就是说每一个路径只有一个表示,这些路径不能改变。在zookeeper中,路径由Unicode字符串组成,并且有一些限制。字符串/zookeeper用于保存管理信息。

数据存储

zookeeper中的每个节存取的数据操作都是原子性操作,读操作会获取节点相关的所有数据,写操作会替换节点的所有数据,另外,每一个节点都拥有自己的访问控制列表,这个列表规定了用户的权限,限制谁可以做什么

节点类型

zookeeper中的节点分为两种,分别为临时节点和永久节点。节点的类型在创建的时候即被确定,不能改变。

  • 临时节点:该节点的声明周期依赖于创建他们的会话,一旦会话结束,临时节点将被自动删除,也可以手动删除。虽然每一个临时节点绑定到一个会话,但是这个节点对所有的客户端会话都是可见的。临时节点不允许有子节点。
  • 永久节点:该节点的声明周期不依赖于会话,只有客户端显式删除他们才会消失。

除此之外,还有另外一个概念,有一种叫做顺序节点。在创建znode的时候,zookeeper会在路径结尾添加一个递增的计数。这个计数对于此节点的父节点来说是唯一的。它的格式为%10d,当计数值大于2的32次方-1时,计数器将会溢出。

节点操作

zookeeper的一个设计目标是提供一个非常简单的编程接口,因此,它仅仅支持以下操作:

操作描述
create创建znode,在创建一个节点的时候,必须确保父节点已经存在
delete删除znode,在删除一个节点的时候,保证该节点没有子节点
exists判断是否存在znode,并获取他的元数据
getData/setData获取/设置znode节点关联的数据
getChildren获取该znode的所有子节点
sync使客户端的znode视图与zookeeper同步
监视器

zookeeper可以为所有的读操作设置一个watcher,这些读操作包括exists()getChildren()以及getData()watch时间是一次性的触发器,当watch的对象发生改变时,将会触发此对象上watch所对应的事件,watch事件将被异步发送给客户端,并且zookeeperwatch机制提供了有序的一致性保障。理论上,客户端接收watch时间的时间要快于其看到watch对象状态变化的时间。

zookeeper的集群架构

zookeeper对实现高性能,高可用性,严格有序的访问非常重要,zookeeper可以部署为集群模式。zookeeper的服务器会对信息进行共享,他们保持状态的内存映像,以及持久储存中的事务日志和快照,只要大部分服务器可用,则Zookeeper服务可用。

分布式与数据复制

Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。数据复制的好处:

  • 容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作;
  • 提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力;
  • 提高性能:让客户端本地访问就近的节点,提高用户访问速度。

从客户端读写访问的透明度来看,数据复制集群系统分下面两种:

1、写主(WriteMaster) :对数据的修改提交给指定的节点。读无此限制,可以读取任何一个节点。这种情况下客户端需要对读与写进行区别,俗称读写分离;

2、写任意(Write Any):对数据的修改可提交给任意的节点,跟读一样。这种情况下,客户端对集群节点的角色与变化透明。

zookeeper来说,它采用的方式是写任意。通过增加机器,它的读吞吐能力和响应能力扩展性非常好,而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因),而响应能力则取决于具体实现方式,是延迟复制保持最终一致性,还是立即复制快速响应。

结构如图:

zookeeper的功能

zookeeper提供了命名服务、配置管理、集群管理、分布式锁、队列管理等一系列的功能。这些功能都是基于znode数据结果来协调完成的。

命名服务

zookeeper的文件系统里创建一个目录,具有唯一的path,在无法确定分布式架构下其他机器时可以通过这个path进行联系。

配置管理

在分布式架构下,多台机器的配置修改变变得困难,可以把配置信息放在zookeeper上面的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生改变,每个应用程序都会受到zookeeper的通知。

集群管理

集群管理的问题在于如何确定机器的加入和退出,以及出现故障时,选举master方面的问题。对于机器的加入和退出,可以通过创建一个父节点,然后监听这个节点的子节点变化消息,一旦有机器加入或宕机,则该机器与zookeeper的连接断开,其所创建的临时节点被删除,其他所有机器都收到通知,新的机器加入也是同样的道理。关于选举master,假设我们在创建临时节点的时候,使用顺序节点,每一个节点都带者一个对于父节点唯一的序号,此时,选取最小的节点作为master即可。一旦机器宕机了,节点被删除,又重新选举。

分布式锁

使用zookeeper实现分布式锁,有两种方式:

  • 将一个临时znode看做一把锁,客户端创建这个节点成功后则表示获得锁,此时其他客户端创建这个znode将会失败,直到获得锁的客户端释放这个锁(删除该节点),其他客户端才能获取锁。

  • 创建一个父节点/distribute_lock,所有客户端在它下面创建临时顺序编号的节点,如果判断到当前客户端的顺序最小则获取锁,用完删除,其他节点依次获得锁。

队列管理

两种类型的队列:

  • 同步队列,当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。
  • 队列按照FIFO方式进行入队和出队操作。

第一类,在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
第二类,和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号

zookeeper简单部署应用

部署zookeeper

这里采用3台本地虚拟机进行部署,操作系统为CentOs 6.5,它们的ip地址分别为:

  • 192.168.31.224
  • 192.168.31.225
  • 192.168.31.226

去到/usr/local/目录

cd /usr/local

下载zookeeper包

wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

解压

tar -zxvf zookeeper-3.4.10.tar.gz

对目录重命名

mv zookeeper-3.4.10 zk

配置环境变量

# vi ~/.bashrc
export ZOOKEEPER_HOME=/usr/local/zk
export PATH=$ZOOKEEPER_HOME/bin
source ~/.bashrc

接着执行以下命令

cd zk/conf
# 复制配置文件,zookeeper默认配置文件为zoo.cfg
cp zoo.sample.cfg zoo.cfg
mkdir data

然后编辑zoo.cfg修改以下内容:

dataDir=/usr/local/zk/data/
server.0=192.168.31.224:2888:3888
server.1=192.168.31.225:2888:3888
server.2=192.168.31.226:2888:2888

然后去到/zk/data/目录下

cd /usr/local/zk/data/
vi myid 

myid的内容为zoo.cfg中的server.{}=192.168.31.xxx中的{}部分,比如192.168.31.224ip地址的myid文件内容为0,依次类推,其他两台机器的内容为12

在3台机器都部署好之后,执行:

zkServer.sh start

查看状态,在3台机器上执行应该是显示一个leader两个follower

zkServer.sh status

然后可以通过jps命令查看输出结果是否有QuromPeerMain进程,如果存在,则表示zookeeper集群部署成功了。

基于zookeeper的分布式锁简单实现

zookeeper默认提供了JavaC两种语言的接口,我们通过java实现一个简单的分布式锁。

使用IDEA创建一个maven项目,添加如下依赖:

<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.5</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions>
</dependency>

接着编写获得分布式锁的代码:

public class ZooKeeperSession {private static CountDownLatch connectedSemaphore = new CountDownLatch(1);private ZooKeeper zookeeper;public ZooKeeperSession() {try {this.zookeeper = new ZooKeeper("192.168.31.224:2181,192.168.31.225:2181,192.168.31.226:2181", 50000, new ZooKeeperWatcher());System.out.println(zookeeper.getState());connectedSemaphore.await();System.out.println("ZooKeeper session established......");} catch (Exception e) {e.printStackTrace();}}/*** 获取分布式锁* @param path*/public void acquireDistributedLock(String path) {try {zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);System.out.println("success to acquire lock");  } catch (Exception e) {// NodeExistsExceptionint count = 0;while(true) {try {Thread.sleep(1000); zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);} catch (Exception e2) {count++;System.out.println("the " + count + " times try to acquire lock......");continue;}System.out.println("success to acquire lock after " + count + " times try......");break;}}}/*** 释放掉一个分布式锁* @param productId*/public void releaseDistributedLock(String path) {try {zookeeper.delete(path, -1); System.out.println("release the lock......");  } catch (Exception e) {e.printStackTrace();}}/*** 建立zk session的watcher* @author Administrator**/private class ZooKeeperWatcher implements Watcher {public void process(WatchedEvent event) {System.out.println("Receive watched event: " + event.getState());if(KeeperState.SyncConnected == event.getState()) {connectedSemaphore.countDown();} }}   
}

上述代码实现了一个最简单的分布式锁,在构造函数中,连接上zookeeper,然后在获取分布式锁的代码也是很简单粗暴。
首先创建了一个临时节点(CreateMode.EPHEMERAL),如果创建这个节点失败了,则证明这个锁已经在占用,则无限循环知道获取到这个锁为止,当锁的持有者释放掉锁之后(delete node),则可以获取该锁。

总结

其实这篇文章不算原创,有很多内容都摘自其他博客,自己也没有研究得这么深入,写这篇文章的目的是为了记录一下一些知识,其实写博客的一个很重要的原因就是记录一些知识,因为我觉得有时候找资料上网找不如上自己博客找。找到的信息还比较可靠吧,毕竟是自己的经验。

参考

  • Zookeeper 3.4 Documentation
  • ZooKeeper学习第一期—Zookeeper简单介绍
  • Zookeeper的功能以及工作原理

这篇关于一篇文章粗浅了解Apache zookeeper的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1096603

相关文章

Zookeeper安装和配置说明

一、Zookeeper的搭建方式 Zookeeper安装方式有三种,单机模式和集群模式以及伪集群模式。 ■ 单机模式:Zookeeper只运行在一台服务器上,适合测试环境; ■ 伪集群模式:就是在一台物理机上运行多个Zookeeper 实例; ■ 集群模式:Zookeeper运行于一个集群上,适合生产环境,这个计算机集群被称为一个“集合体”(ensemble) Zookeeper通过复制来实现

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

ZooKeeper 中的 Curator 框架解析

Apache ZooKeeper 是一个为分布式应用提供一致性服务的软件。它提供了诸如配置管理、分布式同步、组服务等功能。在使用 ZooKeeper 时,Curator 是一个非常流行的客户端库,它简化了 ZooKeeper 的使用,提供了高级的抽象和丰富的工具。本文将详细介绍 Curator 框架,包括它的设计哲学、核心组件以及如何使用 Curator 来简化 ZooKeeper 的操作。 1

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

zookeeper相关面试题

zk的数据同步原理?zk的集群会出现脑裂的问题吗?zk的watch机制实现原理?zk是如何保证一致性的?zk的快速选举leader原理?zk的典型应用场景zk中一个客户端修改了数据之后,其他客户端能够马上获取到最新的数据吗?zk对事物的支持? 1. zk的数据同步原理? zk的数据同步过程中,通过以下三个参数来选择对应的数据同步方式 peerLastZxid:Learner服务器(Follo

PHP: 深入了解一致性哈希

前言 随着memcache、redis以及其它一些内存K/V数据库的流行,一致性哈希也越来越被开发者所了解。因为这些内存K/V数据库大多不提供分布式支持(本文以redis为例),所以如果要提供多台redis server来提供服务的话,就需要解决如何将数据分散到redis server,并且在增减redis server时如何最大化的不令数据重新分布,这将是本文讨论的范畴。 取模算法 取模运

java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频)

这是什么系统? 资源获取方式在最下方 java计算机毕设课设—停车管理信息系统(附源码、文章、相关截图、部署视频) 停车管理信息系统是为了提升停车场的运营效率和管理水平而设计的综合性平台。系统涵盖用户信息管理、车位管理、收费管理、违规车辆处理等多个功能模块,旨在实现对停车场资源的高效配置和实时监控。此外,系统还提供了资讯管理和统计查询功能,帮助管理者及时发布信息并进行数据分析,为停车场的科学

CSP-J基础之数学基础 初等数论 一篇搞懂(一)

文章目录 前言声明初等数论是什么初等数论历史1. **古代时期**2. **中世纪时期**3. **文艺复兴与近代**4. **现代时期** 整数的整除性约数什么样的整数除什么样的整数才能得到整数?条件:举例说明:一般化: 判断两个数能否被整除 因数与倍数质数与复合数使用开根号法判定质数哥德巴赫猜想最大公因数与辗转相除法计算最大公因数的常用方法:举几个例子:例子 1: 计算 12 和 18

Apache Tiles 布局管理器

陈科肇 =========== 1.简介 一个免费的开源模板框架现代Java应用程序。  基于该复合图案它是建立以简化的用户界面的开发。 对于复杂的网站,它仍然最简单,最优雅的方式来一起工作的任何MVC技术。 Tiles允许作者定义页面片段可被组装成在运行一个完整的网页。  这些片段,或Tiles,可以用于为了降低公共页面元素的重复,简单地包括或嵌入在其它瓦片,制定了一系列可重复使用