【大数据技术基础 | 实验六】ZooKeeper实验:ZooKeeper进程协作
一、实验目的
掌握Java代码如何连接ZooKeeper集群及通过代码读写ZooKeeper集群的目录下的数据,掌握ZooKeeper如何实现多个线程间的协作。
二、实验要求
用Java代码实现两个线程,一个向ZooKeeper中某一目录中写入数据,另一线程监听此目录,若目录下数据有更新则将目录中数据读取并显示出来。
三、实验原理
通过ZooKeeper实现不同物理机器上的进程间通信。
场景使用:客户端A需要向客户端B发送一条消息msg1。
实现方法:客户端A把msg1发送给ZooKeeper集群,然后由客户端B自行去ZooKeeper集群读取msg1。
四、实验环境
- 云创大数据实验平台:
- Java 版本:jdk1.7.0_79
- Hadoop 版本:hadoop-2.7.1
- ZooKeeper 版本:zookeeper-3.4.6
五、实验步骤
本实验主要完成多线程通过ZooKeeper完成彼此间的协作问题,实验过程包含启动集群、编写代码、客户端提交代码三个步骤。
(一)启动ZooKeeper集群
启动ZooKeeper集群。具体步骤可以参考:【大数据技术基础 | 实验五】ZooKeeper实验:部署ZooKeeper。
(二)导入jar包
首先,我们在本地打开我们的开发工具Eclipse,然后创建一个名为ZooKeeperTest的Java项目。
创建完项目之后,我们需要从服务器上ZooKeeper安装包的lib目录下,将如下jar包导入到开发工具,我们需要用到WinSCP工具连接到服务器,然后直接进行拖拽到本地项目下的lib包内即可。从ZooKeeper安装包的lib目录下,将如下jar包导入到开发工具:
jline-0.9.94.jar
log4j-1.2.16.jar
netty-3.7.0.Final.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
zookeeper-3.4.6.jar
找到虚拟机内的ZooKeeper安装包的lib目录/usr/cstor/zookeeper/lib
,然后将lib下的这些jar包导入到我们本地的项目lib目录内:
一共有六个jar包,最后一个zookeeper-3.4.6.jar它在这个目录/usr/cstor/zookeeper/lib
的上一级里面:
然后我们需要将这六个jar导入到我们的项目中,我们右键每一个jar包 -> Build Path -> Add to Build Path 即可导入成功:
导入成功后显示如下:
(三)编写java代码
在开发工具编写Java代码,完成实验要求的功能,代码如下:
向/testZk
目录写数据线程代码实现:WriteMsg.java
import org.apache.zookeeper.ZooKeeper;
import java.util.Date;
public class WriteMsg extends Thread {
@Override
public void run() {
try {
ZooKeeper zk = new ZooKeeper("slave1:2181", 500000, null);
String content = Long.toString(new Date().getTime());
// 修改节点 /testZk 下的数据,第三个参数为版本,如果是 -1,则忽略数据版本,直接修改
zk.setData("/testZk", content.getBytes(), -1);
// 关闭 session
zk.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
监听/testZk
目录若数据改变则读取数据并显示线程代码实现:ReadMsg.java
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
public class ReadMsg {
public static void main(String[] args) throws Exception {
final ZooKeeper zk = new ZooKeeper("slave1:2181", 500000, null);
// 定义watch
Watcher watcher = new Watcher() {
public void process(WatchedEvent event) {
// 监听到数据变化时取出数据
if (EventType.NodeDataChanged == event.getType()) {
try {
byte[] bb = zk.getData("/testZk", null, null);
System.out.println("/testZk的数据: " + new String(bb));
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
// 设置watch
zk.exists("/testZk", watcher);
// 更新/testZk目录信息,触发watch
while (true) {
Thread.sleep(2000);
new WriteMsg().start();
// watch一次生效后就会被删除,需要重新设置
zk.exists("/testZk", watcher);
}
}
}
最后,要点击菜单栏中的Run,选择Run As -> Java Application。这将自动创建一个默认的运行配置。
(四)做成jar包
将上述代码打成jar包,注意要选择Runnable JAR file:
Launch configuration选择Read - ZooKeeperTest:(注意:若上一步中,没有选择Run As -> Java Application创建运行配置,这里则没有ReadMsg - ZooKeeperTest的选项)
用WinSCP工具上传到客户端节点:
六、实验结果
因为我们要在/testZk
目录写数据线程,但在上一期实验中我们最后删除了这个目录,所以我们需要重新启动客户端,然后创建/testZk
目录,然后退出。
./zkCli.sh -server master:2181,slave1:2181,slave2:2181
create /testZk ""
quit
然后我们执行如下命令即可执行代码:
java -jar /root/ZooKeeperTest.jar
在客户端提交jar包后运行Java代码,打印日志信息为ZooKeeper接收线程监控到/testZk
目录信息有变化时,读取该目录的内容:
七、实验心得
通过本次实验,我对ZooKeeper在分布式系统中的应用有了更深入的理解,尤其是在实现多线程和进程间通信方面的强大功能。实验的目标是掌握如何利用Java代码与ZooKeeper集群进行连接,并通过ZooKeeper来实现不同线程间的协作。在实验中,我实现了两个线程,其中一个负责向ZooKeeper的特定目录写入数据,另一个线程则监听该目录的变化,并在数据更新时读取和显示新的内容。这样的设计体现了ZooKeeper的协调服务在分布式环境中进行进程间通信的应用。
首先,实验需要配置和启动ZooKeeper集群,并导入相关的jar包,以便使用ZooKeeper的API进行开发。通过对代码的编写,我实现了向指定目录写入数据和监听数据变化的功能。在这个过程中,我不仅掌握了ZooKeeper的基本操作,如设置监听器和操作节点数据,还深入了解了如何使用Watcher机制来监听节点的变化。Watcher在数据更新时能够触发读取操作,这种机制对于监控和协调多线程有着重要意义。
此外,实验中遇到的一些问题也让我对分布式系统的调试有了新的体会。在反复调试和查看日志信息的过程中,我认识到数据一致性和节点状态管理对系统稳定性的关键作用。总的来说,通过本次实验,我不仅增强了对ZooKeeper基础操作的熟练度,还认识到其在大型分布式系统中作为协调服务的重要性。ZooKeeper的Watcher机制为高效的线程协作和数据一致性提供了可靠的保障,提升了我对分布式系统应用开发的兴趣和信心。
- 点赞
- 收藏
- 关注作者
评论(0)