public class TestZK {// zookeeper集群的ip和端口private String connectString = "192.168.204.141:2181,192.168.204.142:2181,192.168.204.143:2181";/*session超时的时间: 时间不宜设置太小。因为zookeeper和加载集群环境会因为性能等原因而延迟略高,如果时间太少,还没有创建好客户端,就开始操作节点。会报错的。(心急吃不了热豆腐)*/private int sessionTimeout = 60 * 1000;//zookeeper客户端对象private ZooKeeper zkClient;@Beforepublic void init() throws Exception {zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {public void process(WatchedEvent watchedEvent) {System.out.println("得到监听反馈,再进行的业务处理代码!");System.out.println(watchedEvent.getType());}});}

分布式和集群的区别

分布式和集群,都是很多人在做

  • 分布式:负责工作不一样,但是最终目的都是一样的
  • 集群:负责工作一样

概述

是一个开源的分布式(多台服务器干一件事)的,为分布式应用提供“协调服务”的Apache项目

服务平台,利用zookeeper部署技术

最初的运用领域在大数据技术生态圈当中。

工作机制

Zookeeper从设计模式角度来理解;是一个基于观察者模式(一个人干活,有人盯着)设计的分布式服务管理框架。他负责 存储管理 大家都关心的数据。

  • 然后接受观察者的注册,一旦这些数据发生变化
  • Zookeeper就将负责通知已经注册的那些观察者做出相应的反应
  • 从而实现集群中类似Master/Slave管理模式

Zookeeper=文件系统+通知机制

机制(例:美团原理):

  1. 商家营业并入驻
  2. 获取当前营业的饭店列表
  3. 服务器节点下线
  4. 服务器节点上下线事件通知
  5. 重新再获取服务器列表,并注册监听

特点

  1. 是一个leader和多个follower来组成的集群
  2. 集群中只要有半数以上的节点存活,Zookeeper就能正常工作(5台服务器挂2台,没问题;4台服务器挂2个,就停止)
  3. 全局数据一致,每台服务器都保存一份相同的数据副本,无论clien连接哪台server,数据都是一致的。
  4. 数据更新原子性,一次数据要么成功,要么失败
  5. 实时性,在一定时间范围内,client能读取到最新数据
  6. 更新的请求按照顺序执行,会按照发送过来的顺序,逐一执行

数据结构

Zookeeper数据模型的结构与linux文件系很类似,整体上可以看作是一棵数,每个节点称作一个ZNode。

每一个ZNode默认能够存储1MB的数据(元数据),每个ZNode的路径都是唯一的

  • 元数据,又称中介数据,中继数据,为描述数据的数据,主要是描述数据属性的信息,用来支持如指示存储位置、历史数据、资源查找、文件记录等功能

应用场景

提供的服务包括:统一命名服务,统一配置管理,统一集群管理,服务器节点动态上下线,负载均衡等

统一命名服务

  • 在分布式环境下,通常需要对应用或服务进行统一命名,便于识别
  • 例如:服务器的IP地址不容易记,但域名相比之下却很容易记住

统一配置管理

  • 分布式环境下,配置文件做到同步是必经之路
  • 1000台服务器,如果配置文件做出修改,那一台一台的修改,运维人员肯定会疯,如何做到修改一处就快速同步到每台服务器上

  • 将配置管理交给Zookeeper
  1. 将配置信息写入到Zookeeper的某个节点上
  2. 每个客户端都监听这个节点
  3. 一旦节点中的数据文件被修改,Zookeeper这个话匣子就会通知每台客户服务器

服务器节点动态上下线

  • 客户端能够实现获取服务器上下线的变化

软负载均衡

  • Zookeeper会记录每台服务器的访问次数,让访问次数最少的服务器去处理最新的客户请求

下载地址

镜像库地址:http://archive.apache.org/dist/zookeeper/

 Zookeeper内部原理

选举机制

  • 半数机制:集群中半数以上机器存活,集群可用。所以Zookeeper适合安装奇数台服务器
  • 虽然在配置文件中并没有指定Master和Slave。但是,Zookeeper工作时,是有一个节点为Leader,其他则为Follower,Leader是通过内部的选举机制临时产生的
  • 例:假如有5台服务器,第一台服务器投票与自己,如果没超过半数,无法成为leader,则将票数推给第二台服务器,此时,第二台服务算上自己就有两个票数,但是票数任未过半。第二台将两个票数推给第三台服务器,此时,第三台服务器拥有三个票数,成为leader。第四五台服务器则不继续进行投票选举(已经出现leader时,其它的服务器就是Follower)

节点类型

持久型:

