Zookeeper快速入门

发布时间 2023-11-05 22:01:32作者: 小曾Study平台

Zookeeper快速入门

核心:1、zookeeper自己如何选主的?

​ 2、zookeeper如何帮别人选主的?

1、集群与分布式

一、集群:将一个任务部署在多个服务器,每个服务器都能独立完成该任务。
二、分布式:将一个任务拆分成若干个子任务,由若干个服务器分别完成这些子任务,每个服务器只能完成某个特定的子任务!但是容易出现单点故障,因此常搭建集群分布式。
总结:集群是通过提高单位时间内执行的任务数来提升效率,分布式是以缩短单个任务的执行时间来提升效率

2、技术架构演变

单体系统架构--->垂直系统架构--->粗粒度分布式--->细粒度分布式(容器)

单一系统架构

单体应用就是将应用程序打包成一个独立的单元,当流量很小时,只需要一个应用将所有功能都部署在一起,以减少部署节点和成本。
特点:
所有的功能集中在一个项目工程中;
所有的功能打成一个war包部署到服务器;
应用与数据库分开部署;
通过部署应用集群和数据库集群来提高系统的性能。
优点:
开发简单、易于测试、容易部署,便于共享
缺点:
妨碍持续交互、不够灵活、受技术栈限制、可靠性差、伸缩性差、技术债务

image-20231025092802662

垂直应用架构

将一个单一应用拆成互不相干的几个应用,来提升效率!
特点:
将单体结构规模为项目的单位进行垂直划分,就是将一个大项目拆分成一个个单体结构项目。
数据与数据之间耦合性比较大,数据冗余。
项目之间的接口多为数据同步功能。
优点:
开发成本低,架构简单
避免单体应用的无限扩大
系统拆分实现了流量分担,解决了并发问题。
可以针对不同系统进行扩容、优化。
方便水平扩展、负载均衡、容错率提高。
缺点:
系统之间调用,如果IP发生改变,需要手动更改。
垂直架构中的相同代码需要不断复制、不能复用。
系统性能扩展只能通过扩展集群节点,成本高,有瓶颈。

image-20231025094054388

SOA面向服务架构(粗粒度微服务架构)、

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽离出来,作为独立的服务,逐渐形成稳定的服务中心,当服务越来越多,小服务资源等问题逐渐凸显,此时需要增加一个调度中心基于访问压力实时管理集群容量,提高系统集群利用率。
特点:
基于SOA的架构思想将重复公用的功能抽取为组件,以服务的形式给各系统提供服务。
各项目与服务之间采用WebService、RPC等方式进行通信
使用ESB企业服务总线作为项目与服务之间通信的桥梁。

image-20231025095328272

微服务架构

特点:
将系统服务层完全独立出来,并将服务层抽取为一个一个的微服务;
微服务中每一个服务都对应唯一的业务能力,遵循单一原则。
微服务之间采用restful风格等轻量级协议传输。
优点:
团队独立、技术独立、前后端分离、数据库分离、服务拆分度更细、团队可以快速投入生产、微服务易于被一个开发人员理解、维护、修改和维护、可以更加精准定位每个服务的优化方案,提高系统可维护性、适用于互联网时代、产品迭代周期更短。
缺点:
微服务过多,服务治理成本高、不利于维护。
分布式系统开发的技术成本高,对于团队跳转大。
微服务将原来的函数式调用改为服务调用
多服务运维难度
测试的难度提升
微服务是一种架构风格,架构是为了解耦,实际使用的是分布式系统开发。
微服务是SOA发展出来的产物,它是一种比较现代化的细粒度的SOA实现方式。

image-20231025100234894

3、CAP原则

C:数据一致性
A:数据可用性(单位时间响应速度)
P:系统分区容错性(搭建集群实现数据同步)
Eric Brewer在2000年PODC会议提出,CAP三者不可兼得。
取舍策略:
CA:只满足数据一致性、可用性,就是单体系统架构,无法满足分区容错性,放弃了系统扩展性,分布式节点受限,无法部署子系统。
CP:只满足数据一致性、系统分区容错性,无法满足可用性,大多数银行支付系统采用的架构,来牺牲响应速度获取数据安全。
AP:只满足可用性、系统分区容错性,无法满足数据一致性,这也是大多数互联网公司采用的策略,比如:双十一时,淘宝秒杀活动,客户在访问产品时,为了提高系统的可用性,数据库集群没有数据同步,可能查询的数据的不一致,但在进行下单时,就进行数据同步实现数据一致性,可以过滤掉只看不买的客户,提高系统的响应速度。

