最新文章:

首页 运维技术

分布式开发Zookeeper实现集群管理

发布时间:2017年03月20日 评论数:抢沙发 阅读数:5982

    说到分布式开发Zookeeper是必须了解和掌握的,分布式消息服务kafka 、hbase 到hadoop等分布式大数据处理都会用到Zookeeper,所以在此将Zookeeper作为基础来讲解。

    Zookeeper 是分布式服务框架,主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等等。

    Zookeeper 的核心是广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。

    Zab协议有两种模式,它们分别是恢复模式(选主)和广播 模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后, 恢复模式就结束了。

    状态同步保证了leader和Server具有相同的系统状态。为了保证事务的顺序一致性,zookeeper采用了递增的事务id号 (zxid)来标识事务。

    所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用 来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递 增计数。

    每个Server在工作过程中有三种状态:

    LOOKING:当前Server不知道leader是谁,正在搜寻。

    LEADING:当前Server即为选举出来的leader。

    FOLLOWING:leader已经选举出来,当前Server与之同步。

    一步到位分布式开发Zookeeper实现集群管理

    ZooKeeper的安装模式分为三种,分别为:单机模式、集群模式和集群伪分布模式

    环境

    CentOS7.0 (windows中使用就使用zkServer.cmd)

    ZooKeeper最新版本

    用root用户安装(如果用于hbase时将所有文件权限改为hadoop用户)

    Java环境,最好是最新版本的。

    分布式时多机间要确保能正常通讯,关闭防火墙或让涉及到的端口通过。

    下载

    去官网下载 :http://zookeeper.apache.org/releases.html#download

    下载后放进CentOS中的/usr/local/ 文件夹中,并解压到当前文件中 /usr/local/zookeeper(怎么解压可参考之前的Haproxy的安装文章)

    安装

    单机模式

    进入zookeeper目录下的conf子目录, 重命名 zoo_sample.cfg文件,Zookeeper 在启动时会找这个文件作为默认配置文件:

    mv /usr/local/zookeeper/conf/zoo_sample.cfg zoo.cfg

    配置zoo.cfg参数

    # The number of milliseconds of each tick 
    tickTime=2000 
    # The number of ticks that the initial 
    # synchronization phase can take 
    initLimit=10 
    # The number of ticks that can pass between 
    # sending a request and getting an acknowledgement 
    syncLimit=5 
    # the directory where the snapshot is stored. 
    # do not use /tmp for storage, /tmp here is just 
    # example sakes. 
    dataDir=/usr/local/zookeeper/data 
    dataLogDir=/usr/local/zookeeper/log 
    # the port at which the clients will connect 
    clientPort=2181 
    # # Be sure to read the maintenance section of the 
    # administrator guide before turning on autopurge. 
    # #http://zookeeper.apache.org/doc/current/zookeeperAdmin.html
    #sc_maintenance 
    # # The number of snapshots to retain in dataDir 
    #autopurge.snapRetainCount=3 
    # Purge task interval in hours # Set to "0" to disable auto purge feature 
    #autopurge.purgeInterval=1

    参数说明:

    tickTime:毫秒值.这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。

    dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。

    dataLogDir:顾名思义就是 Zookeeper 保存日志文件的目录

    clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

    再创建上面配置的data和log文件夹:

    mkdir /usr/local/zookeeper/data mkdir /usr/local/zookeeper/log

    启动zookeeper

    先进入/usr/local/zookeeper文件夹

    cd /usr/local/zookeeper

    再运行

    bin/zkServer.sh start

    检测是否成功启动:执行

    bin/zkCli.sh 或 echo stat|nc localhost 2181

    伪集群模式

    所谓伪集群, 是指在单台机器中启动多个zookeeper进程, 并组成一个集群. 以启动3个zookeeper进程为例,模拟3台机。

    将zookeeper的目录多拷贝2份:

    zookeeper/conf/zoo.cfg文件与单机一样,只改为下面的内容:

    tickTime=2000 initLimit=5 syncLimit=2 dataDir=/usr/local/zookeeper/data dataLogDir=/usr/local/zookeeper/log clientPort=2180 server.0=127.0.0.1:2888:3888 server.1=127.0.0.1:2889:3889 server.2=127.0.0.1:2890:3890

    新增了几个参数, 其含义如下:

    1 initLimit: zookeeper集群中的包含多台server, 其中一台为leader, 集群中其余的server为follower. initLimit参数配置初始化连接时, follower和leader之间的最长心跳时间. 此时该参数设置为5, 说明时间限制为5倍tickTime, 即5*2000=10000ms=10s.

    2 syncLimit: 该参数配置leader和follower之间发送消息, 请求和应答的最大时间长度. 此时该参数设置为2, 说明时间限制为2倍tickTime, 即4000ms.

    3 server.X=A:B:C 其中X是一个数字, 表示这是第几号server. A是该server所在的IP地址. B配置该server和集群中的leader交换消息所使用的端口. C配置选举leader时所使用的端口. 由于配置的是伪集群模式, 所以各个server的B, C参数必须不同.

    参照zookeeper/conf/zoo.cfg, 配置zookeeper1/conf/zoo.cfg, 和zookeeper2/conf/zoo.cfg文件. 只需更改dataDir, dataLogDir, clientPort参数即可.

    在之前设置的dataDir中新建myid文件, 写入一个数字, 该数字表示这是第几号server. 该数字必须和zoo.cfg文件中的server.X中的X一一对应./usr/local/zookeeper/data/myid文件中写入0, /usr/local/zookeeper1/data/myid文件中写入1, /Users/apple/zookeeper2/data/myid文件中写入2.

    分别进入/usr/local/zookeeper/bin, /usr/local/zookeeper1/bin, /usr/local/zookeeper2/bin三个目录, 启动server。启动方法与单机一致。

    bin/zkServer.sh start

    分别检测是否成功启动:执行

    bin/zkCli.sh 或 echo stat|nc localhost 2181

    集群模式

    集群模式的配置和伪集群基本一致.

    由于集群模式下, 各server部署在不同的机器上, 因此各server的conf/zoo.cfg文件可以完全一样.

    下面是一个示例:

    tickTime=2000 initLimit=5 syncLimit=2 dataDir=/usr/local/zookeeper/data dataLogDir=/usr/local/zookeeper/log clientPort=2180 server.0=192.168.80.30:2888:3888 server.1=192.168.80.31:2888:3888 server.2=192.168.80.32:2888:3888

    示例中部署了3台zookeeper server, 分别部署在192.168.80.30, 192.168.80.31, 192.168.80.32上.

    需要注意的是, 各server的dataDir目录下的myid文件中的数字必须不同,192.168.80.30 server的myid为0, 192.168.80.31 server的myid为1, 192.168.80.32 server的myid为2

    分别进入/usr/local/zookeeper/bin目录, 启动server。启动方法与单机一致。

    这时会报大量错误?其实没什么关系,因为现在集群只起了1台server,zookeeper服务器端起来会根据zoo.cfg的服务器列表发起选举leader的请求,因为连不上其他机器而报错,那么当我们起第二个zookeeper实例后,leader将会被选出,从而一致性服务开始可以使用,这是因为3台机器只要有2台可用就可以选出leader并且对外提供服务(2n+1台机器,可以容n台机器挂掉)。

    ZooKeeper服务命令

    1. 启动ZK服务: zkServer.sh start 2. 查看ZK服务状态: zkServer.sh status 3. 停止ZK服务: zkServer.sh stop 4. 重启ZK服务: zkServer.sh restart

    zk客户端命令:

    ZooKeeper 命令行工具类似于Linux的shell环境,使用它可以对ZooKeeper进行访问,数据创建,数据修改等操作.

    使用 zkCli.sh -server 192.168.80.31:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。命令行工具的一些简单操作如下:

    1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容 2. 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据 3. 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串 4. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串 5. 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置 6. 删除文件: delete /zk 将刚才创建的 znode 删除 7. 退出客户端: quit 8. 帮助命令: help

    扩展

    通过上述命令实践,我们可以发现,zookeeper使用了一个类似文件系统的树结构,数据可以挂在某个节点上,可以对这个节点进行删改。另外我们还发现,当改动一个节点的时候,集群中活着的机器都会更新到一致的数据。

    zookeeper的数据模型

    在简单使用了zookeeper之后,我们发现其数据模型有些像操作系统的文件结构,结构如下图所示

    一步到位分布式开发Zookeeper实现集群管理

    (1) 每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识,如/SERVER2节点的标识就为/APP3/SERVER2

    (2) Znode可以有子znode,并且znode里可以存数据,但是EPHEMERAL类型的节点不能有子节点

    (3) Znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本。

    (4) znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和 服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了

    (5) znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2

    (6) znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等等。

    选举流程

    当 leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的 Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos。

    basic paxos流程:

    1 .选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;

    2 .选举线程首先向所有Server发起一次询问(包括自己);

    3 .选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;

    4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;

    5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。

    通 过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于 n+1.每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信 息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。

    应用场景

    是指通过指定的名字来获取资源或者服务的地址,提供者的信息。利用Zookeeper很容易创建一个全局的路径,而这个路径就可以作为一个名字,它可以指向集群中的集群,提供的服务的地址,远程对象等。简单来说使用Zookeeper做命名服务就是用路径作为名字,路径上的数据就是其名字指向的实体。

    阿里巴巴集团开源的分布式服务框架Dubbo中使用ZooKeeper来作为其命名服务,维护全局的服务地址列表。在Dubbo实现中:

    服务提供者在启动的时候,向ZK上的指定节点/dubbo/${serviceName}/providers目录下写入自己的URL地址,这个操作就完成了服务的发布。

    服务消费者启动的时候,订阅/dubbo/{serviceName}/providers目录下的提供者URL地址, 并向/dubbo/{serviceName} /consumers目录下写入自己的URL地址。

    注意,所有向ZK上注册的地址都是临时节点,这样就能够保证服务提供者和消费者能够自动感应资源的变化。

    另外,Dubbo还有针对服务粒度的监控,方法是订阅/dubbo/{serviceName}目录下所有提供者和消费者的信息。

    一步到位分布式开发Zookeeper实现集群管理
二维码加载中...
本文作者:Mr.linus      文章标题: 分布式开发Zookeeper实现集群管理
本文地址:http://www.90qj.com/424  百度暂未收录本文
版权声明:若无注明,本文皆为“挨踢 Blog”原创,转载请保留文章出处。
挤眼 亲亲 咆哮 开心 想想 可怜 糗大了 委屈 哈哈 小声点 右哼哼 左哼哼 疑问 坏笑 赚钱啦 悲伤 耍酷 勾引 厉害 握手 耶 嘻嘻 害羞 鼓掌 馋嘴 抓狂 抱抱 围观 威武 给力
提交评论

清空信息
关闭评论