ClickHouse生产运维系列[部署篇]-02_Zookeeper介绍及集群安装部署
Zookeeper是Apache开源的一个分布式框架,它主要为分布式应用提供协调服务。Zookeeper最早由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,并于2010年11月正式成为Apache的顶级项目。有个比较有意思的是,大数据生态系统里很多组件选用动物或昆虫来命名,比如我们所熟知的Hadoop是头可爱的大象、Hive是一只蜜蜂、Camel是一头骆驼,Zoo
一、ZooKeeper介绍
Zookeeper是Apache开源的一个分布式框架,它主要为分布式应用提供协调服务。 Zookeeper最早由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache,并于2010年11月正式成为Apache的顶级项目。 有个比较有意思的是,大数据生态系统里很多组件选用动物或昆虫来命名,比如我们所熟知的Hadoop是头可爱的大象、Hive是一只蜜蜂、Camel是一头骆驼,ZooKeeper图像是什么呢,是一个动物园管理者。
pache ZooKeeper是一个开源的分布式协调服务,它为分布式应用提供了一套简单而强大的基础架构服务,用以实现诸如配置管理、命名服务、分布式同步以及提供组服务等功能。ZooKeeper的设计目标是将这些复杂的分布式协调过程封装成一个简单的接口,从而使分布式应用的开发变得更加容易和可靠。
核心概念
ZooKeeper的数据模型类似于一个文件系统,以层次化的目录树形式组织数据,每个节点称为一个Znode。这些Znode可以存储数据,并且可以有子节点。不仅如此,ZooKeeper还为这些Znode提供了临时节点和观察者(Watcher)机制,增强了其在分布式环境中的应用场景。
-
临时节点:这是一种特殊类型的节点,当创建它的客户端会话结束时,这个节点会被自动删除。这对于实现锁和选举机制非常有用。
-
观察者(Watcher):客户端可以在Znode上设置观察者,当这个Znode发生变化(如数据更改、节点删除、子节点变化)时,设置了观察者的客户端会收到通知。
使用场景
ZooKeeper在分布式系统中的典型使用场景包括:
-
配置管理:动态地更新和管理分布式环境中的配置信息。
-
命名服务:为分布式系统中的资源和服务提供全局唯一的名称。
-
分布式锁:在分布式环境中协调和控制资源的访问。
-
集群管理:监控入群和退群的节点,以及节点状态的变化。
强一致性保证
ZooKeeper保证了一系列强一致性的特性,包括顺序一致性、原子性、单一视图、可靠性和实时性(或最终一致性)。这些保证使得ZooKeeper成为构建可靠分布式系统的坚实基础。
开发和运行要求
ZooKeeper用Java编写,因此它需要Java运行时环境。根据ZooKeeper的不同版本,对Java版本有不同的要求,通常推荐使用Java 8或更高版本以确保最佳兼容性和性能。
二、ZooKeeper与ClickHouse-Keeper对比
ClickHouse-Keeper是ClickHouse从21.8版本开始引入的一个组件,旨在作为ZooKeeper的替代品,用于管理ClickHouse集群的元数据和一些协调任务。下面是基于集成度、性能、配置和维护、兼容性、功能、社区和支持、稳定性和成熟度、开发语言、快照和日志处理等几个维度,对ClickHouse-Keeper和原生ZooKeeper进行的对比。
集成度
-
ClickHouse-Keeper:与ClickHouse紧密集成,为ClickHouse设计,提供了更为直接和高效的集成方式,减少了第三方依赖。
-
ZooKeeper:作为一个独立的服务运行,需要额外的部署和配置步骤来与ClickHouse或其他应用集成。
性能
-
ClickHouse-Keeper:由于是为ClickHouse量身定制,性能上有针对性的优化,特别是在处理大量并发请求和高负载情况下,表现可能更优。
-
ZooKeeper:虽然性能稳定且在分布式系统中表现良好,但在极端负载或特定场景下可能不如ClickHouse-Keeper优化得更为精细。
配置和维护
-
ClickHouse-Keeper:配置和维护更为简化,尤其是在ClickHouse环境中,因为可以共享一些配置和监控工具。
-
ZooKeeper:需要独立配置和维护,对于不熟悉ZooKeeper的用户来说,学习曲线可能更陡峭。
兼容性
-
ClickHouse-Keeper:设计时考虑到与ZooKeeper的兼容性,但主要集中在ClickHouse的使用场景。
-
ZooKeeper:广泛用于各种分布式系统,兼容性和适用范围更广。
功能
-
ClickHouse-Keeper:虽然提供了ZooKeeper的核心功能,但可能在某些高级功能上有所缺失或差异。
-
ZooKeeper:成熟、功能丰富,支持广泛的用例和场景。
社区和支持
-
ClickHouse-Keeper:作为ClickHouse生态的一部分,享有ClickHouse社区的支持,但社区相对较小。
-
ZooKeeper:有一个庞大且活跃的社区,得到了广泛的支持和贡献,包括官方文档和第三方资源。
稳定性和成熟度
-
ClickHouse-Keeper:虽然经过ClickHouse团队的精心设计和测试,但相对较新,可能在某些边缘情况下稳定性不如ZooKeeper。
-
ZooKeeper:历经多年发展,被广泛认为是分布式系统中的稳定和成熟解决方案。
开发语言
-
ClickHouse-Keeper:使用与ClickHouse相同的开发语言(主要是C++),有助于提高项目内部的协同效率。
-
ZooKeeper:主要使用Java开发,这对Java生态系统的用户更为友好。
快照和日志处理
-
ClickHouse-Keeper:优化了快照和日志的处理,特别是在与ClickHouse数据和操作相关的场景中。
-
ZooKeeper:提供了可靠的快照和日志处理机制,但可能没有针对特定场景(如ClickHouse使用场景)的优化。
针对上述内容,可以通过一个简单的图表来将二者做个对比,表格内容如下所示。
维度 | ClickHouse-Keeper | ZooKeeper |
---|---|---|
集成度 | 与ClickHouse紧密集成,减少第三方依赖 | 作为独立服务运行,需要额外设置 |
性能 | 针对性能进行了优化,尤其是在高负载下 | 在多种场景下表现稳定,但未针对性优化 |
配置和维护 | 简化了配置和维护过程 | 需要单独配置和维护,学习曲线较陡 |
兼容性 | 专为ClickHouse设计,可能缺乏更广泛的生态系统兼容性 | 广泛兼容分布式系统 |
功能 | 覆盖核心功能,可能缺少一些高级功能 | 成熟、功能丰富 |
社区和支持 | 属于ClickHouse社区的一部分,相对较少 | 大型、活跃的社区,支持广泛 |
稳定性和成熟度 | 相对较新,稳定性可能有边缘情况 | 经过时间考验的稳定性和成熟度 |
开发语言 | 与ClickHouse相同(主要是C++) | 主要使用Java,对Java生态系统有利 |
快照和日志处理 | 针对ClickHouse用例进行了优化 | 可靠的机制,未针对ClickHouse特别优化 |
另外ClickHouse-Keeper在处理zxid Overflow[溢出]方面相对原生ZooKeeper做了优化,一定程度解决了zxid Overflow问题。
注:zxid是一个64位数字,分为两部分:高32位标识Leader周期,低32位标识事务序号。每个新事务使低32位加1。当低32位满(0xffffffff),触发选主,重置zxid:新周期开始,序号归零。
三、Zookeeper集群部署
为了更好模拟线上ZooKeeper集群环境,本次仍选用部署Apache ZooKeeper集群,未选择ClickHouse-Keeper,后期会对ClickHouse-Keeper进行调研测试,对比两者的性能差异。
3.1 环境规划
本次选择三台部署CentOS 7.9操作系统的虚拟机用来部署ZooKeeper三节点集群,ZooKeeper版本为3.8.3
主机名 | IP地址 | ZooKeeper版本 |
---|---|---|
prod-ck-zk-01 prod-ck-zk-02 prod-ck-zk-03 | 10.110.5.132 10.110.5.133 10.110.5.134 | apache-zookeeper-3.8.3 |
3.2 部署JDK
本次选择在三节点部署jdk1.8.0_321版本。
-- root用户,三节点都需操作,此处以其中一节点为例 [root@prod-ck-zk-01 ~]# cd /home/ [root@prod-ck-zk-01 home]# tar -zxf jdk1.8.0_321.tar.gz -- 编辑环境变量 [root@prod-ck-zk-01 ~]# cat << EOF | sudo tee -a /etc/profile export JAVA_HOME=/home/jdk1.8.0_321 export PATH=\$JAVA_HOME/bin:\$PATH export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar EOF -- 生效环境变量 [root@prod-ck-zk-01 ~]# source /etc/profile -- 查看java版本 [root@prod-ck-zk-01 ~]# java -version java version "1.8.0_321" Java(TM) SE Runtime Environment (build 1.8.0_321-b07) Java HotSpot(TM) 64-Bit Server VM (build 25.321-b07, mixed mode)
3.3 部署ZooKeeper
登录ZooKeeper官网下载地址 Index of /dist/zookeeper,下载对应的ZooKeeper版本,本次我选择下载zookeeper-3.8.3/ 这个版本,这个版本是 2023-10-09发布的。
将下载的apache-zookeeper-3.8.3-bin.tar.gz安装包分别上传到三台服务器某个目录下,比如/home目录,保持目录统一。接下来按照如下方式一步步采用二进制方式部署apache-zookeeper-3.8.3。
1)解压tar包
-- root用户,三节点都需操作,此处以其中一节点为例 [root@prod-ck-zk-01 ~]# cd /home [root@prod-ck-zk-01 home]# tar -zxf apache-zookeeper-3.8.3-bin.tar.gz -- 创建目录 [root@prod-ck-zk-01 home]# mkdir -p /data/zookeeper
2)修改配置文件
-- root用户,三节点都需操作,此处以其中一节点为例 [root@prod-ck-zk-01 home]# cd apache-zookeeper-3.8.3-bin/conf/ [root@prod-ck-zk-01 conf]# cp -p zoo_sample.cfg zoo.cfg -- 编辑后的zoo.cfg文件内容如下 tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper clientPort=2181 metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider metricsProvider.httpPort=7000 metricsProvider.exportJvmInfo=true admin.enableServer=true admin.serverPort=8080 server.1=10.110.5.132:2888:3888 server.2=10.110.5.133:2888:3888 server.3=10.110.5.134:2888:3888 autopurge.purgeInterval=1 autopurge.snapRetainCount=5 -- 以上参数具体含义如下 各个参数的含义如下: - `tickTime=2000`: ZooKeeper使用的基本时间单位,单位是毫秒。这个值用于心跳和超时等。 - `initLimit=10`: 这是follower初始化与leader之间的连接时能容忍的最多心跳次数(tickTime的数量)。 - `syncLimit=5`: 这是leader和follower之间发送消息,请求和应答时间长度,单位是tickTime。 - `dataDir=/data/zookeeper`: ZooKeeper存储数据的目录。 - `clientPort=2181`: 客户端连接ZooKeeper服务器的端口号。 - `metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider`: ZooKeeper的度量提供者类名,这里配置的是PrometheusMetricsProvider,表示使用Prometheus进行监控。 - `metricsProvider.httpPort=7000`: Prometheus的HTTP服务端口。 - `metricsProvider.exportJvmInfo=true`: 是否导出JVM的相关信息给Prometheus。 - `admin.enableServer=true`: 是否启用ZooKeeper的admin server。 - `admin.serverPort=8080`: ZooKeeper admin server的端口号。 - `server.X=ip:port:port`: ZooKeeper集群中的服务器配置,X代表服务器的编号,ip是服务器的IP地址,第一个端口是服务器之间通信的端口,第二个端口是leader选举使用的端口。 - `autopurge.purgeInterval=1`: 自动清理的间隔(单位是小时),这里配置的是1小时清理一次。 - `autopurge.snapRetainCount=5`: 保留的快照文件数量,超过这个数量的旧文件会被清理。
3)添加java.env配置文件
-- root用户,三节点都需操作,此处以其中一节点为例 -- 通过如下命令在/home/apache-zookeeper-3.8.3-bin/conf目录下新增 java.env 配置文件,命令及配置文件内容如下: cat << 'EOF' | tee -a /home/apache-zookeeper-3.8.3-bin/conf/java.env #!/bin/sh export JVMFLAGS="-Xms128m \ -Xmx6g \ -Xloggc:/var/log/zookeeper/zookeeper-gc.log \ -XX:+UseGCLogFileRotation \ -XX:NumberOfGCLogFiles=16 \ -XX:GCLogFileSize=16M \ -verbose:gc \ -XX:+PrintGCTimeStamps \ -XX:+PrintGCDateStamps \ -XX:+PrintGCDetails \ -XX:+PrintTenuringDistribution \ -XX:+PrintGCApplicationStoppedTime \ -XX:+PrintGCApplicationConcurrentTime \ -XX:+PrintSafepointStatistics \ -XX:+UseG1GC \ -Djute.maxbuffer=8388608 \ -XX:MaxGCPauseMillis=50 $JVMFLAGS" EOF -- 以上各参数解释如下 这些是JVM启动参数,用于调整内存、垃圾收集和日志: - `-Xms128m`: 初始堆内存128MB。 - `-Xmx6g`: 最大堆内存6GB。 - `-Xloggc`: 垃圾收集日志路径。 - `-XX:+UseGCLogFileRotation`: 启动日志轮转。 - `-XX:NumberOfGCLogFiles=16`: 日志文件数16个。 - `-XX:GCLogFileSize=16M`: 日志文件大小16MB。 - `-verbose:gc`: 输出垃圾收集信息。 - `-XX:+PrintGCTimeStamps`: 添加GC时间戳。 - `-XX:+PrintGCDateStamps`: 添加GC日期戳。 - `-XX:+PrintGCDetails`: 输出GC详细信息。 - `-XX:+PrintTenuringDistribution`: 新生代年龄分布信息。 - `-XX:+PrintGCApplicationStoppedTime`: 应用暂停时间。 - `-XX:+PrintGCApplicationConcurrentTime`: 应用运行时间。 - `-XX:+PrintSafepointStatistics`: 安全点统计信息。 - `-XX:+UseG1GC`: 使用G1垃圾收集器。 - `-Djute.maxbuffer=8388608`: ZooKeeper序列化缓冲区大小8MB。 - `-XX:MaxGCPauseMillis=50`: 期望最大GC暂停时间50毫秒。 `$JVMFLAGS`: 累加已有的JVMFLAGS参数。
4)增加myid文件
-- root用户,三节点都需操作 -- 在ZooKeeper集群各数据目录/data/zookeeper,增加myid文件,标识当前节点,用于ZooKeeper集群选举【注意,各节点myid值不同】 -- 节点一 prod-ck-zk-01 [root@prod-ck-zk-01 ~]# echo 1 >> /data/zookeeper/myid -- 节点二 prod-ck-zk-02 [root@prod-ck-zk-02 ~]# echo 2 >> /data/zookeeper/myid -- 节点二 prod-ck-zk-03 [root@prod-ck-zk-03 ~]# echo 3 >> /data/zookeeper/myid
5)启动Zookeeper集群
-- root用户操作 -- 在ZooKeeper节点一/home/目录创建start_zk_cluster.sh集群启动脚本,脚本内容如下所示: cat << 'EOF' | sudo tee /home/start_zk_cluster.sh > /dev/null #!/bin/bash # 定义服务器列表 SERVERS=("10.110.5.132" "10.110.5.133" "10.110.5.134") # Zookeeper启动脚本的路径 ZK_START_SCRIPT="/home/apache-zookeeper-3.8.3-bin/bin/zkServer.sh start" # root密码 PASSWORD="root" # 遍历服务器列表并通过ssh启动Zookeeper for SERVER in "${SERVERS[@]}"; do echo "Starting Zookeeper on ${SERVER}..." sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no root@$SERVER $ZK_START_SCRIPT done echo "Zookeeper cluster startup initiated on all servers." EOF -- 然后执行start_zk_cluster.sh脚本 [root@prod-ck-zk-01 home]# sh start_zk_cluster.sh -- 输出结果如下 Starting Zookeeper on 10.110.5.132... /usr/bin/java ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Starting zookeeper ... STARTED Starting Zookeeper on 10.110.5.133... /usr/bin/java ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Starting zookeeper ... STARTED Starting Zookeeper on 10.110.5.134... /usr/bin/java ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Starting zookeeper ... STARTED Zookeeper cluster startup initiated on all servers. -- 注意:若报 sshpass: command not found,需各服务器安装 sshpass,通过如下方式安装sshpass sudo yum install sshpass
3.4 查看Zookeeper集群状态
-- 节点一查看ZK当前状态 [root@prod-ck-zk-01 ~]# /home/apache-zookeeper-3.8.3-bin/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: follower ## 显示当前状态为follower -- 节点二查看ZK当前状态 [root@prod-ck-zk-02 ~]# /home/apache-zookeeper-3.8.3-bin/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: leader ## 显示当前状态为leader -- 节点三查看ZK当前状态 [root@prod-ck-zk-03 ~]# /home/apache-zookeeper-3.8.3-bin/bin/zkServer.sh status ZooKeeper JMX enabled by default Using config: /home/apache-zookeeper-3.8.3-bin/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Client SSL: false. Mode: follower ## 显示当前状态为follower
3.5 ZooKeeper验证
3.5.1 查看四字命令是否有效
分别使用浏览器打开 http://xxx.xxx.xxx.xxx:8080/commands/mntr 验证四字命令是否有效,若输入如下内容表示有效。
{ "version": "3.8.3-6ad6d364c7c0bcf0de452d54ebefa3058098ab56, built on 2023-10-05 10:34 UTC", "server_state": "leader", "peer_state": "leading - broadcast", "write_batch_time_in_commit_processor{quantile=\"0.5\"}": "NaN", "write_batch_time_in_commit_processor_count": 0, "write_batch_time_in_commit_processor_sum": 0, ---此处省略部分内容 ...... "prep_process_time_count": 0, "prep_process_time_sum": 0, "reads_after_write_in_session_queue{quantile=\"0.5\"}": "NaN", "reads_after_write_in_session_queue_count": 0, "reads_after_write_in_session_queue_sum": 0, "learner_commit_received_count": 0, "command": "monitor", "error": null }
注:四字命令含义详细解释如下:
在Zookeeper中,`mntr` 是一种四字命令(four-letter word command),可以用于获取Zookeeper服务的详细运行时状态信息。这些命令通常用于监控和诊断。当你访问 `http://xxx.xxx.xxx.xxx:8080/commands/mntr`,你实际上是通过HTTP接口发送了一个 `mntr` 命令到Zookeeper服务器。 Zookeeper的HTTP接口是一个额外的服务,可能是由某个Zookeeper监控或管理工具提供的。如果Zookeeper服务配置了HTTP服务器并且启用了`mntr`命令的HTTP接口,那么你可以通过这种方式获取Zookeeper的状态信息。 `mntr` 命令返回的信息通常包含以下内容: - `zk_version`: Zookeeper的版本 - `zk_avg_latency`: 平均延迟时间 - `zk_max_latency`: 最大延迟时间 - `zk_min_latency`: 最小延迟时间 - `zk_packets_received`: 接收到的数据包数量 - `zk_packets_sent`: 发送的数据包数量 - `zk_num_alive_connections`: 存活的连接数 - `zk_outstanding_requests`: 未完成请求的数量 - `zk_server_state`: 服务器的状态(leader/follower/standalone) - `zk_znode_count`: Znode节点的数量 - `zk_watch_count`: watch的数量 - `zk_ephemerals_count`: 临时节点的数量 - `zk_approximate_data_size`: 数据的近似大小 - `zk_open_file_descriptor_count`: 打开的文件描述符的数量 - `zk_max_file_descriptor_count`: 文件描述符的最大数量 这些指标很有用,可以帮助你了解Zookeeper集群的健康状况和性能表现。例如,`zk_server_state` 指示了节点在集群中的角色(是否为领导者),而`zk_avg_latency` 反映了处理请求的平均时间。 请记住,不是所有的Zookeeper服务都会公开HTTP接口来访问这些命令。如果无法通过上述HTTP接口获取信息,可能需要排查Zookeeper集群配置。
3.5.2 查看Promethues是否有效
通过浏览器分别使用http://xxx.xxx.xxx.xxx:7000/metrics 来查看Promethues是否有效,若输出如下内容标识有效。
# HELP requests_in_session_queue requests_in_session_queue # TYPE requests_in_session_queue summary requests_in_session_queue{quantile="0.5",} NaN requests_in_session_queue_count 0.0 requests_in_session_queue_sum 0.0 # HELP session_queues_drained session_queues_drained # TYPE session_queues_drained summary session_queues_drained{quantile="0.5",} NaN ---此处省略部分内容 ...... # HELP read_final_proc_time_ms read_final_proc_time_ms # TYPE read_final_proc_time_ms summary read_final_proc_time_ms{quantile="0.5",} NaN read_final_proc_time_ms{quantile="0.9",} NaN read_final_proc_time_ms{quantile="0.99",} NaN read_final_proc_time_ms_count 0.0 read_final_proc_time_ms_sum 0.0
注:IP:7000/metrics具体含义如下。
`IP:7000/metrics` 通常指的是一个通过HTTP协议访问的网络地址,用于获取监控指标数据。这里的组成部分解释如下: - **IP**:这部分代表主机的IP地址。 - **7000**:这个数字代表网络服务监听的端口号 - **/metrics**:这是URL中的路径部分,它通常指向服务器上的一个特定资源或服务。在许多监控系统中(例如Prometheus),`/metrics` 路径是一个约定俗成的端点,用于暴露和提供监控指标数据。这些数据通常以纯文本格式提供,遵循Prometheus的指标格式,这样Prometheus就可以定期抓取这些数据并将其存储在其时间序列数据库中。
好了,以上就是ZooKeeper集群部署的相关知识内容,作为安装篇,我们已经将Zookeeper集群部署完毕,下一篇内容是使用ckman部署ClickHouse集群。
更多推荐
所有评论(0)