总而言之,没有最好的策略,要根据实际应用场景,选择合适的策略!

image-20231025101828160

image-20231025101628613

4、BASE理论

BA:数据基本可用,允许分布式在出现故障的时候,允许损失部分可用性。需要注意的是,基本可用不等价于系统不可用。
  响应时间上的损失:正常情况下搜索引擎需要在0.5s之内返回给用户相应的查询结果,但由于出于故障,查询结果的响应时间增加到了1~2秒。
  功能损失:在双十一秒杀活动时,为了保护系统的稳定性,商城系统采用限流架构,部分消费者会被引导到一个降级页面。
  
S(soft state 软状态):允许系统存在中间状态,而该中间状态不会影响数据整体可用性,分布式存储中一般一份数据会有多个,允许不同副本数据同步的延时就是软状态,也就是实现数据的弱一致性。比如:redis的redlock,系统从一个带有红锁redis中获取数据,然后把获取的数据与redis副本进行比对,如果超过一半以上的redis副本数据一致就响应数据结果。

E(最终一致性):系统不可能一直处于软状态,在一定期限过后,最终实现数据同步的一致性,是弱一致性的一种特例。

模型

强一致性:无论更新操作在哪一个副本执行,之后所有的读操作都要获取到最终的数据,也就是所有的数据都要实现同步后才能读取。zookeeper采用的就是数据强一致性。
弱一致性:在执行更新操作时,允许有部分副本不进行数据更新,数据就可以进行查询响应。
最终一致性:在弱一致性的时间期限过后,最终所有的副本都要进行数据更新,是弱一致性的特例。

5、Paxos算法

前提:1、消息不能被篡改。2、节点之间相互信任

议员数是固定的,每个提议都有一个pid单调递增,每个提议超过半数才能生效,每个议员只会同意大于当前pid的提议,提议包括生效和未生效,如果议员收到比当前记录的pid相等或小于的值就会拒绝投票,并告诉提议已提过。发起提议的议员收到超过半数的回复,立即给所有人发通知:提议生效。

image-20231026085028387

image-20231026085305293

冲突:假设s1、s2、s3议员,s1发出一号提议给s3,s3的pid更新为1,s2同样发出一号提议给s3,s3发现一号提议s1已经提过,拒绝这个倡议并表示这个提议已经提过。

解决:s2在提议前先向s1、s3打听并更新一号提议,然后继续发起2号提议。

image-20231026085813360

运用到分布式集群中概念替换:

小岛:服务器集群

议员:单台服务器

居民:客户端

议员总数是确定的:为了超过半数

提议:每次对集群节点数据的修改

每个提议都有一个pid,这个pid单调递增:唯一标识

每个提议超过半数同意生效:数据最终一致性

每次议会不能保证所有议员pid都相同:网络传输异常

最终目标:保证所有议员对于提议都能达成一致看法(弱一致性----->最终一致性)

议员给所有人发通知生效:广播传递

  • 无主模式

人人都能发出指令、投票,投票人数可能导致分区,事务编号就会导致混乱,每个节点都有可能有自己的提议,当议员下线重启时,议员进行数据同步时,要从多个节点同步。

活锁状态:当有两个客户端依次提出一系列相同pid编号递增的提案,就会陷入死循环。

image-20231026091952662

  • 最终模型:有主模式+奇数台

所有的提议都进入主机的队列中,主机从队列中依次提取提议向从机发起请求,主机收到半数以上的从机的投票请求,就使用广播向所有从机发起更新数据、提议生效通知,所有服务器增加pid值并与公共pid保持同步,保证了数据一致性。

解决了活锁问题,也解决了服务器宕机重启同步数据的问题(如果无主模式,重启后的服务器无法知道哪个服务器数据完整,有主模式,直接向主机进行数据同步)。

image-20231026093930547

有主模式下主机宕机如何选主:所有候选服务器投票ID值最大的服务器,超过半数投票通过,新的主机选举产生,新产生的主机就会标识term(朝代)。

