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.3docker run -d \--name zookeeper2 \-v /opt/zookeeperconf/zookeeper2/:/conf/ \-e ZOO_MY_ID=2 \zookeeper:3.9.3docker 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 addressat 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 refusedat 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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大数据学习 | HBASE高级】hbase-phoenix 与二次索引应用

1. hbase-phoenix的应用 1.1 概述&#xff1a; 上面我们学会了hbase的操作和原理&#xff0c;以及外部集成的mr的计算方式&#xff0c;但是我们在使用hbase的时候&#xff0c;有的时候我们要直接操作hbase做部分数据的查询和插入&#xff0c;这种原生的方式操作在工作过程中还…

Python入门(7)--高级函数特性详解

Python高级函数特性详解 &#x1f680; 目录 匿名函数&#xff08;Lambda&#xff09;装饰器的使用生成器与迭代器递归函数应用实战案例&#xff1a;文件批处理工具 1. 匿名函数&#xff08;Lambda&#xff09;深入解析 &#x1f3af; 1.1 Lambda函数基础与进阶 1.1.1 基本…

【环境配置】GPU - 加速深度学习

版本对应关系Previous PyTorch Versions | PyTorch 这里具体讨论需要使用GPU时的环境配置。Pytorch 和 torchvision 等框架可以利用 CUDA 和 cuDNN 提供的 GPU 加速功能,高效地处理大规模的深度学习任务,如计算机视觉中的图像分类、目标检测等任务。 1. NVIDIA 显卡硬件条件…

拆解测试显示Mac Mini (2024)固态硬盘并未锁定 互换硬盘后仍可使用

此前已经有维修达人尝试将 Mac Mini (2024) 固态硬盘上的 NAND 闪存拆下并替换实现扩容&#xff0c;例如可以从 256GB 扩容到 2TB。虽然接口类似于 NVMe M.2 SSD 但直接安装普通硬盘是无效的&#xff0c;苹果仍然通过某种机制检测硬盘是否能够兼容。 不过知名拆解网站 iFixit 的…

微服务中的技术使用与搭配:如何选择合适的工具构建高效的微服务架构

一、微服务架构中的关键技术 微服务架构涉及的技术非常广泛&#xff0c;涵盖了开发、部署、监控、安全等各个方面。以下是微服务架构中常用的一些技术及其作用&#xff1a; 1. 服务注册与发现 微服务架构的一个重要特性是各个服务是独立部署的&#xff0c;因此它们的地址&am…

STM32学习笔记之__attribute__

在STM32当中&#xff0c;运用__attribute__主要是确认把什么数据放置在什么地址上 举例&#xff1a; uint32_t g_test_buffer[250000] __attribute__((at(SRAM_BASE_ADDR))); 把g_test_buffer数组的数据放在SRAM_BASE_ADDR地址上。 参考&#xff1a;STM32学习笔记之__attrib…

Qt / Qt Quick程序打包的一些坑 (四)

【写在前面】 打包方法见 Qt / Qt Quick程序打包的方法。 这里是再次记录一些坑。 【正文开始】 直接进入正题&#xff1a; 在 Qt5 中&#xff0c;如果我们的 Qml 中使用了【Qt Shapes】模块&#xff0c;那么在打包的时候&#xff0c;会缺少Qt5QuickShapes.dll。 然后&#xff…

主界面获取个人信息客户端方

主界面获取个人信息客户端方 前言 上一集我们完成了websocket身份验证的内容&#xff0c;那么这一集开始我们将要配合MockServer来完成主界面获取个人信息的内容。 需求分析 我们这边是完成客户端那方的内容&#xff0c;当客户端登录成功之后&#xff0c;我们就要从服务器获…

Spring整合Redis

前言 在Spring项目中整合Redis&#xff0c;能显著提升数据缓存、分布式锁、会话管理等操作的效率。Jedis作为轻量级的Java Redis客户端&#xff0c;搭配Spring Data Redis模块&#xff0c;能够简化Redis的连接和数据操作&#xff0c;实现更高性能的读写与灵活的缓存管理。本文…

爬虫——Requests库的使用

