zookeeper功能介绍(二)---java在zookeeper节点上存储及读取数据

介绍

上一节用java展示了zookeeper的数据结构。zookeeper不光能创建节点,还能在节点上存储数据。本节就讲述如何用java在zookeeper节点上存储并读出数据。

一、首先是jar包:


	com.101tec
	zkclient
	0.10

二、序列化及反序列化介绍

要在zookeeper节点上写入数据以及读取数据,需要对数据进行序列化及反序列化。而这一步不需要我们手工进行,但需要我们给zookeeper客户端设置好序列化工具对象,该对象需要实现org.I0Itec.zkclient.serialize.ZkSerializer接口。下面用java包的序列化功能编写一个zookeeper序列化工具.

ZkSerializer.java

package com.lan.LanUtil.temp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;

public class ZkSerialize implements ZkSerializer{

	/**
	 * 1序列化
	 */
	@Override
	public byte[] serialize(Object data) throws ZkMarshallingError {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			// 序列化
			baos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(baos);
			oos.writeObject(data);
			byte[] bytes = baos.toByteArray();
			return bytes;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				if(baos!=null) baos.close();
				if(oos!=null) oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 1反序列化
	 */
	@Override
	public Object deserialize(byte[] bytes) throws ZkMarshallingError {
		ByteArrayInputStream bais = null;
		ObjectInputStream ois = null;
		try {
			// 反序列化
			bais = new ByteArrayInputStream(bytes);
			ois = new ObjectInputStream(bais);
			return ois.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bais.close();
				ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

三、在节点上存储及读取数据

创建一个ZookeeperData.java类:

package com.lan.LanUtil.temp;

import java.util.List;

import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.ZkSerializer;

import com.lan.LanUtil.Student;

public class ZookeeperData {

	private static String zkServer = "192.168.9.188:2181";//zookeeper地址

	public static void main(String[] args) {
		ZkClient zkClient = new ZkClient(zkServer);//创建zookeeper的java客户端连接
		
		if(!zkClient.exists("/LAN")) {
			zkClient.createPersistent("/LAN");
		}
		Student stu1 = new Student();
		Student stu2 = new Student();
		stu1.setName("刘德华");
		stu2.setName("周星驰");
		zkClient.setZkSerializer(new ZkSerialize());//这里先设置好序列化工具再写入数据
		zkClient.createEphemeral("/LAN/liu", stu1);
		zkClient.createEphemeral("/LAN/zhou");
		zkClient.writeData("/LAN/zhou", stu2);
		showZkPathData(zkClient, "/LAN", new ZkSerialize());//展示LAN目录下的所有子目录
		
		zkClient.close();
	}

	/**
	  *  遍历展示目录下的所有节点
	 * @author LAN
	 * @date 2018年12月3日
	 * @param zkClient
	 * @param root
	 */
	public static void showZkPathData(ZkClient zkClient, String root, ZkSerializer serializer) {
		zkClient.setZkSerializer(serializer);
		List children = zkClient.getChildren(root);
		if(children.isEmpty()){
			return;
		}
		for(String s:children){
			String childPath = root.endsWith("/")?(root+s):(root+"/"+s);
			Object data = zkClient.readData(childPath, true);
			if(data!=null) {
				System.err.println(data.getClass());
			}
			System.err.println(childPath+"("+data+")");
			showZkPathData(zkClient, childPath, serializer);
		}
	}
}

运行结果如下:

在节点上写入数据可以直接在创建节点时写入,也可以节点创建后再用writeData方法写入。但重要的一点是写入数据前先设置好序列化工具。假如不设置,则会采用默认的java序列化工具。要求序列化和反序列化必须对应,否则就有可能数据存进去后无法读取出来。关于序列化和反序列化,可以选择其他的第三方序列化功能,效率可能会比java自带的序列化功能要好,如kryo序列化工具。

结语

zookeeper 4种类型的节点都可以存储数据,本节只是用临时节点作简单的介绍。zookeeper不光能在节点上写入及读取数据,还可以删除、修改、设置数据版本号等功能,这些功能本文不再作详细介绍。

 

author:蓝何忠

email:[email protected]

你可能感兴趣的:(zookeeper,Java)