image-20231026094621730

问题:如果主机过多都参与选举,性能就会下降。

  • 基于角色的有主模式+奇数台

有三种角色:主机、从机、观察者

主机:数据读写

从机:投票选主机、读数据

观察者:读数据

当服务器数量过多,选出合适奇数台候选服务器,候选服务器参与投票选出主机,剩下的就是从机,不是候选服务器的就是观察者服务器,观察者服务不参与主机选举过程,只读取并同步主机的数据,来响应客户端的请求,这样就可以解决因服务器过多,选举主机时性能下降问题。

6、ZAB协议(Paxos算法精简版)

概念:数据库二段提交

专有名词:binlog(最终持久化)、redolog(实时落盘,崩溃恢复)、undolog(事务回滚)

核心内容:数据库在数据提交时,突然宕机,数据就会实时落盘程redolog,当数据库再次重启时,就会执行redolog日志,执行成功后,写入binlog中进行数据持久化,然后执行结果响应(awck)回来,进行删除redolog操作,防止重复执行redolog日志。

事务回滚:数据反向操作。如:数据库把数据从18更新到22,然后进行回滚操作时,把22更新为18.

  • ZAB三个阶段:
  1、发现:zookeeper集群必须选择出一个leader进程,同时leader会维护一个follower可用列表,客户端与follower进行通信。
  2、同步:leader要负责与本身数据与follower完成同步,做到多副本存储。follower将队列未处理完的请求消费完成后,写入本地事物日志中。
  广播:leader接受客户端新的proposal请求,将新的proposal请求广播给所有的follower(不完全二段提交)。
  • 核心内容:
ZAB定义事务请求的处理方式:所有的事务请求必须有一个全局唯一的服务器来协调处理,这是leader服务器,其他都是follower服务器;leader服务器负责将客户端事务请求,转换为一个事务Proposal,并将Proposal分发给集群中所有follower服务器,也就是向所有follower服务器发送广播请求实现数据同步;leader服务器分发之后,就等待follower服务器的反馈响应(ACK请求),收到了一半以上的follower服务器反馈后,leader服务器就会再次向follower服务器发送commit请求,要求follower服务器进行事务的提交。
  • 角色
leader:主机
cluster:zookeeper集群
learner:follower(从机)、observer(观察者)
Proposal:节点的改变
Zxid:提议编号单调递增。
clinet:客户端
法令:所有ZNode及其数据

7、Zookeeper集群搭建

  • 下载apache-zookeeper-*.*.*-bin.tar.gz包并上传到服务器,地址:https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.9.1/apache-zookeeper-3.9.1-bin.tar.gz
  • 解压到指定文件夹下
tar -zxvf  apache-zookeeper-3.9.1-bin.tar.gz  -C /usr/local/zookeeper/
  • 创建zookeeper数据存放目录dataDir、日志存放目录dataLogDir
mkdir -p /var/zookeeper/data
mkdir -p /var/zookeeper/logs
  • 进入解压包的config目录下,修改配置文件
cd /usr/local/zookeeper/apache-zookeeper-3.9.1/config/
cp zoo.simple.cfg  zoo.cfg
vim zoo.cfg
  • zoo.cfg内容如下:
dataDir=/var/zookeeper/data
dataLogDir=/var/zookeeper/logs
#配置集群
server.1=192.168.147.110:2888:3888
server.2=192.168.147.120:2888:3888
server.3=192.168.147.130:2888:3888
  • 其中1、2、3是每个zookeeper的myid值,myid文件存在data目录下!数字要对应相应主机IP的zookeeper服务器。

  • 设置myid值(在192.168.147.110主机上操作)

touch /var/zookeeper/data/myid
echo 1 > /var/zookeeper/data/myid
  • 配置环境变量
vim  /etc/profile
  • profile内容如下:
export ZOOKEEPER_HOME=/usr/local/zookeeper/apache-zookeeper-3.9.1/
export PATH=${ZOOKEEPER_HOME}/bin;${PATH}
  • 环境生效
source /etc/profile

其他服务器也同样以上配置,为了加快速度,可以编写脚本执行!

