闲扯两句, 个别学习一门新技术我当初会间接看文档,文档上的一些外围观点放到文章中,起因在于我心愿记录我的思考过程,同时也是锤炼本人浏览英文文档的能力。

概述

首先咱们关上bing搜索引擎,搜寻Zookeeper,有同学可能会问,你为什么让关上bing搜素引擎,而不是百度呢。那是因为目前在百度搜寻Zookeeper,第一页没找到官网:

然而你关上bing搜寻Zookeeper:

个人感觉百度的搜寻品质有变差的迹象,所以我最近用bing比拟多。

ZooKeeper is a high-performance coordination service for distributed applications. It exposes common services - such as naming, configuration management, synchronization, and group services - in a simple interface so you don't have to write them from scratch.

Zookeeper为分布式应用提供高性能协调服务,用简略的接口提供了许多服务,有域名服务、配置管理、分布式同步、组服务。

解读1: 域名服务、配置管理、分布式同步、组服务这四个似懂非懂.

解读2 为分布式应用提供了高性能的协调服务,高性能咱们是喜爱的,协调了啥?

再聊聊分布式吧

咱们再来聊聊服务端零碎架构的演进吧,最后的时候咱们的服务只在一台服务器上运行,缓缓的随着用户量的一直晋升,单机部署曾经无奈再满足访问量了。于是人们天然就想到了集群,即雷同的利用再部署一遍,由Nginx或其余中间件依据负载平衡算法将申请摊派到集群的机器上。然而为了谋求高牢靠,咱们不能将一个做单机集群,将利用在配置文件中改端口实现集群,然而这并不牢靠,如果这台计算机呈现了什么问题,整个服务都会变得不可用,为了不让鸡蛋放在一个篮子里,维持服务的高牢靠,咱们将服务在多台计算机上,这样就算一台计算机上的服务呈现了问题,服务还是可用的(当初咱们的服务还是一个单体利用),这也就是分布式部署,所以分布式并不一定要和微服务挂钩。

然而这又引入了新的问题:

  • 一个节点挂掉不能提供服务时如何被集群通晓并由其余节点接替工作
例子: 当数据量与访问量一直回升,单机的MySQL无奈再撑持零碎的访问量,咱们开始搭建集群,晋升数据库的拜访能力,为了减少可靠性,咱们多机部署,甚至多地部署。

一般来说增删改耗费的性能远小于查问的性能,所以咱们选若干台数据库节点做写入,对于用户的新增数据申请,会摊派到写节点,写节点写入实现要将这个数据扩散到其余节点, 但这里有一个问题就是如果写节点挂掉呢,那一个自然而然的操作是从从库中再选一个读库回应申请,同时将挂掉的结点从集群中剔除.

  • 在分布式的场景下如何保障工作只被执行一次。
例子: 分布式下的定时工作,在计算机A和B上都部署了服务,如何保障定时工作只执行一次。

这也就是Zookeeper的协调。

基本概念与设计指标

在设计指标外面能看到外围概念。
  • ZooKeeper is simple. (Zookeeper 是简略的)

ZooKeeper allows distributed processes to coordinate with each other through a shared hierarchical namespace which is organized similarly to a standard file system. The namespace consists of data registers - called znodes, in ZooKeeper parlance - and these are similar to files and directories. Unlike a typical file system, which is designed for storage, ZooKeeper data is kept in-memory, which means ZooKeeper can achieve high throughput and low latency numbers.

Zookeeper通过相似于文件系统的命名空间来实现对分布式过程的协调,命名空间是由一个一个数据寄存器组成,在Zookeeper中它们被称为znode, ZNode与文件系统的文件夹是类似的,然而Zookeeper抉择将数据保留在内存中,这意味着Zookeeper能够实现高吞吐和低提早。

这就是Zookeeper的命名空间,像不像Linux的文件系统, 一个典型的树结构, 其实你也能够类比到windows的文件系统,/是根目录,这是硬盘,上面是文件夹。像一个文件夹有多个子文件夹一样,一个znode也领有多个结点,以key/value模式存储数据。Znode有两种,分为长期节点和永恒节点,节点的类型在创立时被确定,并且不能扭转。 长期节点的生命周期依赖于创立它们的会话。一旦会话完结,长期节点将会被主动删除,当然也能够手动删除,长期节点不容许领有子节点。永恒节点的生命周期不依赖于会话,并且只有在客户端显式执行删除操作的时候,能力被删除。Znode还有一个序列化的个性,如果创立的时候指定的话,该Znode的名字前面会主动追加一个递增的序列号。序列号对于此节点的父节点来说是惟一的,这样便会记录每个子节点的创立的先后顺序。

