MemCachedClient for 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();
	}
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值