rsync -av  /usr/local/zookeeper/zookeeper-***/config/zoo.cfg root@192.168.147.120: /usr/local/zookeeper/zookeeper-***/config  #同步配置文件
rsync -av  /usr/local/zookeeper/zookeeper-***/config/zoo.cfg root@192.168.147.130: /usr/local/zookeeper/zookeeper-***/config  #同步配置文件

开放端口号(每台主机都要开放)

firewall-cmd --permanent --zone=public --add-port=2181/tcp,2888/tcp,3888/tcp
firewall --reload

启动zookeeper

zkServer.sh start

windows下载可视化工具(prettyZoo)中msi文件,下载地址:https://github.com/vran-dev/PrettyZoo/releases

image-20231026112716428

关于选主问题:

如果依次启动zookeeper服务器,第二个启动的主机会被选举leader主机
如果同时启动zookeeper服务器,最后启动主机会被选举leader主机

在window上编写好的脚本,在linux中使用dos2unix filename.sh 命令转换成linux可执行的脚本字符编码进行执行。

  • 一键启动、停止、查看ZK集群脚本:
#!/bin/bash

case $1 in
"start")
for host in node1 master node2
do
   ssh root@${host} "${ZOOKEEPER_HOME}/bin/zkServer.sh start"
done
;;
"stop")
   for host in node1 master node2
do
   ssh root@${host} "${ZOOKEEPER_HOME}/bin/zkServer.sh stop"
done
;;
"status")
for host in node1 master node2
do
   ssh root@${host}  "${ZOOKEEPER_HOME}/bin/zkServer.sh status"
done
;;
esac

执行脚本时出现找不到命令情况,需要在/root/.bashrc中追加脚本全路径名

cat [脚本全路径]  >> ~/.bashrc

8、ZooKeeper常见命令

一、zk服务命令

zkServer.sh start #启动zk服务
zkServer.sh status #查看zk状态
zkServer.sh stop  #停止zk

二、zk客户端命令

ls  /  #查看根节点下的所有节点
create /znode  "value"  #创建节点并赋值,默认创建持久节点
create -s /znode  #创建顺序节点,名字全局递增
create -e /znode #创建临时节点
create  /znode/pnode   #临时节点不能有子节点,创建子节点需要一级一级去创建
zkCli.sh [-server host:port]  #客户端访问zk,默认访问本地服务
quit #关闭客户端
close #关闭连接并没关闭客户端
connect [host:port] #重新连接

三、操作节点数据

get /znode #获取节点下的值
set /znode value #设置或修改节点下的值
delete /znode #删除节点下的值
delete /path  #删除没有子节点的节点
rmr /path #移除节点并且递归移除所有子节点
stat /zNode #查看节点状态

9、Zookeeper存储模型

zookeeper是一个树状结构,维护一个小型的数据节点znode
数据以keyvalue的方式存在,目录是数据的key
所有的数据访问都必须以绝对路径的方式呈现

image-20231026163005018

  • 读取节点状态信息
666 当前节点的值
cZxid = 0xf00000013
创建这个节点的事务id,ZXID是一个长度64位的数字,
低32位是按照数字递增,即每次客户端发起一个proposal,低32位的数字简单加1。
高32位是leader周期的epoch编号
ctime = Mon Dec 09 17:33:06 CST 2019 创建时间
mZxid = 0xf00000013 最后一次修改节点数据的事务ID
mtime = Mon Dec 09 17:33:06 CST 2019 修改时间
pZxid = 0xf00000014 子节点的最新事务ID
cversion = 1 对此znode的子节点进行的更改次数
dataVersion = 对此znode的数据所作的修改次数
aclVersion = 对此znode的acl更改次数
ephemeralOwner = 0x0 (持久化节点)0x16ee9fc0feb0001(临时节点)
dataLength = 3 数据的长度
numChildren = 1 子节点的数目
  • 节点分类
持久化节点(PERSISTENT)
    默认创建的就是持久化节点 create -p 
临时节点(Ephemral)
只要创建节点的会话有效,节点就不会失效
可以被所有的客户端所查看
事务编号和临时节点编号是一致的
    create -e
一旦会话结束,临时节点也会被自动删除,一般这个功能用于判断节点和服务器是否保持连接
序列化节点(Sequential)
   在名字的后面添加一个序列号(有序)
create -s

10、监听机制

