Apache ZooKeeper 速成课程
在过去的几十年里,互联网改变了我们的生活方式。通过互联网提供的服务通常由复杂的软件系统支持,经常跨过地理位置分开的大量服务器。这样的系统在计算机科学术语上被称为分布式系统。为了正确有效地运行这些大型系统,在这些系统彼此之间的进程应该有某种协议,该协议也称为分布式协调。达成协议的组件构成了分布式系统的总体目标,或者一项协议完成一些子任务,最终达成总目的。这不像听起来那么简单,因为进程不仅必须同意,而且也要确认别的同级进程是否同意。尽管听起来在一个大的分布式系统中协调任务和流程很简单,实际上当谈到实现容错的正确方式时,这是一个非常棘手的问题。ApacheZooKeeper,Apache软件基金会的一个项目,旨在解决设计和开发分布式系统时的这些协调问题,通过一个简单 API 提供一组可靠原语。
在这一章,我们将讨论以下主题:
[*] 什么是分布式系统及其特点
[*] 为什么分布式系统协调很困
[*] 介绍 ApacheZooKeeper
[*] 下载和安装 ApacheZooKeeper
[*] 使用 ZooKeeper shell 连接 ZooKeeper
[*] 多节点 ZooKeeper 集群配置
定义一个分布式系统
分布式系统被定义为一个软件系统,由独立的计算实体通过计算机网络连接在一起,这些组件为实现一个共同目标进行相互交流和协调。一个e-mail系统,例如Gmail 或Yahoo!Mail就是这样的一个分布式系统例子。多玩家在线游戏,有能力的玩家处于地理分开的位置,这是另一个分布式系统例子。
为了确定一个分布式系统,以下是你需要寻找的特征:
[*] 资源共享:这是指系统使用资源的可能性,例如存储空间、计算能力、数据,和从任何地方到来的服务,等等
[*] 可扩展性:这是指逐步扩展和改善系统的可能性,从硬件和软件两个角度
[*] 并发性:这是指系统由多用户同时使用来完成相同任务或不同任务的能力
[*] 性能和可伸缩性:这可以确保系统不因为总体负载的增加降低响应时间
[*] 容错:这将确保系统始终可用,即使一些组件失败或以降级模式运行
[*] 通过API 抽象:这确保系统各个组件对最终用户隐藏,只向他们暴露最终服务
设计一个分布式系统很难,编程集合独立计算实体功能在一起更难。设计和开发人员常常做出一些假设,也称为分布式计算谬论。这些谬论列表最初由 Sun Microsystems公司工程师在初始设计网络文件系统(NFS)时编制,你可以参考这些:
假设
现实
网络可靠
现实中,组件之间的网络或互连可能由于系统内部错误或由于电源故障等外部因素而失败
反应为零
分布式系统用户可以从世界任何地方连接到它,并且也需要花费时间将数据从一个地方移动到另一个地方。网络的服务质量也会影响应用程序的延迟
宽带无限
在最近网络宽带提高了很多,但是在世界各地这并不是统一的。宽带取决于网络的类型(T1、LAN、WAN、移动网络,等等)
网络安全
网络从来不安全。对于一个在设计应用程序时不重视安全方面的系统经常会遇到拒绝服务***
拓扑不变
现实中,拓扑从来都不是常数。随着时间推移,组件被添加/删除,系统应该容忍这种变化
拥有管理
分布式系统从未在隔离功能。它们与其他外部系统交互功能;这超出了管理控制
传输代价零
远非如此,到处都是成本,从建立网络到从源到目的地发送网络数据包。CPU周期成本以实际美元的形式支付给网络服务提供商
网络是均匀的
网络由大量不同实体组成。因此,对于正确地运行一个应用程序,需要与各个组件进行互操作,网络类型、操作系统,甚至是实现语言。
分布式系统设计人员在设计系统时需要记住所有之前的点。除此之外,未来棘手的问题还有要解决多计算实体或独立程序的参与,协调它们的动作。通常,要实现这种协调逻辑,开发人员和设计人员都会陷入困境;导致不正确和低效的系统设计。而 ApacheZooKeeper就是被设计和开发协调这种动作的,这使得一个高度可靠的分布式协调成为可能。
ApacheZooKeeper为开发一个高度可伸缩、可靠、健壮的集中服务实现分布式系统协调,开发人员可以直接通过他们应用程序使用一个非常简单的接口,一个集中的协调服务。它使应用程序开发人员可以集中精力在他们的应用程序核心业务逻辑上,完全依赖 ZooKeeper 服务协调部分正确开始他们的应用。它简化了应用程序开发过程,使它更加灵活。
使用 ZooKeeper,开发人员可以实现常见的分布式协调任务,如下所示:
[*] 配置管理
[*] 命名服务
[*] 分布式同步,如锁和障碍
[*] 集群成员操作,如检测节点离开/节点加入
任何分布式应用程序都需要这些服务这样或那样的方式,实现协调和同步它们从头开始经常导致应用程序行为不正常的错误。Zookeeper 减轻了需要在分布式应用程序实现的协调和同步服务,通过一组丰富的 API 提供了简单和优雅的原语。
为何分布式系统协调如此具有挑战性
在介绍了 ApacheZooKeeper及其在设计和开发分布式应用程序时的角色后,让我们来更深入研究为什么协调在分布式系统中是如此困难。让我们做一个配置管理分布式应用程序的例子,由多个同时运行的独立软件组件组成,跨过多个物理服务器。现在,有一个主节点(master node)集群配置存储,其他从节点(worker nodes)从这个主节点下载自动配置自己,看起来这似乎是一个简单和优雅的解决方案。但是,这种解决方案会因为主节点的一个潜在问题就变成单点故障。即便我们假设主节点有容错设计,设计一个当配置信息变更时动态传播给所有从节点的系统也并非易事。
分布式系统中另一个协调问题是服务的发现。通常,为维持负载提高应用程序的可用性,我们会给系统添加更多的物理服务器。不过,我们需要让客户端或从节点知道在集群中成员的这些变化和在集群中主机不同服务的新机器可用性。这需要客户端本身精心的设计和实现逻辑。
可伸缩性提高可用性,但是它复杂协调。水平可伸缩的分布式系统,跨越成千上万台物理服务器,经常容易出错,如硬件故障、系统崩溃、通信链路故障,等等。这些类型的失败不遵循任何模式,因此,在应用程序逻辑里处理此类故障,和设计系统的容错性确实是一个难题。
因此,从指出到现在,很明显,设计一个分布式系统并不那么容易。制作出正确、快速、可伸缩集群协调,是困难而且经常容易出错,从而导致整个集群不一致。在这里,ApacheZooKeeper为设计和开发分布式系统带来了一个健壮的协调服务。
ApacheZooKeeper 介绍
ApacheZooKeeper是 Apache软件基金会的一个软件项目,它为大型分布式系统的各种协调问题提供了一个开源解决方案。ZooKeeper最初由雅虎开发。
ZooKeeper,作为一个集中式协调服务,运行在一个叫做 ZooKeeper服务集群集合里,分散并且高度可靠。分布式同步、组管理、领导人选择已经被服务实现,因此应用程序不需要通过自己重新发明轮子通过实现。另外,应用程序可以使用 ZooKeeper暴露的原语构建更强大的抽象来解决各种各样的问题。我们将会在第4章“执行常见分布式系统任务”深入研究这些概念。
ApacheZooKeeper使用 Java 编写。附带了 C、Java、Perl 和Python 客户端绑定。社区也贡献了可供其它语言使用的有效客户端库,例如 Go、Scala、Erlang,等等。
ApacheZooKeeper被大量组织广泛使用,例如 Yahoo! Inc.、Twitter、Netflix 和Facebook,在它们的分布式应用程序平台上作为一个协调服务。在第7章“ZooKeeper实战”中我们将探讨更多关于如何在真实世界的使用。
Apache ZooKeeper 亲手实践
在本节,我们将向你展示如何下载和安装 ApacheZooKeeper,以便我们可以马上开始使用ZooKeeper。本章旨在通过开发人员使用 ZooKeeper的亲手实践,为他们的分布式应用程序给予详细安装和使用说明。我们将从一个ZooKeeper单节点安装开始,熟悉基本配置,其次学习 ZooKeeper shell。最后,你将学会如何搭建一个多节点的 ZooKeeper集群。
下载和安装
ZooKeeper支持多种平台。GNU/Linux 和Oracle Solaris作为服务端和客户端开发和生产平台都被支持。Windows和MacOS X 建议只作为服务器和客户端开发平台。
ZooKeeper使用 Java编写,需要Java6 或以上更高版本运行。尽管推荐使用 Oracle 版本 Java,OpenJDK也可以正常工作,正确执行 ZooKeeper功能和本书中的许多代码示例。
可以从这里下载 Oracle Java
http://www.oracle.com/technetwork/java/javase/downloads/index.html
ZooKeeper作为一个 ZooKeeper服务整体感知运行。在生成集群,三个 ZooKeeper服务器是一个整体的最小推荐数量,建议你在单独的机器上允许它们。不过,通过在一台单独机器上以独立模式安装,你可以学习和评估 ZooKeeper。
下载
让我们从乔治亚理工大学的Apache 镜像下载稳定版本(http://b.gatech.edu/1xElxRb):
$ wget
http://www.gtlib.gatech.edu/pub/apache/zookeeper/stable/zookeeper-3.4.6.tar.gz
$ ls -alh zookeeper-3.4.6.tar.gz
-rw-rw-r-- 1 saurav saurav 17M Feb 20 2014zookeeper-3.4.6.tar.gz
安装
一旦我们下载了 ZooKeepertar 包,安装设置一个单独的 ZooKeeper节点相当简单明了。让我们将压缩的tar 文件提取到/usr/share:
$ tar -C/usr/share -zxf zookeeper-3.4.6.tar.gz
$ cd/usr/share/zookeeper-3.4.6/
$ ls
binCHANGES.txtcontribdocsivy.xmlLICENSE.txt
README_packaging.txtrecipes zookeeper-3.4.6.jarzookeeper-3.4.6.jar.md5
build.xml confdist-mavenivysettings.xmllib
NOTICE.txtREADME.txtsrczookeeper-3.4.6.jar.asc
zookeeper-3.4.6.jar.sha1
在本例中,ZooKeeper压缩文件被提取到了/usr/share/zookeeper-3.4.6,按如下方式导出 ZK_HOME:
$ exportZK_HOME=/usr/share/zookeeper-3.4.6
配置
一旦我们提取了 tar 包,下一步就是配置 ZooKeeper。conf文件夹拥有 ZooKeeper 的配置文件。 ZooKeeper 需要从 ZooKeeper 文件夹里conf 文件夹中一个名为zoo.cfg的配置文件。这里有一个示例配置文件,其中包含一些供参考的配置参数。
让我们使用下面最小参数创建我们的配置文件,并将它保存在conf文件夹里:
$ cat conf/zoo.cfg
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
配置参数的含义解释如下:
[*] tickTime:以毫秒为单位:用于会话注册和客户端对 ZooKeeper 服务端心跳检测。最小会话超时是两倍tickTime值。
[*] dataDir:ZooKeeper 状态内存存储位置;包括数据库快照和更新数据库的事务日志。提取 ZooKeeper文档不会创建这个目录,因此如果这个目录不在系统中,你需要创建并设置可写权限。
[*] clientPort:这个端口监听客户端连接,它是ZooKeeper客户端发起连接的地方。客户端端口可以被设置为任意数字,配置不同的服务端监听不同的端口。默认端口是 2181。
在第5章“Apache ZooKeeper 管理”中我们将学习各种存储、网络和 ZooKeeper 集群配置详细参数。
如前所述,ZooKeeper需要一个 Java运行环境来工作。
运行下面命令,看看在你系统上安装的 Java:
$ java–version
如果已经安装Java并正确配置了路径,根据 Java 的发行版本(Oracle 或OpenJDK),前面的命令将显示在你系统上安装运行的Java版本。例如,在我的系统上,我安装了Java1.7.0.67,因此,使用前面的命令,在我的系统上将会返回以下输出:
$ java-version
javaversion "1.7.0_67"
Java(TM)SE Runtime Environment (build 1.7.0_67-b01)
JavaHotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)
ZooKeeper需要正确地设置JAVA_HOME环境变量。运行以下命令,看看你的系统是否设置:
$ echo$JAVA_HOME
在我的系统,JAVA_HOME被设置为/usr/java/latest,因此,我得到如下输出:
$ echo$JAVA_HOME
/usr/java/latest
启动ZooKeeper 服务
现在,考虑到 Java已经安装和工作正常,让我们继续并开启ZooKeeper服务。使用下面命令,所有ZooKeeper启动/停止服务和调用 ZooKeeper命令shell的管理脚本都跟着压缩文件被送到bin文件夹下:
$ pwd
/usr/share/zookeeper-3.4.6/bin
$ ls
README.txtzkCleanup.shzkCli.cmdzkCli.shzkEnv.cmdzkEnv.sh
zkServer.cmdzkServer.sh
在Unix平台(GNU/Linux,MacOSX,等等)使用.sh 扩展脚本,对于MicrosoftWindows 操作系统使用NaNd 扩展脚本。
在GNU/Linux 系统上启动 ZooKeeper服务,你需要按照下面执行zkServer.sh脚本。这个脚本给出了一个启动、停止、重启,和查看 ZooKeeper 服务状态的操作:
$./zkServer.sh
JMX enabledby default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Usage:./zkServer.sh
{start|start-foreground|stop|restart|status|upgrade|print-cmd}
为避免到 ZooKeeper安装目录运行这些脚本,你可以使用如下命令将它设置到你的PATH变量:
exportPATH=$PATH:/usr/share/zookeeper-3.4.6/bin
使用start 参数执行zkServer.sh启动 ZooKeeper服务。成功启动的服务将显示下面输出:
$ zkServer.sh start
JMX enabled by default
Using config: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
你可以使用 ps 命令,检查ZooKeeper服务是否已经开启:
$ ps –ef| grep zookeeper | grep –v grep | awk '{print $2}'
5511
如果你的系统安装了jps命令,你可以使用如下命令检查 ZooKeeper 服务的启动:
$ which jps
jps is /usr/bin/jps
$ jps
5511 QuorumPeerMain
5565 Jps
ZooKeeper进程被列为QuorumPeerMain。在这种情况下,作为jps 的报道,ZooKeeper服务运行在与进程 ID 5511相匹配的 ps 命令报道。
如下所示,可以通过zkServer.sh脚本检查ZooKeeper服务的状态:
$zkServer.sh status
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode:standalone
你可以为同样的脚本使用 stop 参数,停止服务进程:
$zkServer.sh stop
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Stoppingzookeeper ... STOPPED
当ZooKeeper已经停止或不运行时检查状态将显示如下结果:
$zkServer.sh status
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Errorcontacting service. It is probably not running.
一旦我们ZooKeeper实例已经运行,接下来要做的就是连接它。ZooKeeper附带一个默认的基于Java 命令行shell连接到一个 ZooKeeper实例。这里也有一个 C客户端,我们将在后面的小节讨论。
用基于Javashell 连接到ZooKeeper
开启基于 Java 的ZooKeeper命令行shell,如下,我们仅仅只需使用服务>
${ZK_HOME}/bin/zkCli.sh–server zk_server:port
在我们的例子中,我们已经在同一台机器上运行了我们的ZooKeeper服务,所以 ZooKeeper服务是localhost,或回送地址是127.0.0.1。我们配置的默认端口是2181:
$zkCli.sh -server localhost:2181
连接上运行的 ZooKeeper实例,我们将在终端上看到类似如下的输出(省略一些输出):
Connectingto localhost:2181
...............
............... Welcome
to ZooKeeper! JLine
support is enabled
...............
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
看看 ZooKeeperJavashell 支持的命令清单,你可以在 shell 终端运行help命令:
help
ZooKeeper -server host:port cmd args
connect host:port
get path
ls path
set path data
rmr path
delquota[-n|-b] path
quit
printwatches on|off
create [-s][-e] path data acl
stat path
close
ls2 path
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path
setquota -n|-b val path
我们可以通过命令行接口执行一些简单的命令。让我们开始运行ls命令,在 Unix,使用清单如下:
ls /
现在,ls命令返回一个叫做zookeeper 的字符串,它是 ZooKeeper 的专用术语znode。注意,我们将会在下一章,第2章了解“ApacheZooKeeper内部工作原理”介绍ZooKeeper数据模型。如下,我们可以通过ZooKeepershell 创建一个 znode:
首先,让我们创建一个HelloWorld空数据 znode:
create /HelloWorld""
Created /HelloWorld
ls /
如下,我们使用delete 命令可以删除创建的 znode:
delete /HelloWorld
ls /
在之后章节,这里显示的操作将更清晰我们了解的关于 ZooKeeper 架构、数据模型,命名空间和内部结构的知识。让我们看看基于 C语言的 ZooKeeper 命令行shell。
用基于C shell 连接到ZooKeeper
ZooKeeper附带了一个基于 C语言的命令行shell。但是,要使用这个 shell,我们需要在${ZK_HOME}/src/c. AGNU/GCC命令里构建 C来源。要构建它们,只需在前面的忙碌运行三个命令:
$./configure
$ make
$ makeinstall
默认情况下,C客户端库安装在/usr/local/lib。C客户端库能够构建单线程和多线程库。单线程库以_st 为后缀,而多线程库以_mt为后缀。
基于 C 的ZooKeepershell使用这些库来执行。这样,前面的构建完成后,叫做cli_st和cli_mt的两个可执行档在当前文件夹生成。这两个二进制文件分别是单线程和多线程命令行 shell。当cli_mtis运行时,我们会得到以下输出:
$ cli_mt
USAGEcli_mt zookeeper_host_list
Version:ZooKeeper cli (c client) version 3.4.6
使用基于 Cshell连接到ZooKeeper服务实例,在你的终端执行下面的命令:
$ cli_mtlocalhost:2181
Watcher SESSION_EVENT state = CONNECTED_STATE
Got a newsession>
基于CZooKeepershell还支持多个命令,比如 Java版本。执行help命令,让我们看看下面的可用命令:
help
create[+]
delete
set
get
ls
ls2
sync
exists
wexists
myid
verbose
addauth
quit
prefix the command with the character 'a' to run the command
asynchronously.run the 'verbose' command to toggle verbose logging.
i.e.'aget /foo' to get /foo asynchronously
我们可以发出相同的一组命令列出 znode,创建一个 znode,最后删除它:
ls /
time = 3msec
/: rc = 0
zookeeper
time = 5 msec
create /HelloWorld
Creating node
Watcher CHILD_EVENT state = CONNECTED_STATE for path /
: rc = 0
name = /HelloWorld
ls /
time = 3msec
/: rc = 0
zookeeper
HelloWorld time = 3 msec
delete/HelloWorld
Watcher CHILD_EVENT state = CONNECTED_STATE for path /
ls /
time = 3 msec
/: rc = 0
zookeeper
time = 3msec
基于 CZooKeepershell格式化输出显示命令执行的时间以及返回代码(rc)。返回代码为零,表示命令成功执行。
我们之前构建和安装在/usr/local/ lib的C静态和共享库是必需的,可以用ZooKeeperC 编程语言为分布式应用程序 ZooKeeper 编程。Perl 和Python 客户端也附带分发在 ZooKeeper的这个基于 C接口上。
建立多节点ZooKeeper 集群
到目前为止,我们已经建立了一个单机模式的 ZooKeeper服务实例。一个单机实例是一个潜在的单点故障。如果 ZooKeeper服务失效,我们使用这个实例的整个分布式协调应用程序都将失效,停止运转。因此,以单机模式运行 ZooKeeper是不适合生产的,但是为了开发和评估,这个服务也是需要的。
在生产环境中,ZooKeeper 应该以复制模式运行在多个服务器上,也叫 ZooKeeper 集合。推荐最小的服务器数量是 3,在生产环境中 5 台服务器是最常见的。复制的服务器在同一个应用程序域中称为仲裁(quorum)。在这种模式下,ZooKeeper服务实例运行在多个不同机器上,仲裁中的所有的服务都有相同的配置文件的副本。在一个仲裁中,ZooKeeper实例运行在一个群首/追随模式下。其中一个实例是民选领袖,其他人成为追随者。如果群首失效,发生新群首选举,另一个正在运行的实例成为群首。不过,这些复杂性对于使用ZooKeeper的应用程序和开发人员却完全是隐藏的。
群集模式下 ZooKeeper 配置文件与我们使用的单机模式是一样的,除了少数几条。这里显示了一个示例配置文件:
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
解释一下这里的两个配置参数:
[*] initLimit:这是追随者最初连接群首超时值,单位为 tick 值倍数
[*] syncLimit:追随者与群首进行 sync 操作时的超时值,单位为 tick 值倍数
这两个单位中指定超时时间为tickTime。因此,在我们的示例中,initLimit 的超时时间是5 倍2000毫秒,或者是 10秒。
前面示例中其他三个实体以server.id=host:port:port 格式的服务器列表构成法定人数。.id 标识符是一个数字,用于仲裁中服务器的主机名。在我们是示例配置中,zoo1仲裁成员分配到的标识符是1。
标识符是需要在服务器一个名为myid的数据据文件夹指明的。很重要,myid 文件应该有一个只包含服务> 再次,我们有了两个端口好之后,每台服务主机就成为:2888和3888。这里有关于它们的说明:
[*] 第一个端口,2888,主要用于集群中点对点通信,如追随者连接到领导者。追随者使用这个端口打开一个 TCP 到领导者的连接
[*] 第二个端口,3888,用于群首选举,防止仲裁出现新群首。所有通信通过TCP,第二个端口需要响应仲裁内部群首选举。
启动服务器实例
为仲裁中的每个服务配置文件后,我们需要启动 ZooKeeper服务实例。这个过程与单机模式是一样的。执行下面命令行,我们必须连接到每一台机器:
${ZK_HOME}/bin/zkServer.shstart
一旦实例启动成功,我们将执行下面命令检查每台机器实例状态:
${ZK_HOME}/bin/zkServer.shstatus
例如,看看下一个法定人:
#${ZK_HOME}/bin/zkServer.sh status
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode:follower
#${ZK_HOME}/bin/zkServer.sh status
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode:leader
#${ZK_HOME}/bin/zkServer.sh status
JMXenabled by default
Usingconfig: /usr/share/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode:follower
如前所述,zoo2是集群群首,zoo1和zoo3是追随者。通过命令行shell 连接到 ZooKeeper集群也和单机模式相同,除了我们现在以一个连接字符串 host1:port2, host2:port2 … 格式指定的到服务端${ZK_HOME}/bin/zkCli.sh参数:
$zkCli.sh -server zoo1:2181,zoo2:2181,zoo3:2181
Connectingto zoo1:2181, zoo2:2181, zoo3:2181
… … … …
Welcometo ZooKeeper!
… … … …
一旦 ZooKeeper集群建立和运行起来,有两种方式来监控它,一种是使用 Java 管理扩展(JMX)通过客户端端口发送一些命令,也称为四字单词(Four Letter Words)。第5章“Apache ZooKeeper管理”中我们将探讨有关ZooKeeper监控更多细节。
运行ZooKeeper 多节点模式
在单机下运行 ZooKeeper多节点模式也是可能的。这是用于测试目的的。多节点模式在同一台机器上运行,我们需要调整配置;例如,我们可以将服务器名称设置为localhost同时指定唯一仲裁和群首选举端口。
让我们使用下面配置文件设置单台机器上多节点 ZooKeeper 集群:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper
clientPort=2181
server.1=localhost:2666:3666
server.2=localhost:2667:3667 server.3=localhost:2668:3668
前面的小节中已经解释过,每一个服务实体 X 代表 XZooKeeper 服务上的地址和端口。第一个字段是服务 X主机名或 IP 地址,第二个和第三个字段分别是仲裁连接和群首选举的 TCP 端口。由于我们在同一台机器上启动三个 ZooKeeper服务实例,我们需要为每一个服务实体使用不同的端口号。
当我们在同一台机器上运行不止一个ZooKeeper服务进程时,我们需要为每一个实例配置不同的客户端端口。
最后但并非最不重要,我们必须为我们正在运行的每个实例自定义dataDir参数。
将这些放在一起,一个集群中有 ZooKeeper集群中有 3 个实例,我们将创建 3 个不同配置文件。我们调用这些zoo1.cfg,zoo2.cfg,和zoo3.cfg,并且把它们保存在${ZK_HOME}的conf文件夹。我们将创建 3 个不同实例的数据文件夹,叫做zoo1,zoo2,和zoo3,在/var/lib/zookeeper。至此,三个配置文件如下所示:
这里,你将看到第一个实例的配置文件:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo1
clientPort=2181
server.1=localhost:2666:3666 server.2=localhost:2667:3667
server.3=localhost:2668:3668
第二个配置文件在这里:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo2
clientPort=2182
server.1=localhost:2666:3666 server.2=localhost:2667:3667
server.3=localhost:2668:3668
最后一个实例第三个配置文件在这里:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/var/lib/zookeeper/zoo3
clientPort=2183
server.1=localhost:2666:3666 server.2=localhost:2667:3667
server.3=localhost:2668:3668
我们还需要解决 myid 文件中服务器实例>
$ echo 1> /var/lib/zookeeper/zoo1/myid
$ echo 2> /var/lib/zookeeper/zoo2/myid
$ echo 3> /var/lib/zookeeper/zoo3/myid
现在,我们已经准备就绪启动 ZooKeeper实例。如下,让我们启动实例:
$ ${ZK_HOME}/bin/zkServer.shstart ${ZK_HOME}/conf/zoo1.cfg
$${ZK_HOME}/bin/zkServer.sh start ${ZK_HOME}/conf/zoo2.cfg
$${ZK_HOME}/bin/zkServer.sh start ${ZK_HOME}/conf/zoo3.cfg
一旦所有实例启动,我们可以使用zkCli.sh脚本连接到多节点 ZooKeeper集群,像我们之前那样:
$${ZK_HOME}/bin/zkCli.sh –server \
localhost:2181, localhost:2182, localhost:2183
看!在一台机器 ZooKeeper集群上我们运行有三个节点!
小结
在这一章中,你了解了一般分布式系统的定义和为什么组成一个大型系统之间的实体协调如此困难,还有这是一个需要被解决的非常重要问题。你学习了 ApacheZooKeeper对于分布式系统设计和开发人员如何是一个很好的解决协调问题的工具。本章提供在不同模式下安装和配置一个 ZooKeeper 的细节,如单机、集群,同时也谈到了如何用 ZooKeepershell从命令行连接到一个 ZooKeeper服务。
在下一章,你将了解到 Apache ZooKeeper 的内部和架构,你将详细了解 ZooKeeper数据模型和由 ZooKeeper服务暴露的 API 接口。下一章中介绍的概念将帮助你掌握 ZooKeeper的设计语义,增加读者在他们的分布式应用程序中使用配置使用 ZooKeeper信心。
注:本文翻译自《Apache ZooKeeper Essentials》(Packt 出版有限公司,2015年1月)第1章
转载请注明出处
页:
[1]