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
相关文章:

ZooKeeper单机、集群模式搭建教程
单点配置 ZooKeeper在启动的时候,默认会读取/conf/zoo.cfg配置文件,该文件缺失会报错。因此,我们需要在将容器/conf/挂载出来,在制定的目录下,添加zoo.cfg文件。 zoo.cfg logback.xml 配置文件的信息可以从二进制包…...

函数指针示例
目录: 代码: main.c #include <stdio.h> #include <stdlib.h>int Max(int x, int y); int Min(int x, int y);int main(int argc, char**argv) {int x,y;scanf("%d",&x);scanf("%d",&y);int select;printf(&q…...

vue如何实现组件切换
一、使用条件渲染 (v-if) <template><div><button click"currentView ComponentA">Show Component A</button><button click"currentView ComponentB">Show Component B</button><component-a v-if"curren…...

计算机视觉 1-8章 (硕士)
文章目录 零、前言1.先行课程:python、深度学习、数字图像处理2.查文献3.环境安装 第一章:概论1.计算机视觉的概念2.机器学习 第二章:图像处理相关基础1.图像的概念2.图像处理3.滤波器4.卷积神经网络CNN5.图像的多层表示:图像金字…...

整数唯一分解定理
整数唯一分解定理,也称为算术基本定理,是由德国数学家高斯在其著作《算术研究》中首次提出的。本文回顾整数唯一分解定理以及对应的几个重要结论。 一、整数唯一分解定理 整数唯一分解定理,也称为算术基本定理,是数论中的一个重…...

Grass脚本2倍速多账号
前言,小编也是第一次撸空投,我是抱着试一试的态度,梦想总是要有的万一白嫖了呢 Grass 是什么? Grass 扩展程序是一款创新的工具,它可以帮助您释放未使用的网络资源的力量。 通过分享您的剩余带宽,您可以赚…...

15分钟学 Go 第 56 天:架构设计基本原则
第56天:架构设计基本原则 学习目标 理解和掌握基本的架构设计原则,以提升软件系统的可维护性、可扩展性和可重用性。 内容提纲 架构设计原则概述常见架构设计原则 单一职责原则 (SRP)开放/封闭原则 (OCP)里氏替换原则 (LSP)接口分离原则 (ISP)依赖反…...

HTML5 Video(视频)
HTML5 Video(视频) HTML5视频是现代网页设计中不可或缺的一部分,它允许开发者在网页中嵌入视频内容,为用户提供丰富多样的媒体体验。本文将深入探讨HTML5视频的各个方面,包括其基本用法、支持的格式、自定义播放器、浏览器兼容性以及最佳实践。 一、HTML5视频的基本用法 …...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-串行调用多个tools(三)
一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

MySQL:表设计
表的设计 从需求中获得类,类对应到数据库中的实体,实体在数据库中表现为一张一张的表,类中的属性就对应着表中的字段(也就是表中的列) 表设计的三大范式: 在数据库设计中,三大范式࿰…...

173. 二叉搜索树迭代器【 力扣(LeetCode) 】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 173. 二叉搜索树迭代器 一、题目描述 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: BSTIterato…...

