dsg

    科技2022-08-04  145

    zookeeper

    zk的介绍zk单机版的安装zk的命令javaAPI操作zkzk的架构znode的类型sessionWatcheszk的工作流程leader推选过程配置完全分布式zk集群hadoop集群交由zk管理配置RM的HA高可用自动容灾

    zk的介绍

    hadoop高可用配置HA的自动容灾(自动切换激活态)zookeeper是分布式协同服务,用于管理集群zookeeper是轻量级的进程,资源占用很小,一般是与其他进程一起的zookeeper是分布式应用,实现分布式读写技术zookeeper是以文件系统的层级结构存储数据,每个节点的数据大小不能超过1Mzookeeper提供了以下服务: Naming service(名称服务),按名称区分集群中的节点Configuration management(配置管理),对加入节点的最新化处理Cluster management(集群管理),实时感知集群中节点的增减Leader election(领导推选服务),leader选举Locking and synchronization service(分布式锁与同步服务),修改时锁定数据,实现容灾Highly reliable data registry(高可用数据注册表),节点宕机数据也是可用的

    zk单机版的安装

    安装jdk下载zookeeper-3.4.12.tar.gz,并上传到服务器上去跟命令走 #解压到soft目录下 tar -zvxf zookeeper-3.4.12.tar.gz -C /soft/ #配置环境变量 vi /etc/profile export ZK_HOME=/soft/zookeeper-3.4.12 export PATH=$PATH:$ZK_HOME/bin source /etc/profile #配置zk,如下面zoo.cfg所示,主要修改数据目录的存储地址 cd /soft/zookeeper-3.4.12/conf cp zoo_sample.cfg zoo.cfg #启动zk,启动日志默认放在bin目录下的zookeeper.out中 zkServer.sh start #启动成功查看进程会有一个QuorumPeerMain的进程 jps #关停zk zkServer.sh stop

    zoo.cfg的配置

    # 滴答的毫秒数 tickTime=2000 # 初始同步阶段滴答的次数 initLimit=10 # 在发送请求和得到确认的中间需要滴答的次数 syncLimit=5 # 数据目录(主要配置这个) dataDir=/home/zk/zookeeper # 对外连接端口 clientPort=2181

    zk的命令

    #启动客户端连接到服务器,端口默认2181,进入zk命令行 zkCli.sh -server Centos100:2181 #查看帮助 help #查看目标路径下的文件,系统里默认有一个路径/zookeeper/quota路径,[]表示没有关联数据 ls 目标路径 # 创建数据关联路径,将Tom关联到路径/a下,注意必须先创建父节点,才能创建子节点,没有递归创建,并且创建的路径必须要写数据,否则创建失败,参数:-s创建序列节点,-e创建临时节点,不加参数默认是持久节点 create /a Tom #查看目标路径下关联的数据以及数据信息 get /a # 修改路径下关联的数据,修改之后数据版本dataVersion会相应的加1 set /a tomas # 删除路径,注意当前目标路径下有子节点不能删除 delete /a/a1 #递归删除,目标路径下有子节点也能删除 rmr /a #切换连接源,先关闭当前连接源,但不退出命令 close connect Centos100:2181 #退出 quit

    javaAPI操作zk

    import org.apache.zookeeper.*; /** * 查询指定路径下的子节点(不递归) * @throws Exception */ public static void ls() throws Exception { //连接zookeeper,多个集群连接用“,”隔开 ZooKeeper zk = new ZooKeeper("192.168.200.100:2181,192.168.200.101:2181,192.168.200.102:2181",5000,null); //查看根路径下的子节点,不递归 List<String> list = zk.getChildren("/", null); for(String str: list){ System.out.println(str); } } /** * 递归查询指定路径下的所有子节点 * @param path * @throws Exception */ public static void lsAll(String path) throws Exception { ZooKeeper zk = new ZooKeeper("192.168.200.100:2181,192.168.200.101:2181,192.168.200.102:2181",5000,null); //查看根路径下的子节点,不递归 List<String> list = zk.getChildren(path, null); if(list != null && list.size() > 0) for(String str: list){ if(path.equals("/")){ System.out.println(path + str); lsAll(path + str); }else{ System.out.println(path + "/" + str); lsAll(path + "/" + str); } } } /** * 修改对应路径下关联的值 * @throws Exception */ public static void setdata() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.200.100:2181,192.168.200.101:2181,192.168.200.102:2181",5000,null); //版本必须跟之前的版本一致 zk.setData("/a","zhangsan".getBytes(),1); } /** * 创建节点 * @throws Exception */ public static void createnode() throws Exception { ZooKeeper zk = new ZooKeeper("192.168.200.100:2181,192.168.200.101:2181,192.168.200.102:2181",5000,null); /** * ACL: * OPEN_ACL_UNSAFE:完全开放的ACL * CREATOR_ALL_ACL:只有创建者的会话ID拥有所有权限 * READ_ACL_UNSAFE:只有读权限 * 节点类型: * PERSISTENT:永久节点 * PERSISTENT_SEQUENTIAL:永久序列节点 * EPHEMERAL:临时节点 * EPHEMERAL_SEQUENTIAL:临时序列节点 */ zk.create("/b","lisi".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } /** * 绑定观察者 * @param zk * @throws Exception */ public static void listenInfo(final ZooKeeper zk) throws Exception { ZooKeeper zk = new ZooKeeper("192.168.200.100:2181,192.168.200.101:2181,192.168.200.102:2181",5000,null); Watcher watcher = new Watcher() { @Override public void process(WatchedEvent event) { try { //观察者的方法调用一次就不会继续调用,所以需要后面不断注册观察者 byte[] data = zk.getData("/a", this, null); System.out.println(new String(data)); } catch (Exception e) { e.printStackTrace(); } } }; //第一次注册 byte[] data = zk.getData("/a", watcher, null); System.out.println(new String(data)); //保证程序塞着,不会死掉 while (true){ Thread.sleep(1000); } }

    zk的架构

    client 从server获取信息,周期性发送数据给server,表示自己还活着。client连接时,server回传ack信息。如果client没有收到reponse,自动重定向到另一个server。server zk集群中的一员,向client提供所有service,回传ack信息给client,表示自己还活着。ensemble 一组服务器。最小节点数是3leader 如果连接的节点失败,自动恢复,zk服务启动时,完成leader选举。follower 追寻leader指令的节点。znode zk中的节点,维护了stat,由Version number(版本号), Action control list (ACL访问控制列表),Timestamp(时间戳),Data length(数据长度)构成。

    znode的类型

    永久节点 client结束,还存在,所有节点默认都是永久节点临时节点-e 在client当前会话有效,会话断开自动删除。临时节点不能有子节点。leader推选时使用序列节点-s 在节点名之后附加10个数字,主要用于同步和锁。

    session

    Session中的请求以FIFO(先进先出)执行,一旦client连接到server,session就建立了。sessionid分配给client。client以固定间隔向server发送心跳,表示session是valid的,zk集群如果在超时时候,没有收到心跳,判定为client挂了,与此同时,临时节点被删除。

    Watches

    client能够通过watch机制在数据发生变化时收到通知。client可以在read节点时设置观察者。watch机制会发送通知给注册的客户端。观察模式只触发一次。session过期,watch机制删除了。

    zk的工作流程

    zk集群启动后,client连接到其中的一个节点,这个节点可以leader,也可以follower连通后,node分配一个id给client,发送ack信息给client如果客户端没有收到ack,连接到另一个节点client连通后,client会周期性发送心跳信息给节点保证连接不会丢失如果client读取数据,发送请求给node,node读取自己数据库,返回节点数据给client如果client存储数据,将路径和数据发送给node,node转发给leader。leader再补发请求给所有follower。只有大多数(超过半数)节点成功响应,则写操作成功。(读不需要请求leader,写需要请求leader)

    leader推选过程

    所有节点在同一目录下创建临时序列节点节点下会生成/xxx/xx000000001等序列节点序号最小的节点就是leader,其余就是follower.每个节点观察小于自己节点的主机。(注册观察者)如果leader挂了,对应znode删除了。观察者收到通知,会重新推选leader

    配置完全分布式zk集群

    挑选3台主机(奇数台)每台机器都安装zk(解压,配置环境变量)配置zk的配置文件,zoo.cfg,(每台机器配置相同) #在配置单机版的基础上再加上以下内容 #server.n,n是主机的编号,范围是1~255 #两个端口,第一个端口是节点作为leader时,供follower连接的端口;第二个端口是leader挂掉后,follower之间相互连接的端口,用于推选新的leader server.1=Centos100:2888:3888 server.2=Centos101:2888:3888 server.3=Centos102:2888:3888 在你配置的数据目录dataDir的路径下添加文件myid,文件的内容就是你刚才配置的对应的主机编号配置zk的日志输出目录,log4j.properties zookeeper.log.dir=/home/zk/log zookeeper.tracelog.dir=/home/zk/log 在每个节点主机下启动zk zkServer.sh start #查看zk的身份 zkServer.sh status

    hadoop集群交由zk管理

    hadoop交由zk管理可以实现自动容灾的功能 步骤:

    hadoop集群模式是HA高可用配置

    自动容灾引入两个组件,zk quarum + zk容灾控制器(ZKFC) 运行NN节点的主机还要运行ZKFC,主要负责以下任务:

    健康监控:ZKFC使用运行状况检查命令定期ping其本地NameNode。只要NameNode以健康状态及时响应,ZKFC就会认为该节点健康。如果该节点已崩溃,冻结或以其他方式进入不正常状态,则运行状况监视器将其标记为不正常。session管理:当本地NameNode运行状况良好时,ZKFC会在ZooKeeper中保持打开的会话。如果本地NameNode处于活跃状态,则它还将持有一个特殊的“锁定” znode。该锁使用ZooKeeper对“临时”节点的支持。如果会话过期,将自动删除锁定节点。选举:如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,则它本身将尝试获取该锁。如果成功,则表明它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于活动状态。故障转移过程类似于上述的手动故障转移:首先,如有必要,将先前的活动节点隔离,然后将本地NameNode转换为活动状态。

    停掉hadoop集群

    配置hdfs-site.xml,启用自动容灾

    <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>

    配置core-site.xml,指定zk的连接地址

    <property> <name>ha.zookeeper.quorum</name> <value>Centos100:2181,Centos101:2181,Centos102:2181</value> </property>

    分发这个两个文件到其他主机

    在zk中初始化HA状态

    #先启动zk zkServer.sh start #在任意一个NN主机上初始化HA到zk hdfs zkfc -formatZK #登录zk客户端查看HA是否初始化到zk zkCli.sh ls /

    启动hadoop集群

    start-all.sh #启动完之后NN主机上会多出一个进程DFSZKFailoverController容灾控制器

    配置RM的HA高可用自动容灾

    配置yarn-site.xml

    <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>cluster1</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>Centos100</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>Centos101</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>Centos100:8088</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>Centos101:8088</value> </property> <property> <name>yarn.resourcemanager.zk-address</name> <value>Centos100:2181,Centos101:2181,Centos102:2181</value> </property>

    分发配置文件到另外一个名称节点

    手动管理命令

    #查看状态 yarn rmadmin -getServiceState rm1 #切换状态 yarn rmadmin -transitionToActive rm1 yarn rmadmin -transitionToStandby rm1

    启动yarn

    yarn-daemon.sh start resourcemanager

    登录到http://192.168.200.100:8088/cluster/cluster查看

    Processed: 0.009, SQL: 8