Zookeeper 入门指北

Zookeeper 是一个分布式调度服务,用来解决分布式系统中的统一调度问题。开发一个分布式系统是一件很困难的事情,主要原因就是因为我们没办法去很有效的处理分布式系统中部分服务失败的问题。在一个分布式系统中,不同机器间是需要互相通信的,并且由通信方发起到被通信方,然后结果要由被通信方回应。这时候假如被通信方因为机房故障或者断电网络等一些因素,没办法通知,这样通信方就不知道发生了什么,这样整个集群就发生了部分失败的故障。Zookeeper 提供了一些工具能够让分布式应用安全合理的处理部分失败的问题。

安装和启动

Zookeeper 的运行有两种方式,一种是 Standalone,还有一个就是 Replicated。这两种的区别就是第一种只部署了单个节点,而且第二种就是以集群的方式来部署。当以集群来部署的时候,客户端不需要连接所有的服务端,只需要连接其中一个就可以获得一致性的读写服务。

下载

到 Apache Zookeeper 的下载页面下载安装包,并且解压出来:

wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz
tar -xzvf zookeeper-3.4.11.tar.gz
cd zookeeper-3.4.11

启动

启动一个 Standalone 的服务很简单,只需要一个配置文件并且放到 conf/zoo.cfg 下面即可,在 conf 目录下 Zookeeper 已经有一个默认的文件了,直接复制过来即可,内容大概是这样:

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181

其中 tickTime 是基本时间单元,以毫秒为单位,用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime 。然后启动:

bin/zkServer.sh start

HelloWorld

每个程序的第一步都是跑一个 HelloWorld,Zookeeper 也不例外,输入以下的命令:

echo ruok | nc localhost 2181

你应该会看到:

imok

快速入门

Zookeeper 的数据存储就类似是一个文件系统,但是没有文件和文件夹的概念,取而代之的是以 znode 来标示的。这个 znode 既是数据的容器,也是其他节点的容器,也就是说 znode 可以存储数据和其他 znode (可以理解为文件和文件夹,znode 就是文件夹,里面的数据就是文件,唯一不同的是一个 znode 只能有一个数据,但是可以有多个其他的 znode),可以看一下图:

Zookeeper 自带了一个命令行的客户端,我们可以通过该命令行来操作一下,首先连接到 Zookeeper:

bin/zkCli.sh -server 127.0.0.1:2181

你应该可以看到以下,并且光标一直在闪烁等待输入,可以使用 ls / 命令简单操作一下。

Welcome to ZooKeeper!
[zk: 127.0.0.1:2181(CONNECTED) 0]

在 Zookeeper 中,ZNode 可以分为持久节点和临时节点两类。持久节点是指一旦这个 ZNode 被创建了,除非主动进行删除操作,否则将一直保存在ZooKeeper上;临时节点就是和客户端会话绑定,一旦客户端断开链接,那么这个客户端创建的所有临时节点都会被移除。

创建 znode

[zkshell: 9] create /zk_test my_data
Created /zk_test

其中的/zk_test是 znode 的名字,my_data是具体存储的数据,创建成功之后可以用 ls / 来查看一下:

[zkshell: 11] ls /
[zookeeper, zk_test]

获取数据

接下来,通过运行get命令来验证数据是否与znode相关联,如下所示:

[zkshell:12] get / zk_test 
my_data 
cZxid = 5 
ctime = Fri Jun 05 13:57:06 PDT 2009 
mZxid = 5 
mtime = Fri Jun 05 13:57:06 PDT 2009 
pZxid = 5 
cversion = 0 
dataVersion = 0 
aclVersion = 0 
ephemeralOwner = 0 
dataLength = 7 
numChildren = 0

更新数据

[zkshell:14] set / zk_test junk 
[zkshell:15] get / zk_test 
junk 

为了方便阅读,去除掉了部分无关的数据显示。

删除数据

接下来删除掉刚才创建的 znode,注意如果该 znode 下有其他的 znode,则无法删除,必须要先把其他的删除了。

[zkshell:16] delete / zk_test 
[zkshell:17] ls / 
[zookeeper] 

集群部署