在爬虫开发中&#xff0c;HTTP请求是与服务器进行交互的关键操作。通过发送HTTP请求&#xff0c;爬虫可以获取目标网页或接口的数据&#xff0c;而有效地处理请求和响应是爬虫能够高效且稳定运行的基础。Requests库作为Python中最常用的HTTP请求库&#xff0c;因其简洁、易用和…

深入描述dts和dtsi的区别

QA&#xff1a;dts和dtsi的区别 在嵌入式 Linux 系统中&#xff0c;DTS&#xff08;Device Tree Source&#xff09;和 DTSI&#xff08;Device Tree Source Include&#xff09;是描述硬件设备树的文件格式。它们本质上是同一种语法的文件&#xff0c;但在使用上有一定区别。…

LinkedHashMap实现LRU

LRU 环境&#xff1a;JDK11 最近接触LRU(Least Recently Used)&#xff0c;即最近最少使用&#xff0c;也称淘汰算法&#xff0c;在JDK中LinkedHashMap有相关实现 LRU的LinkedHashMap实现 LinkedHashMap继承HashMap。所以内存的存储结构和HashMap一样&#xff0c;但是LinkedH…

IDEA部署AI代写插件

前言 Hello大家好&#xff0c;当下是AI盛行的时代&#xff0c;好多好多东西在AI大模型的趋势下都变得非常的简单。 比如之前想画一幅风景画得先去采风&#xff0c;然后写实什么的&#xff0c;现在你只需描述出你想要的效果AI就能够根据你的描述在几分钟之内画出一幅你想要的风景…

27-压力测试

测试目标 & 测试数据 ● 测试目标 ○ 测试集群的读写性能 / 做集群容量规划 ○ 对 ES 配置参数进行修改&#xff0c;评估优化效果 ○ 修改 Mapping 和 Setting&#xff0c;对数据建模进行优化&#xff0c;并测试评估性能改进 ○ 测试 ES 新版本&#xff0c;结合实际场…

正则表达式常用字符

基础正则 ^:开头字符 $:结尾字符 ^$:空行 .:任意一个字符 *:前一个字符连续出现0次或以上 .*:所有 []&#xff1a;括号中的任意一个字符 [a-z] [a-zA-Z0-9] [a-zA-Z0-9] [^]:除括号内以外的字符 扩展正则 |:或 ssh|telnet|http ():表示整体 ^(ssh|telnet|http)^ssh|^telnet|^ht…

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明

4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明 文章目录 4. Spring Cloud Ribbon 实现“负载均衡”的详细配置说明前言1. Ribbon 介绍1.1 LB(Load Balance 负载均衡) 2. Ribbon 原理2.2 Ribbon 机制 3. Spring Cloud Ribbon 实现负载均衡算法-应用实例4. 总结&#x…

Redis 线程模型详解:理解 Redis 高效性能的关键

Redis 是一个开源的高性能键值存储系统&#xff0c;因其卓越的速度和强大的功能被广泛应用于各种场景&#xff0c;如缓存、消息队列和实时数据存储等。Redis 的性能优越不仅归功于其高效的数据结构和内存存储&#xff0c;还源于其独特的线程模型。本文将详细介绍 Redis 的线程模…

vue3【实战】切换全屏【组件封装】FullScreen.vue

效果预览 原理解析 使用 vueUse 里的 useFullscreen() 实现 代码实现 技术方案 vue3 vite UnoCSS vueUse 组件封装 src/components/FullScreen.vue <template><component:is"tag"click"toggle":class"[!isFullscreen ? i-ep:full-sc…

docker:基于Dockerfile镜像制作完整案例

目录 摘要目录结构介绍起始目录package目录target目录sh目录init.sh脚本start.sh脚本stop.sh脚本restart.sh脚本 config目录 步骤1、编写dockerfilescript.sh脚本 2、构件镜像查看镜像 3、保存镜像到本地服务器4、复制镜像文件到指定目录&#xff0c;并执行init.sh脚本5、查看挂…

lua实现雪花算法

lua实现雪花算法 雪花算法介绍组成部分优点缺点 代码示例 雪花算法介绍 雪花算法&#xff08;Snowflake Algorithm&#xff09;是一种用于生成唯一ID的分布式生成算法&#xff0c;最初由Twitter开发。它的主要目的是在分布式系统中生成唯一的、时间有序的ID&#xff0c;这些ID通…