ZooKeeper单机、集群模式搭建教程

单点配置

ZooKeeper在启动的时候,默认会读取/conf/zoo.cfg配置文件,该文件缺失会报错。因此,我们需要在将容器/conf/挂载出来,在制定的目录下,添加zoo.cfg文件。

  • zoo.cfg

  • logback.xml

配置文件的信息可以从二进制包的conf文件中获取 ZooKeeper的github地址

/conf/zoo.cfg配置文件

#基本时间单位
tickTime=2000

#存储数据的目录
dataDir=/data

#存储日志的目录
dataLogDir=/datalog 

#是否以独立模式运行,如果是集群模式,则改为false
standaloneEnabled=true

#客户端端口,用户连接zookeeper服务
clientPort=2181

logback.xml日志文件,顺带将输出日志设置了,不设置的话,会采用默认的日志等级

<configuration>
  <property name="zookeeper.console.threshold" value="INFO" />
  <property name="zookeeper.log.dir" value="." />
  <property name="zookeeper.log.file" value="zookeeper.log" />
  <property name="zookeeper.log.threshold" value="WARN" />
  <property name="zookeeper.log.maxfilesize" value="256MB" />
  <property name="zookeeper.log.maxbackupindex" value="20" />
  
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n</pattern>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <level>${zookeeper.console.threshold}</level>
    </filter>
  </appender>

  <root level="WARN">
    <appender-ref ref="CONSOLE" />
  </root>
</configuration>
docker run -d \
   --name zookeeper \
   -v /opt/zookeeperconf/zookeeper1/:/conf/ \
   zookeeper:3.9.3

之后就可以正常启动了。

我们进入到容器中,验证启动的ZooKeeper是否可以正常使用

# 进入容器内部,使用bash命令行
docker exec -it zookeeper1 /bin/bash

# 通过2181端口,连接ZooKeeper服务
bin/zkCli.sh -server 127.0.0.1:2181

#创建/zk_test目录,并绑定mydata值
create /zk_test mydata

#获取zk_test的绑定值,另外两个ls是列出该目录下,所有的值
get zk_test

集群配置

节点数量说明:

建议配置奇数节点3、5、7、9。原因如下:

ZooKeeper集群模式,只有在超过半数节点可用的情况下,才会对外提供服务;

  • 3个节点,允许宕机1个

  • 5个节点,允许宕机2个

  • 7个节点,允许宕机3个

  • 8个节点,也是允许宕机3个,所以配置奇数个,性价比高。

配置文件说明:

logback.xml文件可以共享一个,但是zoo.cgf需要配置不同的文件,因为当server-list列表中的节点是自己的时候,会监听该地址。当节点是别人的时候,去向该地址发起请求,建立连接。所以,zoo.cfg需要是不同的文件。如何判断是否是自己的地址:server.x中的x isEqual ZOO_MY_ID。

搭建步骤:

1.启动多个节点

这里,我们启动三个节点。先将单机模式的配置文件复制三份,并按照下方docker命令将容器依次启动。注意,如果我们进行集群模式的搭建,必须在环境变量中传入ZOO_MY_ID,该值用作节点的编号。【先启动单机,获取每一个节点的IP通信地址,之后再进行配置文件的修改,搭建集群。】

# 节点1,节点与ZOO_MY_ID相对应
docker run -d \
   --name zookeeper1 \
   -v /opt/zookeeperconf/zookeeper1/:/conf/ \
   -e ZOO_MY_ID=1 \
   zookeeper:3.9.3

docker run -d \
   --name zookeeper2 \
   -v /opt/zookeeperconf/zookeeper2/:/conf/ \
   -e ZOO_MY_ID=2 \
   zookeeper:3.9.3

docker run -d \
   --name zookeeper3 \
   -v /opt/zookeeperconf/zookeeper3/:/conf/ \
   -e ZOO_MY_ID=3 \
   zookeeper:3.9.3

2.查看节点的IP地址

由于Docker中网络模式有多种类型,这里建议,初次搭建集群的同学,直接使用容器本身生成的IP地址。这一步的目的是为了确保zk节点之间能够互相进行通信。熟练了之后,我们可以把他们放到同一个网络下,使用别名进行通信。