在开发和测试环境中我们可以以 Standalone 的方式来运行,但是如果要部署到生产环境那么就应用以 Replicated 的方式来部署以获得更高的可用性。在该模式下至少需要三台服务器,并且强烈建议要有一个奇数的服务器。如果你只有两台服务器,那么就会有这样一种情况,如果其中一台服务器出现故障,就会没有足够的机器来形成大多数投票决策,两台服务器本质上不如 一台服务器稳定,因为有两个单点故障。修改配置文件:

tickTime = 2000 
dataDir = /var/lib/zookeeper 
clientPort = 2181 
initLimit = 5 
syncLimit = 2 
server.1 = zoo1:2888:3888 
server.2 = zoo2:2888:3888 
server.3 = zoo3:2888:3888

如果有三台机器的话,每台机器都要这样的配置。然后还要到/var/lib/zookeeper新建一个myid的文本文件,内容就是server.X中的X。接下来就可以按照正常方式启动了,启动之后 Zookeeper 会自动投票选举出一个 Leader,其他的机器就是 Follower

ACL 权限

在 Linux 的文件系统中,权限是以组和用户来表示的,在 Zookeeper 有他自己的一套 ACL 权限用来控制客户端的访问权限(类似用户对资源是否有读写权限),通过鉴权来获得客户端的身份(类似账号密码登录)。它本身的 ACL 机制是以 scheme:id:permissions来表示的,第一个字段表示采用哪种机制,第二个 id 表示用户,permissions表示相关权限(如只读,读写,管理等)。Zookeeper 总共提供了五中的 scheme :

  • world: 下面只有一个 id 叫做 anyone,Zookeeper 中开放所有权限的结点就是 world:anyone
  • auth: 它不需要id, 只要是通过认证的用户都有权限
  • digest: 它对应的 id 为 username:BASE64(SHA1(password)),它需要先通过 username:password 形式的认证
  • ip: 它对应的 id 为客户机的 IP 地址,并且可以设置成一个 IP 段比如 ip:192.168.1.0/16
  • super: 在这种scheme下,对应的 id 拥有超级权限

只是 ACL 毕竟是简单的访问控制,并非完整的权限管理,还是有很多局限性。比如 ACL 没有继承机制,所有的 ZNode 创建后都需要重新设置 ACL 而无法继承上一级的。

基本实例

在对 ZooKeeper 有了一个简单的了解以后,我们就可以用 Zookeeper 来构建一个简单的配置管理服务。集群中的机器可以通过 ZooKeeper 共享一个通用的配置数据,并且可以提供检索和更新配置的服务,我们会用 PHP 语言来实现。

安装扩展

PHP 在操作 Zookeeper 的时候是需要安装一个扩展的,我们可以到 PECL 上面去下载。要注意的是该扩展要依赖一个 C 语言编写的客户端,Zookeeper 已经内置好了,进去 zookeeper-3.4.11/src/c 的目录下,编译安装即可。

配置服务

接下来我们要新建一个 /config 的节点,把所有的配置都放到该节点下,很简单:

[zkshell: 9] create /config my_data
Created /config

我们设计用 ZNode 来存储配置的 key-value 键值对,我们在 ZNode 中存储一个 String 类型的数据作为 value,用 ZNode 的 path 来表示 key。定义一个客户端来读取数据,并且通过 CLI 的方式运行起来,代码不能再简单了:

$zc = new Zookeeper();
$zc->connect('localhost:2181');

$path = '/config/key1';
$zc->get($path, function($i, $type, $key) use ($zc, $path){
    echo $key."\n";
    echo $zc->get($path);
});

while(true){
    echo ".\n";
    sleep(1);
}

然后通过 Zookeeper 自带的命令行客户端来修改一下配置并且切换回去 PHP CLI 的控制台终端窗口应该就可以看到。

传图片麻烦,就不上图了

我们所实现的程序目前都是假设网络稳定的情况下实现的,但是一个真实的情况是,网络环境是会有很多原因导致不稳定的,这里不会讲述如何正确的处理这些失败。

微信与订阅号,欢迎关注 :smile:
file

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 2年前 加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!