  • 持久化目录节点:客户端与zookeeper断开连接后,该节点依旧存在
  • 持久化顺序编号目录节点:客户端与zookeeper断开连接后,该节点依旧存在,创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护,例如:Znode001,Znode002...

短暂型:

  • 临时目录节点:客户端和服务器断开连接后,创建的节点自动删除
  • 临时顺序编号目录节点:客户端和zookeeper断开连接后,该节点被删除,创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护,例如:Znode001,Znode002...

注意:序号是相当于i++,和数据库中的自增长类似

监听器原理

  1. 在main方法中创建Zookeeper客户端的同时就会创建两个线程,一个负责网络连接通信,一个负责监听
  2. 监听事件就会通知网络通信发送给zookeeper
  3. zookeeper获取注册的监听事件后,立刻将监听事件添加到监听列表里
  4. zookeeper监听到 数据变化 或 路径变化,就会将这个消息发送给监听线程(1.监听节点数据变化:get path [watch];2.监听子节点增减的变化:Is path [watch])
  5. 监听线程就会在内部调用process方法(需要我们实现process方法内容)

写数据流程

  1. Client想想Zookeeper的Server1 上写数据,必须得先发送一个写的请求
  2. 如果Server1不是Leader,那么Server1 会把接收到的请求进一步转发给Leader
  3. 这个Leader会将写请求广播给各个Server,各个Server写成功后就会通知Leader
  4. 当Leader收到半数以上的Server数据写成功了,那么就说明数据写成功了
  5. 随后,Leader会告诉Server1数据写成功了
  6. Server1会反馈通知Client数据写成功了,整个流程结束

Zookeeper实战

分布式安装部署

集群思路:先搞定一台服务器,再克隆出两台,形成集群

安装zookeeper

配置服务器编号

  • 在/opt/zookeeper/zkData创建myid文件  : [root@localhost zkData]# vim myid
  • 在文件中添加与server对应的编号:1
  • 其余两台服务器分别对应2和3

配置zoo.cft文件

  • 打开zoo.cfg文件,增加如下配置

  • 配置参数解读 server.A=B:C:D
  1. A:一个数字,表示第几号服务器。集群模式下配置的/opt/zookeeper/zkData/myid文件里面的数据就是A的值
  2. B:服务器的ip地址
  3. C:与集群中Leader服务器交换信息的端口
  4. D:选举时专用端口,万一集群中的Leader服务器挂了,需要一个端口重新进行选举,选出一个新的Leader,二这个端口就是用来执行选举时服务器相互通信的端口

配置其余两台服务器

  1. 在虚拟机数据目录vms下,创建zk02
  2. 将本台服务器数据目录下的.vmx文件和所有的.vmdk文件分别拷贝到zk02下
  3. 虚拟机->文件->打开(选择zk02下的.vmx文件)
  4. 开启此虚拟机,弹出对话框,选择“我已复制该虚拟机”
  5. 进入系统后,修改linux中的ip,修改/opt/zookeeper/zkData/myid中的数值为2.第三台服务器zk03,重复以上的步骤

集群操作

客户端命令行操作

API应用

IDEA环境搭建

  1. 创建一个,maven工程
  2. 添加pom文件
<dependencies><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.6.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>

在resources下创建log4j.properties

log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%nlog4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/zk.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

创建Zookeeper客户端

public class TestZK {// zookeeper集群的ip和端口private String connectString = "192.168.204.141:2181,192.168.204.142:2181,192.168.204.143:2181";/*session超时的时间: 时间不宜设置太小。因为zookeeper和加载集群环境会因为性能等原因而延迟略高,如果时间太少,还没有创建好客户端,就开始操作节点。会报错的。(心急吃不了热豆腐)*/private int sessionTimeout = 60 * 1000;//zookeeper客户端对象private ZooKeeper zkClient;@Beforepublic void init() throws Exception {zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {public void process(WatchedEvent watchedEvent) {System.out.println("得到监听反馈,再进行的业务处理代码!");System.out.println(watchedEvent.getType());}});}

创建节点

一个ACL对象就是一个Id和permission对