语法格式:addWatch [-m mode] path
[mode:]
persistent:持久化订阅:针对当前节点的删除和修改事件触发监听,以及子节点的新增和删除事件触发监听,唯独子节点更新操作不会触发监听。
persistent_recursive:持久化递归订阅:当前节点删除和修改事件触发,以及子节点新增、删除、更新操作触发,并且子节点的子节点数据所有变动都会触发监听

11、权限管理

语法格式:
getAcl /zNode  #查看节点权限
setACl /zNode  #设置节点权限
addauth digest  user:password #添加用户
#设置用户名user密码password的用户可以对/zNode节点读创建写入删除 设置节点权限前要先添加用户,否则无法设置
setAcl  /zNode auth:user:password:rcwd   #设置只有用户名为user密码为password的用户才有权限
setAcl /zNode world:anyone:r  #设置/zNode所人都可以读
quit #退出登录
后续访问/Znode 需要先添加用户 
addauth digest user:password #添加用户才能访问/zNode
  • 权限内容
zk节点有五种操作权限:
write:w 写
create:c 创建
read:r 读取
admin:a 管理
delete:d 删除
身份认证有四种方式: 
world:默认方式,相当于所有人都可以访问
auth:代表通过认证的用户可以访问
digest:代表登录的用户可以访问,最常用  
ip:使用Ip地址访问

12、四字命令

  • 在zoo.cfg文件加入
4lw.commands.whitelist=*
  • 安装nc依赖包
yum install -y nc
  • 语法使用
echo [四字命令]|nc node1 2181

image-20231026160159829

13、复杂的环境搭建

配置观察者模式(paxos算法中的基于角色的有主模式,有角色的人才能参与选举)

观察者不参与主机选举,只与主机同步数据,用户处理客户端响应,用于在服务器太多,造成选主效率低处理方案!
  • 在三台主机中zoo.cfg中配置如下:
peerType=observer
server.1=192.168.147.110:2888:3888:observer #把192.168.147.110节点设置为观察者

14、Raft算法

分布式共识协议

中文动图模拟网站:https://acehi.github.io/thesecretlivesofdata-cn/raft/

有三种角色:leader(主节点)、follower(从节点)、candidate(候选节点)
  • 选主模式
假设有三个节点,主节点在心跳超时时间内为从节点发送消息,其中两个节点没有收到主节点的请求,从节点维护选举超时时间(随机150ms-300ms),哪个从节点超过选举超时时间就变候选人,为自己投票,并向其他节点发起投票请求,重置其他节点选举超时时间,其他节点响应给候选节点,候选节点就成为主节点,其他节点就是从节点,主机在心跳超时时间内不断向从节点发起请求,重置从节点的选举超时时间,维持着主从节点的集群关系。
  • 日志复制
客户端将更改发送到主节点,在下一次心跳时将更改发送给从节点,一旦超过半数以上从节点响应认可,主节点就向从节点发送提交请求,并最终响应给客户端,没有半数以上从节点认可不会进行日志提交,只会追加到本地日志。
在遇到网络不好时,把节点分成两部分,有两个客户端发送到不同主节点上,由于其中一个主节点未收到过半的从节点响应,一直处于追加本地日志未提交状态,当网络恢复,未提交的节点进行日志回滚,并匹配新的主节点日志,进行日志复制。

image-20231026173633981

15、总结

zookeeper如何自己选主?

myid最大节点为自己投票,其他节点为myid最大节点投票,当接收到超过半数投票请求,最大myid节点成为leader,其他节点成为follower,然后所有的follower包括observer只有读数据的权限,leader有读写权限,然后follower以及observer向leader进行数据同步。
客户端发送请求先发送到leader节点队列中,leader节点依次获取请求发起投票请求,受到半数以上follower投票响应,就追加数据并向follower及observer发送原子广播通知,进行数据同步。

zookeeper如何为组件选主呢?

组件集群中的多个leader节点向zookeeper注册中心进行注册,先注册成功的获得分布式锁,zookeeper监听注册成功的leader节点,此时成功为集群leader节点,然后其他leader节点从zookeeper中获取集群leader节点的数据并同步各自的follower节点,一旦zookeeper监听到leader节点释放分布式锁(公平锁),就向其他leader节点发起注册请求,其他leader先成功注册的拿到分布式锁,然后zookeeper又开始监听节点,循环反复!