Znode节点的个性:

  1. 兼具文件和目录特点 既像文件一样保护着数据、信息、工夫戳等数据,又像目录一样能够作为门路标识的一部分,并能够具备子Znode。用户对Znode具备增、删、改、查等操作
  2. Znode具备原子性操作 读操作将获取与节点相干的所有数据,写操作也将替换节点的所有数据
  3. Znode 存储数据大小有限度 每个Znode的数据大小至少1M,然而惯例应用中应该远小于此值。
  4. Znode 通过门路援用,门路必须是相对的。

  • ZooKeeper is replicated

    Like the distributed processes it coordinates, ZooKeeper itself is intended to be replicated over a set of hosts called an ensemble.

    The servers that make up the ZooKeeper service must all know about each other. They maintain an in-memory image of state, along with a transaction logs and snapshots in a persistent store. As long as a majority of the servers are available, the ZooKeeper service will be available.
    Clients connect to a single ZooKeeper server. The client maintains a TCP connection through which it sends requests, gets responses, gets watch events, and sends heart beats. If the TCP connection to the server breaks, the client will connect to a different server.

    如同被其协调的分布式应用一样,Zookeeper自身也维持了一致性,集群中的Zookeeper同步内存状态、以及长久化的日志和快照,只有大部分的服务器是可用的,那么对应的Zookeeper就是可用的。

    客户端连贯到单台Zookeeper,通过该连贯发送申请、获取响应、获取监听事件并发送心跳,如果客户端的连贯断开,客户端将会连贯到其余的Zookeeper上。

  • Conditional updates and watches

    ZooKeeper supports the concept of watches. Clients can set a watch on a znode. A watch will be triggered and removed when the znode changes. When a watch is triggered, the client receives a packet saying that the znode has changed.

    Zookeeper 反对监听的概念,客户端能够监听Znode,当节点被移除或者扭转的时候,会告诉监听的客户端,当节点产生扭转的时候将收到音讯。

小小总结一下

Zookeeper借助以上个性来实现下面咱们提到的性能个性:

  • 域名服务 将ip映射为服务名,如果咱们的服务集群中须要相互调用,那么咱们能够抉择将ip和域名存储到Zookeeper的节点中,在须要调用的时候去用域名来换取到对应的ip地址
  • 配置管理 动静刷新配置, 基于监听机制,咱们将配置文件存储在Znode中,利用监听对应的Znode,Znode扭转会将扭转推送给对应的利用。也就是动静刷新配置
  • 数据的公布与订阅 同样是基于监听机制
  • 分布式锁 不同主机上的过程竞争对立资源,能够借助Zookeeper做分布式锁,举一个例子在服务A身上配置的有定时工作,咱们集群部署为了保障定时工作A只在一台上跑,咱们能够借助分布式锁来实现这个工作。

    为了让咱们让咱们的服务实现更强的吞吐能力和高可用,咱们抉择了分布式部署,然而在计算机的世界里通常是通过某种技术手段解决一个问题,就会引入新的问题,分布式部署的过程中,咱们又遇到了新的问题,比方节点之间的协调(主从集群中选中Leader),资源的竞争问题,为了解决这些问题Zookeeper应运而生。

    为什么会将Zookeeper的官网文档拎进去呢,因为心愿将本人的学习过程也记录下来,我记得刚学Java Web的时候会去B站上找视频,然而我看视频的时候有的时候会想,视频作者是怎么得出这个论断的,他们是怎么得出Zookeeper能够这么用的,因为我想间接获取第一手的材料,有本人的思考过程。

先装起来

说了这么多,咱们先将zookeeper用起来再说。

本次咱们通过在Linux下进行装置部署, 国内进入Zookeeper官网下载比较慢,咱们通过镜像进行下载:

# 首先在cd 到usr下建zookeeper目录,而后在这个目录下建zk1、zk2、zk3.咱们本次做集群部署# zk1 上面执行上面命令 wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz --no-check-certificate # 解压tar -xzvf apache-zookeeper-3.7.1-bin.tar.gz# 而后创立data logs  目录mkdir data logs# 将zk1 上面的所有文件复制到 zk2 zk3 上面一份cp -r /usr/zookeeper/zk1/*  /usr/zookeeper/zk2/cp -r /usr/zookeeper/zk1/*  /usr/zookeeper/zk3/# zk1/data 上面建设myud 文件,此文件记录节点id,每个zookeeper节点都须要一个myid文件来记录节点在集群中的id,此文件只能由一个数字。echo "1" >> /usr/zookeeper/zk1/data/myidecho "2" >> /usr/zookeeper/zk2/data/myidecho "3" >> /usr/zookeeper/zk3/data/myid# 而后进入 apache-zookeeper-3.7.1-bin的conf文件夹上面,将配置文件zoo_sample.cfg重名为zoo.cfg。对该文件进行如下配置mv zoo_sample.cfg  zoo.cfg# 退出以下配置 dataDir 存储数据  dataLogDir 存储日志  clientPort 监听端口dataDir=/usr/zookeeper/zk1/data dataLogDir=/usr/ZooKeeper/zk1/logsclientPort=2181server.1=127.0.0.1:8881:7771server.2=127.0.0.1:8882:7772server.3=127.0.0.1:8883:7773#集群配置中模版为 server.id=host:port:port,id 是下面 myid 文件中配置的 id;ip 是节点的 ip,第一个 port 是节点之间通信的端口,第二个 port 用于选举 leader 节点# 第一个编辑完,咱们用复制指令将这个配置文件复制到zk2和zk3中。留神要改clientPort dataDir dataLogDir /usr/zookeeper/zk1/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start /usr/zookeeper/zk2/apache-zookeeper-3.7.1-bin/bin/zkServer.sh start /usr/zookeeper/zk3apache-zookeeper-3.7.1-bin/bin/zkServer.sh start # 失常启动会输入 Starting zookeeper ... STARTED 如果不释怀能够用jps指令进行监测

节点的增删改查

像是Redis 有Redis Cli一样,Zookeeper也有对应的客户端咱们借助这个客户端来实现创立节点操作。

  • 永恒节点
#连贯zk1/usr/zookeeper/zk1/apache-zookeeper-3.7.1-bin/bin/zkCli.sh -server 127.0.0.1:2181# 创立一个节点 dog 是key 123 是valuecreate /dog 123 # 获取目录中存储的值get /dog# 当初连贯zk2 获取dog节点/usr/zookeeper/zk2/apache-zookeeper-3.7.1-bin/bin/zkCli.sh -server 127.0.0.1:2181# 获取dog目录中存储的值 会发现可能获取的到get /dog
  • 长期节点

    # 连贯zk1 创立长期节点 -e 代表长期节点create -e /dog/cat  123# 连贯zk2 获取/dog/catget /dog/cat# 在zk1中输出quit指令,断掉以后会话quit# 在zk2就获取不到了

  • 经典案例基: 基于Znode长期程序节点+Watcher机制实现偏心分布式锁

原理如下:

申请A首先来到Zookeeper申请创立长期程序节点,Zookeeper为申请A生成节点,申请A查看lock目录下本人的序号是否最小,如果是代表加锁胜利,B监听节点程序值小于本人的节点的变动,如果A执行则B去获取锁,如果有C、D等更多的客户端监听,情理是一样的。

create -s -e /dog/pig  s #在dog下创立长期程序节点# 返回值Created /dog/pig0000000001 

写在最初

其实Zookeeper还有其余性能,如下:

  • 数据的公布和订阅
  • 服务注册与发现
  • 分布式配置核心
  • 命名服务
  • 分布式锁
  • Master 选举
  • 负载平衡
  • 分布式队列

这里只介绍了根本的概念和利用,心愿会对大家学习Zookeeper有所帮忙,放英文正文也是晋升本人浏览英文技术文档的程度。

参考资料

  • 从0到1详解ZooKeeper的利用场景及架构 微信公众号 腾讯技术工程
  • zookeeper 知识点汇总 https://www.cnblogs.com/reycg...
  • zookeeper入门 https://zookeeper.readthedocs...
  • Nginx负载平衡当其中一台服务器挂掉之后,Nginx负载将会怎么呢? https://blog.csdn.net/Tomwild...
  • 基于zookeeper的MySQL主主负载平衡的简略实现 https://www.cnblogs.com/TomSn...