  • 表示哪个/哪些范围的Id(Who)在通过了怎样的鉴权(How)之后,就允许进行那些操作 (What):Who How What;
  • permission(What)就是一个int表示的位码,每一位代表一个对应操作的允许状态。
  • 类似linux的文件权限,不同的是共有5种操作:CREATE、READ、WRITE、DELETE、 ADMIN(对应更改ACL的权限)
  1. OPEN_ACL_UNSAFE:创建开放节点,允许任意操作 (用的最少,其余的权限用的很 少)
  2. READ_ACL_UNSAFE:创建只读节点
  3. CREATOR_ALL_ACL:创建者才有全部权限
//创建节点@Testpublic void createNode() throws Exception {String str = zkClient.create("/lagou", "laosun".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);//参数1:要创建的节点的路径//参数2:节点数据//参数3:节点权限//参数4:节点的类型System.out.println("已创建节点: " + str);}

查询节点的值

@Testpublic void getNodeData() throws Exception {byte[] bytes = zkClient.getData("/lagou", false, new Stat());String str = new String(bytes);System.out.println("/lagou节点的数据:" + str);}

修改节点的值

//修改节点上的数据@Testpublic void updateData() throws Exception {Stat stat = zkClient.setData("/lagou", "laosunA".getBytes(), 0);System.out.println(stat);}

删除节点

//删除节点@Testpublic void delete() throws Exception {zkClient.delete("/lagou", 1);System.out.println("删除成功!");}

获取子节点

//获取子节点@Testpublic void getChildren() throws Exception {List<String> list = zkClient.getChildren("/china", false);for (String child : list) {System.out.println(child);}}

监听子节点的变化

//监听根节点下面的变化@Testpublic void watchNode() throws Exception{List<String> list = zkClient.getChildren("/", true);for (String s : list)System.out.println(s);// 让线程无限的等待下去System.in.read();}

判断ZNode是否变化

@Testpublic void exists()throws Exception{Stat stat = zkClient.exists("/lagou", false);if(stat==null)System.out.println("不存在");elseSystem.out.println("存在");}

分布式锁

  • 锁:我们在多线程中接触过,作用就是让当前的资源不会被其他线程访问!
  1. 我的日记本,不可以被别人看到。所以要锁在保险柜中
  2. 当我打开锁,将日记本拿走了,别人才能使用这个保险柜
  • 在zookeeper中使用传统的锁引发的 “羊群效应” :1000个人创建节点,只有一个人能成功,999 人需要等待!
  • 羊群是一种很散乱的组织,平时在一起也是盲目地左冲右撞,但一旦有一只头羊动起来,其他的羊 也会不假思索地一哄而上,全然不顾旁边可能有的狼和不远处更好的草。羊群效应就是比喻人都有 一种从众心理,从众心理很容易导致盲从,而盲从往往会陷入骗局或遭到失败。

  • 避免“羊群效应”,zookeeper采用分布式锁

  1. 所有请求进来,在/lock下创建 临时顺序节点 ,放心,zookeeper会帮你编号排序
  2. 判断自己是不是/lock下最小的节点 1. 是,获得锁(创建节点) 2. 否,对前面小我一级的节点进行监听
  3. 获得锁请求,处理完业务逻辑,释放锁(删除节点),后一个节点得到通知
  4. 重复步骤2

分布式技术-Zookeeper相关推荐

  1. 深入理解分布式技术 - ZooKeeper数据一致性解读

    文章目录 概述 ZooKeeper 是如何实现数据一致性的 Zab 一致性协议 Zab 协议的两部分 Zab 协议中的 Zxid Zab 流程分析 消息广播 崩溃恢复 数据同步 Zab 与 Paxos ...

  2. 搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务