docker inspect <ContainerName>

我的三个容器的IPAddress分别为172.17.0.2、172.17.0.3、172.17.0.4。

3.改写配置文件,重启所有节点

接下来进行配置文件的更改,如果启动容器的ZOO_MY_ID等于下方的server.x中的X,将其地址更改为0.0.0.0,表示监听该地址。

# 节点1 ,myid=1
tickTime=2000
dataDir=/data
clientPort=2181
initLimit=5
syncLimit=2
standaloneEnabled=false
server.1=0.0.0.0:2888:3888
server.2=172.17.0.3:2888:3888
server.3=172.17.0.4:2888:3888

# 节点2 ,myid=2
tickTime=2000
dataDir=/data
clientPort=2181
initLimit=5
syncLimit=2
standaloneEnabled=false
server.1=172.17.0.2:2888:3888
server.2=0.0.0.0:2888:3888
server.3=172.17.0.4:2888:3888

# 节点3 ,myid=3
tickTime=2000
dataDir=/data
clientPort=2181
initLimit=5
syncLimit=2
standaloneEnabled=false
server.1=172.17.0.2:2888:3888
server.2=172.17.0.3:2888:3888
server.3=0.0.0.0:2888:3888

 配置文件修改完成之后,我们依次进行集群的重启即可。

docker restart zookeeper1

重启之后,我们查看日志,可以会看到节点1和节点2报java.net.ConnectException: Connection refused的错误信息,这是非常正常的。具体原因看下方节点之间通信错误

4.验证集群模式是否配置成功

进行其中一个容器,执行bin/zkServer.sh status,会看到以下信息,Mode:表示该节点在集群中的角色。

我们也可以随机进入一个节点,写入一条信息,看看其他节点能不能同步该信息。

搭建集群时常见的错误信息:

1.Cannot assign requested address

错误信息:无法分配、注册,请求的地址。

解决方法:将节点自身的zoo.cfg的IP地址更改为0.0.0.0即可;

2024-11-04 09:41:20,659 [myid:] - ERROR [ListenerHandler-zookeeper01/10.43.187.245:3888:o.a.z.s.q.QuorumCnxManager$Listener$ListenerHandler@1099] - Exception while listening to address zookeeper01/10.43.187.245:3888
java.net.BindException: Cannot assign requested address
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Unknown Source)
        at java.base/sun.nio.ch.Net.bind(Unknown Source)
        at java.base/sun.nio.ch.NioSocketImpl.bind(Unknown Source)
        at java.base/java.net.ServerSocket.bind(Unknown Source)
        at java.base/java.net.ServerSocket.bind(Unknown Source)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager$Listener$ListenerHandler.createNewServerSocket(QuorumCnxManager.java:1141)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager$Listener$ListenerHandler.acceptConnections(QuorumCnxManager.java:1070)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager$Listener$ListenerHandler.run(QuorumCnxManager.java:1039)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)
Connection refused

错误信息:向其他节点发起建立连接的请求,被拒绝了

解决方法:

        首先,说明一下,在集群中所有节点没有全部启动的情况下,这种报错是正常的,因为我们的节点没有全部启动,所以自然也就没有办法建立连接了,这种情况下,启动所有的节点,自然就不会报错了。还有一种原因,就是配置文件错误,最大的可能性是IP地址配置错误,导致节点之间一直没有办法进行通信。可以试试在报错的容器内部能不能ping无法建立连接的IP地址

2024-11-04 09:28:03,754 [myid:] - WARN  [QuorumConnectionThread-[myid=1]-3:o.a.z.s.q.QuorumCnxManager@401] - Cannot open channel to 2 at election address /10.43.128.163:3888
java.net.ConnectException: Connection refused
        at java.base/sun.nio.ch.Net.pollConnect(Native Method)
        at java.base/sun.nio.ch.Net.pollConnectNow(Unknown Source)
        at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(Unknown Source)
        at java.base/sun.nio.ch.NioSocketImpl.connect(Unknown Source)
        at java.base/java.net.SocksSocketImpl.connect(Unknown Source)
        at java.base/java.net.Socket.connect(Unknown Source)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager.initiateConnection(QuorumCnxManager.java:384)
        at org.apache.zookeeper.server.quorum.QuorumCnxManager$QuorumConnectionReqThread.run(QuorumCnxManager.java:458)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)

 主要参考资料:


ZooKeeper官方教程

DockerHub:ZooKeeper

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/917511.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在Mysql中生成0-23完整的小时数据

目录 1. 创建表2. 插入0-23小时的数据3. 查询并合并数据 在数据分析中&#xff0c;我们经常需要对特定时间段内的数据进行统计和分析。 例如&#xff0c;在名片进线的场景中&#xff0c;我们可能需要了解一天内每小时的名片进线数量。 然而&#xff0c;由于某些时间点可能没有数…

厦门凯酷全科技有限公司正规吗?

在这个短视频风起云涌的时代&#xff0c;抖音作为电商领域的黑马&#xff0c;正以惊人的速度改变着消费者的购物习惯与品牌的市场策略。在这场变革中&#xff0c;厦门凯酷全科技有限公司凭借其专业的抖音电商服务&#xff0c;在众多服务商中脱颖而出&#xff0c;成为众多品牌信…

SpringBoot配置类

在Spring Boot中&#xff0c;配置类是一种特殊的类&#xff0c;用于定义和配置Spring应用程序的各种组件、服务和属性。这些配置类通常使用Java注解来声明&#xff0c;并且可以通过Spring的依赖注入机制来管理和使用。 Spring 容器初始化时会加载被Component、Service、Reposi…

ADS项目笔记 1. 低噪声放大器LNA天线一体化设计

在传统射频结构的设计中&#xff0c;天线模块和有源电路部分相互分离&#xff0c;两者之间通过 50 Ω 传输线级联&#xff0c;这种设计需要在有源电路和天线之间建立无源网络&#xff0c;包括天线模块的输入匹配网络以及有源电路的匹配网络。这些无源网络不仅增加了系统的插入损…

Vue2+ElementUI:用计算属性实现搜索框功能

前言&#xff1a; 本文代码使用vue2element UI。 输入框搜索的功能&#xff0c;可以在前端通过计算属性过滤实现&#xff0c;也可以调用后端写好的接口。本文介绍的是通过计算属性对表格数据实时过滤&#xff0c;后附完整代码&#xff0c;代码中提供的是死数据&#xff0c;可…

【目标检测】用YOLOv8-Segment训练语义分割数据集(保姆级教学)

前言 这篇教程会手把手带你用 YOLOv8-Segment 搭建一个属于自己的分割任务项目。从环境配置到数据集准备&#xff0c;再到模型训练和测试&#xff0c;所有步骤都有详细说明&#xff0c;适合初学者使用。你将学会如何安装必要的软件&#xff0c;标注自己的数据&#xff0c;并使…

Elasticsearch:管理和排除 Elasticsearch 内存故障

作者&#xff1a;来自 Elastic Stef Nestor 随着 Elastic Cloud 提供可观察性、安全性和搜索等解决方案&#xff0c;我们将使用 Elastic Cloud 的用户范围从完整的运营团队扩大到包括数据工程师、安全团队和顾问。作为 Elastic 支持代表&#xff0c;我很乐意与各种各样的用户和…

前深度学习时代-经典的推荐算法

参考自《深度学习推荐系统》—— 王喆&#xff0c;用于学习记录。 1.协同过滤 “协同过滤”就是协同大家的反馈、评价和意见一起对海量的信息进行过滤&#xff0c;从中筛选出目标用户可能感兴趣的信息的推荐过程。 基于用户相似度进行推荐的协同过滤算法 UserCF 用户相似度…

两行命令搭建深度学习环境(Docker/torch2.5.1+cu118/命令行美化+插件),含完整的 Docker 安装步骤

深度学习环境的配置过于繁琐&#xff0c;所以我制作了两个基础的镜像&#xff0c;希望可以帮助大家节省时间&#xff0c;你可以选择其中一种进行安装&#xff0c;版本说明&#xff1a; base 版本基于 pytorch/pytorch:2.5.1-cuda11.8-cudnn9-devel&#xff0c;默认 python 版本…

WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇

WebRTC视频 01 - 视频采集整体架构 WebRTC视频 02 - 视频采集类 VideoCaptureModule WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇 WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇&#xff08;本文&#xff09; WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇 一、前言…

AI在电商平台中的创新应用:提升销售效率与用户体验的数字化转型

1. 引言 AI技术在电商平台的应用已不仅仅停留在基础的数据分析和自动化推荐上。随着人工智能的迅速发展&#xff0c;越来越多的电商平台开始将AI技术深度融合到用户体验、定价策略、供应链优化、客户服务等核心业务中&#xff0c;从而显著提升运营效率和用户满意度。在这篇文章…

Blossom:开源私有部署的markdown笔记软件

在信息化、数字化时代&#xff0c;我们每个人的生活和工作都离不开笔记和知识管理。从简单的待办事项&#xff0c;到复杂的项目计划&#xff0c;再到存储大量个人知识的工具&#xff0c;如何选择一个高效、便捷且符合个人需求的笔记软件&#xff0c;成了许多人的难题。最近在逛…

Linux debian系统安装ClamTk开源图形用户界面(GUI)杀毒软件

一、ClamTk简介 ClamTk 是一个基于 ClamAV 的开源图形用户界面&#xff08;GUI&#xff09;杀毒软件。它使用 GTK2-Perl 脚本构建而成&#xff0c;支持32位与64位操作系统。ClamTk 提供了一个直观的用户界面&#xff0c;使得用户无需深入了解命令行即可完成大部分操作。它具备…

Linux 进程信号的产生

目录 0.前言 1. 通过终端按键产生信号 1.1 CtrlC&#xff1a;发送 SIGINT 信号 1.2 Ctrl\&#xff1a;发送 SIGQUIT 信号 1.3 CtrlZ&#xff1a;发送 SIGTSTP 信号 2.调用系统命令向进程发信号 3.使用函数产生信号 3.1 kill 函数 3.2 raise 函数 3.3 abort 函数 4.由软件条件产…

【大数据学习 | HBASE高级】hive操作hbase

一般在查询hbase的数据的时候我们可以直接使用hbase的命令行或者是api进行查询就行了&#xff0c;但是在日常的计算过程中我们一般都不是为了查询&#xff0c;都是在查询的基础上进行二次计算&#xff0c;所以使用hbase的命令是没有办法进行数据计算的&#xff0c;并且对于hbas…

微信小程序 https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中

授权登录后&#xff0c;拿到用户头像进行加载&#xff0c;但报错提示&#xff1a; https://thirdwx.qlogo.cn 不在以下 downloadFile 合法域名列表中 解决方法一&#xff08;未完全解决&#xff0c;临时处理&#xff09;&#xff1a;在微信开发者工具将不校验...勾上就可以访问…

rk3399开发环境使用Android 10初体验蓝牙功能

版本 日期 作者 变更表述 1.0 2024/11/10 于忠军 文档创建 零. 前言 由于Bluedroid的介绍文档有限&#xff0c;以及对Android的一些基本的知识需要了(Android 四大组件/AIDL/Framework/Binder机制/JNI/HIDL等)&#xff0c;加上需要掌握的语言包括Java/C/C等&#xff0…

1. Django中的URL调度器 (项目创建与简单测试)

1. 创建 Django 项目 运行以下命令创建一个名为 blog_project 的 Django 项目&#xff1a; django-admin startproject blog_project2. 创建博客应用 Django 中&#xff0c;项目可以包含多个应用。创建一个名为 blog 的应用&#xff1a; cd blog_project python manage.py …

数据结构(初阶4)---循环队列详解

循环队列 1.循环队列的结构  1).逻辑模式 2.实现接口  1).初始化  2).判断空和满  3).增加  4).删除  5).找头  6).找尾 3.循环队列的特点 1.循环队列的结构 1).逻辑模式 与队列是大同小异的&#xff0c; 其中还是有一个指向队列头的head指针&#xff0c; 也有一个指向尾…

【蓝桥杯算法】Java的基础API

1. BigInteger 的使用 1.1. 判素数 package 模板;import java.math.BigInteger; import java.util.Scanner;public class 判素数 {static Scanner in new Scanner(System.in);public static void main(String[] args) {int q in.nextInt();while (q-- > 0) {BigInteger …