`

MemCachedClient for java

    博客分类:
  • java
阅读更多
memcache的java客户端com.danga.MemCached.MemCachedClient的实现过程
其实很简单,就是一个socket通信过程
最后附上一个山寨版本的MemCachedClient
 
SockIOPool负责管理socket的pools
SockIO是SockIOPool的一个内部类,功能相当于Socket,可以读写数据
MaintThread是SockIOPool内部类,负责pool的runing和stop
MemCachedClient客户端调用类,拥有各种memcached的操作
NIOLoader是MemCachedClient的内部类,负责各种批量操作
 
 

以下是其实现中的一些罗列点

1.SockIOPool.getInstance()是取得名为default的pool
2.简单的一个创建SockIOPool 初始化pool
String[] serverlist = { "cache0.server.com:12345", "cache1.server.com:12345" };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.initialize();
3.MemCachedClient mcc = new MemCachedClient();就可以使用mcc了
4.get时的socket,向memcache服务器发送socket请求
  String cmd = "get " + key + "\r\n";
  sock.write( cmd.getBytes() );
  sock.flush();
5.getMulti时,按不同的host,组装成get key1 key2,再向服务端发送socket请求
   if ( !cmdMap.containsKey( sock.getHost() ) )
    {
      cmdMap.put( sock.getHost(), new StringBuilder( "get" ) );
    }
    cmdMap.get( sock.getHost() ).append( " " + cleanKey );
6.NATIVE_HASH模式下取得server(另外它还支持OLD_COMPAT_HASH ,NEW_COMPAT_HASH ,CONSISTENT_HASH)
  (long)key.hashCode()再取模
7.初始化socket
  SocketChannel sock = SocketChannel.open();
  sock.socket().connect( new InetSocketAddress( host, port ), timeout );
  return sock.socket();
8.省略N点

下面是一个山寨的MemCachedClient的实现

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 简单的MemcachedClient
 * 
 * @author gaoliang
 * @date 2011-3-11
 */
public class MemcachedClient {

	public static void main(String[] args) {
		MemcachedClient client = new MemcachedClient(new String[] {
				"127.0.0.1:11211", "127.0.0.1:12000" });
		client.add("aa", "aa");
		System.out.println(client.get("aa"));
		client.set("aa", "bb");
		System.out.println(client.get("aa"));
		client.replace("aa", "cc");
		System.out.println(client.get("aa"));
		client.delete("aa");
		System.out.println(client.get("aa"));
	}

	private Map<String, Socket> socketMap = new HashMap<String, Socket>();
	private List<String> hosts = new ArrayList<String>();
	private int num = 0; // 服务器数量

	public MemcachedClient(String[] servers) {
		init(servers);// 初始化并创建socket连接
	}

	public boolean add(String key, Object obj) {
		return Boolean.valueOf(write("add", key, obj, null));
	}

	public boolean add(String key, Object obj, Date date) {
		return Boolean.valueOf(write("add", key, obj, date));
	}

	public Object get(String key) {
		return write("get", key, null, null);
	}

	public boolean delete(String key) {
		return Boolean.valueOf(write("delete", key, null, null));

	}

	public boolean replace(String key, Object obj) {
		return Boolean.valueOf(write("replace", key, obj, null));
	}

	public boolean set(String key, Object obj) {
		return Boolean.valueOf(write("set", key, obj, null));
	}

	public Map<String,Object> getMulti(String[] keys){
		//省略100字
		//拼接get a b c
		//对返回的value做判断
		return null;
	}
	
	// 初始化并创建socket连接
	private void init(String[] servers) {
		try {
			for (String server : servers) {
				if (server.contains(":")) {
					String[] strs = server.split(":");
					socketMap.put(strs[0], new Socket(strs[0], Integer
							.valueOf(strs[1])));
					hosts.add(strs[0]);
					num++;
				}
			}
		} catch (Exception e) {
			System.out.println("init error");
		}
	}

	// 按hash取server的socket连接
	private Socket getSocket(String key) {
		int t = key.hashCode() % num;
		return socketMap.get(hosts.get(t));
	}

	// 向server发送命令,并返回结果
	private String write(String cmd, String key, Object obj, Date date) {
		byte[] value = null;
		if (obj != null) {
			value = obj.toString().getBytes();
		}
		
		//命令字符串
		String cmdStr = "";
		if ("add".equals(cmd) || "set".equals(cmd) || "replace".equals(cmd)) {
			cmdStr = String.format("%s %s %d %d %d\r\n", cmd, key, 32,
					date != null ? date.getTime() / 1000 : 0, value.length);
		}
		if ("get".equals(cmd)) {
			cmdStr = String.format("%s %s\r\n", cmd, key);
		}
		if ("delete".equals(cmd)) {
			cmdStr = String.format("%s %s\r\n", cmd, key);
		}
		Socket socket = getSocket(key);
		return getResponse(cmd, obj, cmdStr, socket);
	}

	//从数据器读取数据
	private String getResponse(String cmd, Object obj, String cmdStr,
			Socket socket) {

		try {
			BufferedOutputStream out = new BufferedOutputStream(socket
					.getOutputStream());
			DataInputStream in = new DataInputStream(socket.getInputStream());
			out.write(cmdStr.getBytes());
			if (obj != null) {
				out.write(obj.toString().getBytes());
				out.write("\r\n".getBytes());
			}
			out.flush();

			String response = readLine(in);
			if (("add".equals(cmd) || "set".equals(cmd) || "replace"
					.equals(cmd))
					&& "STORED".equals(response)) {
				return "TRUE";
			}
			if (("get".equals(cmd))) {
				if (response.contains("VALUE")) {
					String str = readLine(in);
					readLine(in);
					return str;
				} else {
					return null;
				}
			}
			if (("delete".equals(cmd)) && "DELETED".equals(response)) {
				return "TRUE";
			}
		} catch (Exception e) {
			System.out.println("write error");
			return "FALSE";
		}
		return "FALSE";
	}

	public String readLine(DataInputStream in) throws IOException {

		byte[] b = new byte[1];
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		boolean eol = false;

		while (in.read(b, 0, 1) != -1) {
			if (b[0] == 13) {
				eol = true;
			} else {
				if (eol) {
					if (b[0] == 10)
						break;

					eol = false;
				}
			}
			bos.write(b, 0, 1);
		}

		return bos.toString().trim();
	}
}
 
分享到:
评论

相关推荐

    memcached client for java

    memcached的java客户端jar包,方便调用memcached的服务

    spring调用memcached client for java

    spring调用memcached client for java

    基于memcached client for java的cache封装

    NULL 博文链接:https://guazi.iteye.com/blog/1071646

    memcached for java client 例子

    关于memcache 使用的 客户端是memcached client for java 的 JAVA工程

    Spring memcached 源码

    下载压缩包,解压查看里面的 OrgManagerServiceImpl 类的方法,已经测试过Spring集成配置Memcached 成功的

    memcached java client

    java memcached client xmemcached memcache-client-forjava

    Xmemcached测试实例

    测试类包括Xmemcached客户端与memcached client for java两者,可运行比较性能。 XMemcached简介: XMemcached是基于 java nio的Memcached客户端,java nio相比于传统阻塞 io 模型来说,有 效率高(特别在高并发下...

    Xmemcached memcached 实例

    类包括Xmemcached客户端实现和builder实现以及memcached client for java实现,对初学者有借鉴作用,特别是在开发简单例子时出现的超时情况的可以看看是否是同本事例相同。 xmemcached time out 5000 1000

    memcached for java

    由memcached开发人员维护的一个 java客户端,效率比较高,比较稳定

    java_memcached-release_2.5.1

    这次主要的优化工作还是在三个方面:应用服务器(Apache,JBoss)配置,业务流程,Cache Client包(http://code.google.com/p/memcache-client-forjava/ )。这里把过去和这次优化对于Cache的使用作一个经验分享,...

    Memcached-Client源码

    memcached在Java客户端调用时的源码。memcached源码中有一个bug,ip的传参形式为192.168.1.1:12301,到了sockiopool.java中用split(";")来解析ip和端口。这种情况在ipv6的环境下是行不通的。因为v6地址是[xxxx:xx:...

    memcached 完整的项目,服务端(win) 客户端 包括jar包

    memcache java client 2.6.3版本,包括完整的jar包. memcached win 服务端.

    MemcachedDemo

    包含memcached win32 和 win64的安装包 memcached_client_for_java 和spymemcached这两种连接方式的代码 以及需要的jar包,安装memcached服务后可以直接运行

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java开源包1

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包4

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包101

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包11

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

Global site tag (gtag.js) - Google Analytics