    搞懂分布式技术19:使用RocketMQ事务消息解决分布式事务 初步认识RocketMQ的核心模块 rocketmq模块 rocketmq-broker:接受生产者发来的消息并存储(通过调用rocke ...

  3. 搞懂分布式技术16:浅谈分布式锁的几种方案

    搞懂分布式技术16:浅谈分布式锁的几种方案 前言 随着互联网技术的不断发展,数据量的不断增加,业务逻辑日趋复杂,在这种背景下,传统的集中式系统已经无法满足我们的业务需求,分布式系统被应用在更多的场景, ...

  4. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章

     学习笔记:The Log(我所读过的最好的一篇分布式技术文章)         前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文很长,但是我坚持看完了,收获 ...

  5. mybatis中文文档_成神之路!缓存+MyBatis+MySQL+Spring全家桶+分布式技术实战合集

    最近花了很长的时间去搜罗Java核心技术好文,我把每个Java核心技术的优选文章都整理成了一个又一个的文档.昨天也是终于全部整理好了,今天就把这些东西分享给老铁们,也能为老铁们省去不少麻烦,想学什么技 ...

  6. 分布式技术是大规模应用的最后一个考验

    随着用户量的进一步增长,单个子系统数据库也会慢慢达到单机处理能力的上限.此时,已经不能再通过领域拆分来解决问题了,因为仅仅是单一的订单表中的数据就已经超出了单个数据库的处理能力.唯一的解决方式就是把订 ...

  7. 分布式技术与实战第一课 分布式理论与一致性算法

    开篇词:搭建分布式知识体系,挑战高薪 Offer 你好,我是邴越,在一线互联网公司从事分布式开发工作多年,一直关注分布式理论和新技术的发展. 互联网发展到今天,用户数量越来越多,产生的数据规模也越来越 ...

  8. java分布式技术平台架构方案

    CoolJava技术特点 CoolJava的技术解决方案信息系统的稳定性.技术先进性.可拓展性,并且满足未来继续增长.业务变革.监管加强的潜在需求.追求系统快速开发迭代,CoolJava应用开发框架能 ...

  9. 尚硅谷大数据技术Zookeeper教程-笔记01【Zookeeper(入门、本地安装、集群操作)】

    视频地址:[尚硅谷]大数据技术之Zookeeper 3.5.7版本教程_哔哩哔哩_bilibili 尚硅谷大数据技术Zookeeper教程-笔记01[Zookeeper(入门.本地安装.集群操作)] ...

最新文章

  1. Python使用openCV把原始彩色图像转化为灰度图、使用OpenCV把图像二值化(仅仅包含黑色和白色的简化版本)、基于自适应阈值预处理(adaptive thresholding)方法
  2. Web后台服务开发——数据库查询之引入TypeORM
  3. AndroidMVP
  4. nginx报错The program 'nginx' can be found in the following packages
  5. [原创]java WEB学习笔记91:Hibernate学习之路-- -HQL 迫切左外连接,左外连接,迫切内连接,内连接,关联级别运行时的检索策略 比较。理论,在于理解...
  6. 调用 ogc_area 时参数个数或类型错误_Python10函数参数
  7. php ini set开启方法,php ini_set更改php.ini配置功能_PHP教程
  8. Talib技术因子详解(七)
  9. c语言数学函数库根号程序,数学函数8.2.3次方与开根号C语言入门经典.ppt
  10. powerbi嵌入到HTML5,如何把Power BI嵌入到Web应用中
  11. 力扣LeetCode刷题8 机器人大冒险
  12. Ubuntu神奇地变成了只读文件系统的错误--修复方法
  13. 机器的崛起:隐藏的控制论历史(二)
  14. 2021年度IT吃瓜指南
  15. yml中${}的意思
  16. 基于FME的水库功能分区生态红线批量处理方案(从文本到gdb)
  17. Leetcode.463 岛屿的周长
  18. 3d 打印模型下载网站
  19. datagrip 设置查询结果显示行数
  20. CVPR2022学习-人脸识别:An Efficient Training Approach for Very Large Scale Face Recognition

热门文章

  1. 1131 Subway Map
  2. 居于ERP的普遍失败,再论企业管理与信息化
  3. 五十分钟带你看遍C语言初阶语法(总纲)
  4. Hibernate入门4.核心技能
  5. 一个简单的网页计算器-php网站建设代码段分享
  6. 用股票交易量查询接口是怎么查询a股全天总成交量的?
  7. Proxmox VE(PVE)连接WiFi及一些配置
  8. iOS和Android跨平台移动应用开发解决方案
  9. SwiftUI 中的水平条形图
  10. [Win11] ImportError: DLL load failed while importing _multiarray_umath: 找不到指定的模块 Conda无法激活环境