网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
server.3=ubuntu:2890:3890
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/542d9f348b3f4c74b5c1bdaf944018b1.png)
`zoo2.cfg`和`zoo3.cfg`修改方式同理,配置如下
dataDir=/opt/zookeeper/data/zk2
clientPort=2182
server.1=ubuntu:2888:3888
server.2=ubuntu:2889:3889
server.3=ubuntu:2890:3890
dataDir=/opt/zookeeper/data/zk3
clientPort=2183
server.1=ubuntu:2888:3888
server.2=ubuntu:2889:3889
server.3=ubuntu:2890:3890
配置说明:
* `tickTime`:这个时间是作为 Zookeeper server之间或client与server之间维持心跳的时间间隔,也就是每一个 tickTime 时间就会发送一个心跳。
* `initLimit`:这个配置项是用来配置 Zookeeper 接受client(这里所说的client不是用户连接 Zookeeper server的client,而是 Zookeeper server集群中连接到 Leader 的 Follower server)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10个心跳的时间(也就是 tickTime)长度后 Zookeeper server还没有收到client的返回信息,那么表明这个client连接失败。
* `syncLimit`:这个配置项标识 Leader 与 Follower 之间发送消息。请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度。
* `dataDir`:Zookeeper 保存数据的文件夹,默认情况下,Zookeeper 将写数据的日志文件也保存在这个文件夹里。
* `clientPort`:这个port就是client连接 Zookeeper server的port。Zookeeper 会监听这个port,接受client的访问请求。
* `server.A=B:C:D`:当中 A 是一个数字。表示这个是第几号server;B 是这个server的 ip 地址;C 表示的是这个server与集群中的 Leader server交换信息的port;D 表示的是万一集群中的 Leader server挂了。须要一个port来又一次进行选举。选出一个新的 Leader。而这个port就是用来运行选举时server相互通信的port。假设是伪集群的配置方式,因为 B 都是一样,所以不同的 Zookeeper 实例通信port号不能一样,所以要给它们分配不同的port号。
创建zookeeper保存数据文件:
sudo mkdir -p /opt/zookeeper/data/zk1
sudo mkdir -p /opt/zookeeper/data/zk2
sudo mkdir -p /opt/zookeeper/data/zk3
创建节点标识:
在下面三个文件夹下分别创建myid文件
里面分别写1、2、3用于标识第几号server
cd /opt/zookeeper/data/zk1
echo 1 > myid
cd /opt/zookeeper/data/zk2
echo 2 > myid
cd /opt/zookeeper/data/zk3
echo 3 > myid
### 🕘 5.3 启动Zookeeper
cd /opt/zookeeper/
sudo chmod -R 777 data/
./bin/zkServer.sh start conf/zoo1.cfg
./bin/zkServer.sh start conf/zoo2.cfg
./bin/zkServer.sh start conf/zoo3.cfg
查看启动状态:
./bin/zkServer.sh status conf/zoo1.cfg
./bin/zkServer.sh status conf/zoo2.cfg
./bin/zkServer.sh status conf/zoo3.cfg
运行截图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1f4f7dd368d34f9c83f92fbd60fab1cc.png)![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/5fd4fd1020884bc280e296890808f2cc.png)
验证zookeeper安装的正确性:
./bin/zkCli.sh -server 127.0.0.1:2182
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/897d211339da4a298d7b04bd2aecad05.png)
如果连接成功,会有Welcome to zookeeper!和state状态等信息。证明已经成功连接到zookeeper服务。
停止server的命令:
./bin/zkServer.sh stop conf/zoo1.cfg
./bin/zkServer.sh stop conf/zoo2.cfg
./bin/zkServer.sh stop conf/zoo3.cfg
## 🕒 6. ZooKeeper的Shell操作
### 🕘 6.1 帮助手册
[zk: 127.0.0.1:2182(CONNECTED) 0] help
ZooKeeper -server host:port -client-configuration properties-file cmd args
addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path [-b batch size]
delquota [-n|-b|-N|-B] path
get [-s] [-w] path
getAcl [-s] path
getAllChildrenNumber path
getEphemerals path
history
listquota path
ls [-s] [-w] [-R] path
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,…]]] | [-add serverId=host:port1:port2;port3[,…]] [-remove serverId[,…]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b|-N|-B val path
stat [-w] path
sync path
version
whoami
Command not found: Command not found help
[zk: 127.0.0.1:2182(CONNECTED) 1]
### 🕘 6.2 查看当前节点数据
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/077bd06edfa047e486305289faeae07d.png)
### 🕘 6.3 查看当前Zookeeper中所包含的内容
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/c2a80cde13354b379df0a33bcbfe5231.png)
### 🕘 6.4 创建节点
创建节点命令格式:`create [-s] [-e] [-c] [-t ttl] path [data] [acl]`
* `-s`:指定ZNode的类型为顺序节点。
* `-e`:指定ZNode的类型为临时节点,若不指定,则表示永久节点。
* `path`:表示创建的路径
* `data`:表示创建节点的数据,这是因为Znode可以像目录一样存在也可以像文件一样保存数据。
* `Acl`:进行权限控制。一般不需要了解。
示例:创建临时节点
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bd6b9b30f58041a6a7b65912a603a6a5.png)
### 🕘 6.5 获取节点
获取节点命令格式:`get [-s] [-w] path`
* `-s`:查看指定ZNode的属性。
* `-w`:向指定ZNode注册Watcher。
获取Zookeeper指定节点的数据内容以及属性信息:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/737c4edd7d034944a2f2015161cf2ffd.png)
### 🕘 6.6 修改节点
修改节点命令格式:`set [-s] [-v version] path data`
* `data`:表示要修改的内容,该数据内容不允许出现空格。
* `version`:表示数据版本
对前面创建的临时节点testnode-temp进行修改,使得节点内容变成“123”的操作:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/4775ee562f6249918352ff77f3c92c26.png)
### 🕘 6.7 监听节点
监听节点就是监听节点变化,概括为三个过程。客户端向服务端注册Watch、服务端事件发生触发Watch、客户端回调Watch得到触发事件的情况。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9a9835f33aa24799afc8b8facb4a982b.png)
### 🕘 6.8 删除节点
删除节点命令格式:`delete [-v version] path`
使用delete命令删除节点时,若要删除的节点存在子节点,就无法删除该节点,必须先删除子节点,才可删除父节点。使用`rmr`命令递归删除节点,不论该节点下是否存在子节点,可以直接删除。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d1e2ae2ce2104801959a1fd3bbedde2b.png)
## 🕒 7. ZooKeeper的Java API操作
Zookeeper API包含五个包:
org.apache.zookeeper
org.apache.zookeeper.data
org.apache.zookeeper.server
org.apache.zookeeper.server.quorum
org.apache.zookeeper.server.upgrade
org.apache.zookeeper包含Zookeeper类,这也是编程时最常用的类文件,Zookeeper类提供的常用Java API方法。
| 方法名称 | 方法描述 |
| --- | --- |
| create | 创建节点 |
| delete | 删除节点 |
| exists | 判断节点是否存在 |
| get/setData | 获取/修改节点数据 |
| getChildren | 获取指定节点下的所有子节点列表 |
### 🕘 7.1 在Eclipse中搭建ZooKeeper环境
新建Java项目,取名`ZooKeeperDemo`,之后Next,添加依赖
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9df2242d4dbd48a1b94cbc2db44825d1.png)
导入全部依赖,之后新建类`ZKTest`,开始写代码
### 🕘 7.2 创建会话
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
getConnect();
}
// 连接ZooKeeper服务
public static ZooKeeper getConnect()
throws IOException,InterruptedException {
String zkServer = "Ubuntu:2181"; // 此处Ubuntu改成自己的主机名
CountDownLatch countDownLatch = new CountDownLatch(1);
ZooKeeper zooKeeper = new ZooKeeper(zkServer, 3000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("通知状态:"+watchedEvent.getState() + "\t"
+ "事件类型:" + watchedEvent.getType() + "\t"
+ "节点路径:" + watchedEvent.getPath());
if (Event.KeeperState.SyncConnected == watchedEvent.getState()){
countDownLatch.countDown();
}
}
});
countDownLatch.await();
return zooKeeper;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3960dd56a0be4570b087907ba205ed16.png)
如图所示即成功连接。
### 🕘 7.3 创建ZNode
创建持久节点zkapi,并且在持久节点zkapi中挂载子节点zkChild,该子节点的ZNode类型为持久节点,createNode()方法的代码如下。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
createNode();
}
// 使用create方法创建ZNode
public static void createNode()
throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = getConnect();
connect.create(
"/zkapi",
"fruit".getBytes(),
ZooDefs.Ids.OPEN\_ACL\_UNSAFE,
CreateMode.PERSISTENT);
connect.create(
"/zkapi/zkChild",
"apple".getBytes(),
ZooDefs.Ids.OPEN\_ACL\_UNSAFE,
CreateMode.PERSISTENT);
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/f814ec3aa6a543139eaef95bf2e3dcad.png)
### 🕘 7.4 判断ZNode是否存在
判断永久节点zkapi是否存在,existsNode()方法的代码如下所示。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
Stat stat = existsNode();
if (stat != null){
System.out.println(“已存在”);
}else {
System.out.println(“不存在”);
}
}
// 使用exists方法判断ZNode是否存在
public static Stat existsNode()
throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = getConnect();
Stat exists = connect.exists("/zkapi", true);
return exists;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/70a054c76e5e44868b57fad542905643.png)
### 🕘 7.5 获取ZNode的数据内容
获取永久节点zkapi的数据内容,getNode()方法的代码如下所示。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
byte[] nodeData = getNode();
System.out.println(“持久节点zkapi的数据内容为:”+new String(nodeData));
}
// 使用getData方法获取ZNode的数据内容
public static byte[] getNode()
throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = getConnect();
byte[] data = connect.getData("/zkapi", true, null);
return data;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d67ca2493c2e4992bb4cc2ccaba4b1c2.png)
### 🕘 7.6 修改ZNode的数据内容
将持久节点zkapi的数据内容修改为fruit\_new,updateNode()方法的代码如下。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
Stat beforeStat = existsNode();
System.out.println(“持久节点zkapi修改数据内容前的数据版本号:”
+beforeStat.getVersion());
System.out.println(“持久节点zkapi修改数据内容前的数据内容长度:”
+beforeStat.getDataLength());
byte[] beforeNode = getNode();
System.out.println(“持久节点zkapi修改数据内容前的数据内容:”
+new String(beforeNode));
Stat afterStat = updateNode();
System.out.println(“持久节点zkapi修改数据内容后的数据版本号:”
+afterStat.getVersion());
System.out.println(“持久节点zkapi修改数据内容后的数据内容长度:”
+afterStat.getDataLength());
byte[] afterNode = getNode();
System.out.println(“持久节点zkapi修改数据内容后的数据内容:”
+new String(afterNode));
}
// 使用setData方法修改ZNode的数据内容
public static Stat updateNode()
throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = getConnect();
Stat stat = connect.setData(
"/zkapi",
"fruit\_new".getBytes(),
-1);
return stat;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/40d07b445b8347e4b77a45f66b8809e9.png)
### 🕘 7.7 查看ZNode的子节点列表
查看持久节点zkapi的子节点列表,getChildNode()方法的代码如下。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
List childNodes = getChildNode();
for (String childNode : childNodes) {
System.out.println(“持久节点zkapi的子节点:”+childNode);
}
}
// 使用getChildren方法查看ZNode的子节点列表
public static List<String> getChildNode()
throws IOException, InterruptedException, KeeperException {
ZooKeeper connect = getConnect();
List<String> nodeList = connect.getChildren("/zkapi", false);
return nodeList;
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2995374cd6064b64962ca4e6253cf410.png)
### 🕘 7.8 删除ZNode
该方法用于删除持久节点zkapi的子节点zkChild,deleteNode()方法的代码如下。
public class ZKTest {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
deleteNode();
List childNodes = getChildNode();
for (String childNode : childNodes) {
System.out.println(“持久节点zkapi的子节点:”+childNode);
}
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
n {
deleteNode();
List childNodes = getChildNode();
for (String childNode : childNodes) {
System.out.println(“持久节点zkapi的子节点:”+childNode);
}
[外链图片转存中…(img-8lQBkDC6-1715302848343)]
[外链图片转存中…(img-ff4cqoJc-1715302848343)]
[外链图片转存中…(img-EkjFiVpp-1715302848344)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新