大三学生实习面试经历(1)
最近听了一位学长的建议,不能等一切都准备好再去开始,于是就开始了简历投递,恰好简历过了某小厂的初筛,开启了线上面试,记录了一些问题: (通过面试也确实了解到了自己在某些方面确实做的还不够…...

【论文复现】STM32设计的物联网智能鱼缸
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀STM32设计的物联网智能鱼缸 【1】项目功能介绍【2】设计需求总结【3】项目硬件模块组成 1.2 设计思路【1】整体设计思路【2】ESP8266工作模式…...

常见长选项和短选项对应表
长选项和短选项的等效形式 在命令行工具中,这种长选项(如--delete)和短选项(如-d)等效的情况很常见。例如--verbose和-v(用于输出详细信息),--quiet和-q(用于安静模式&a…...

Ubuntu24 上安装搜狗输入法
link 首先在终端中依次输入以下代码 sudo apt update sudo apt install fcitx 找到语言支持 在终端中依次输入 sudo cp /usr/share/applications/fcitx.desktop /etc/xdg/autostart/ sudo apt purge ibus 进入网页 搜狗输入法linux-首页 shurufa.sogou.com/linux 找到刚才下…...

【AI图像生成网站Golang】JWT认证与令牌桶算法
AI图像生成网站 目录 一、项目介绍 二、雪花算法 三、JWT认证与令牌桶算法 四、项目架构 五、图床上传与图像生成API搭建 六、项目测试与调试(等待更新) 三、JWT认证与令牌桶算法 在现代后端开发中,用户认证和接口限流是确保系统安全性和性能的两大关键要素…...
关于强化学习的一份介绍
在这篇文章中,我将介绍与强化学习有关的一些东西,具体包括相关概念、k-摇臂机、强化学习的种类等。 一、基本概念 所谓强化学习就是去学习:做什么才能使得数值化的收益信号最大化。学习者不会被告知应该采取什么动作,而是必须通…...

Python3.11.9+selenium,获取图片验证码以及输入验证码数字
Python3.11.9+selenium,获取图片验证码以及输入验证码数字 1、遇到问题:登录或修改密码需要验证码 2、解决办法: 2.1、安装ddddocr pip install ddddocr 2.2、解析验证码函数 import ddddocr def get_capcha_text():#获取验证码图片ele_pic = driver.find_element(By.XPAT…...

Flutter:事件队列,异步操作,链式调用。
Flutter分2种队列 1、事件队列:异步的处理,按顺序执行 import package:flutter/material.dart; main(){testFuture1();testFuture2(); }// 按顺序执行处理A->B->C testFuture1() async {Future((){return 任务A;}).then((value){print(按顺序执行&…...

从零开始学习 sg200x 多核开发之 eth0 自动使能并配置静态IP
前文提到 sophpi 默认没有使能有线网络,需要手工配置: [rootsg200x]~# ifconfig eth0 up [rootsg200x]~# udhcpc -i eth0 [rootsg200x]~# ifconfig eth0 Link encap:Ethernet HWaddr EA:BD:18:08:1E:87 inet addr:192.168.188.142 Bcast:192.1…...

《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信
《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信 《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信进程间通信的基本概念通过管道实现进程间通信通过管道进行进程间双向通信 运用进程间通信习题(1)什么是进程间通信&…...

开源模型应用落地-qwen模型小试-Qwen2.5-7B-Instruct-tool usage入门-集成心知天气(二)
一、前言 Qwen-Agent 是一个利用开源语言模型Qwen的工具使用、规划和记忆功能的框架。其模块化设计允许开发人员创建具有特定功能的定制代理,为各种应用程序提供了坚实的基础。同时,开发者可以利用 Qwen-Agent 的原子组件构建智能代理,以理解和响应用户查询。 本篇将介绍如何…...

通过声纹或者声波来切分一段音频
通过声纹识别或基于声波特征的模型,确实可以帮助切分一段音频并区分出不同讲话者的语音片段。这种技术被称为 基于声纹的语音分割 或 基于说话人识别的音频分割。其核心原理是利用每个说话者的 声纹特征(即每个人独特的语音特征)来识别和切分…...

sql专场练习(二)(16-20)完结
第十六题 用户登录日志表为user_id,log_id,session_id,visit_time create table sql2_16(user_id int,log_id int,session_id int,visit_time string );没有数据 visit_time 时间格式为2024-11-15 用sql查询近30天每天平均登录用户数量 with t1 as (select visit_time,coun…...

[ 网络安全介绍 2 ] 网络安全发展现状
🍬 博主介绍 👨🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…...

《基于Oracle的SQL优化》读书笔记
查看执行计划set autotrace traceonly explain在当前session中将优化器模式改为RULE。alter session set optimizer_modeRULE;统计信息存储在oracle的数据字典里,且从多个维度描述了oracle数据库里相关对象的实际数据量,实际数据分布等详细信息。 -- 对…...

零基础利用实战项目学会Pytorch
目录 pytorch简介 1.线性回归 2.数据类型 2.1数据类型检验 2.2Dimension0/Rank0 2.3 Dim1/Rank1 2.4 Dim2/Rank2 3.一些方法 4.Pytorch完成分类任务 4.1模型参数 4.2 前向传播 4.3训练以及验证 4.4 三行搞定! 4.5 准确率 5、Pytorch完成回归任务 5.…...

Go八股(Ⅵ)Goroutine 以及其中的锁和思想
Goroutine与并发编程的关系 什么是并发 是指多个任务在同一时间段内进行处理,但不一定是在同一时刻执行。并发强调的是“结构上的并行性”,也就是说,程序能够在一个时间端内同时处理多个任务,但是这些任务可能是交替进行的。例如…...

向潜在安全信息和事件管理 SIEM 提供商提出的六个问题
收集和解读数据洞察以制定可用的解决方案是强大网络安全策略的基础。然而,组织正淹没在数据中,这使得这项任务变得复杂。 传统的安全信息和事件管理 ( SIEM ) 工具是组织尝试使用的一种方法,但由于成本、资源和可扩展性等几个原因࿰…...
蓝桥杯每日真题 - 第15天
题目:(钟表) 题目描述(13届 C&C B组B题) 解题思路: 理解钟表指针的运动: 秒针每分钟转一圈,即每秒转6度。 分针每小时转一圈,即每分钟转6度。 时针每12小时转一圈…...