Linux安装memcached

http://www.cnblogs.com/zgx/archive/2011/08/10/2134097.html

使用xmemcached的时候,

可以参考这里,http://code.google.com/p/xmemcached/wiki/memcached_distributed,使用xmemcached提供的分布式算法。

如果使用普通的取余算法,那么在增加更多节点的时候,会使得命中率迅速下降。但是当使用一致性哈希算法的时候,会很大程度的减少重新填充缓存的部分。进而使得命中率不至于下降太多。

使用一致性哈希的时候,看代码:

package comz;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
import net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator;
import net.rubyeye.xmemcached.utils.AddrUtil;

/**
 * 测试节点的添加和删除对缓存命中率的影响
 * 
 * 从一篇英文文章中做单词频率统计,以单词为key,统计的次数为value,存储在10个节点上 添加两个节点后测试,查看各个节点的命中率变化。
 * 
 * @author Administrator
 * 
 */
public class CacheHitRateTest {

	public static void main(String[] args) throws Exception {
		String ip = "127.0.0.1";

		// 替换这个HashAlgorithm进行测试
		// HashAlgorithm hashAlg = HashAlgorithm.NATIVE_HASH;

		// XMemcachedClient client = new XMemcachedClient(
		// new KetamaMemcachedSessionLocator(hashAlg));
		MemcachedClientBuilder builder = new XMemcachedClientBuilder();
		builder.setSessionLocator(new KetamaMemcachedSessionLocator());
		MemcachedClient mc = builder.build();
		mc.addServer(ip, 11211);
		mc.addServer(ip, 11212);
		mc.addServer(ip, 11213);
		mc.addServer(ip, 11214);
		mc.addServer(ip, 11215);
		mc.addServer(ip, 11216);
		mc.addServer(ip, 11217);
		mc.addServer(ip, 11218);
		mc.addServer(ip, 11219);

		// 初始化数据
		Set<String> keys = init(mc);
		// testHashPerfromance(keys, HashAlgorithm.CRC32_HASH);
		// testHashPerfromance(keys, HashAlgorithm.KETAMA_HASH);
		// testHashPerfromance(keys, HashAlgorithm.FNV1_32_HASH);
		// testHashPerfromance(keys, HashAlgorithm.NATIVE_HASH);
		// testHashPerfromance(keys, HashAlgorithm.MYSQL_HASH);
		// 此时应该是100%
		printHitRate(mc, keys);
		// 添加两个节点后,查看命中率
		mc.addServer(ip, 11220);

		printHitRate(mc, keys);
		mc.shutdown();
	}

	// private static void testHashPerfromance(Set<String> keys,
	// HashAlgorithm hashAlg) {
	// long start = System.currentTimeMillis();
	// for (int i = 0; i < 1000; i++) {
	// for (String key : keys) {
	// hashAlg.hash(key);
	// }
	// }
	// System.out.println(hashAlg.name() + ":"
	// + (System.currentTimeMillis() - start));
	// }

	private static void printHitRate(MemcachedClient client, Set<String> keys)
			throws TimeoutException, InterruptedException, MemcachedException {
		int total = 0;
		int hits = 0;
		for (String key : keys) {
			total++;
			if (client.get(key) != null)
				hits++;
		}
		System.out.println("hit rate=" + (double) hits / total);
	}

	/**
	 * 初始化,统计单词并存储到10个节点,单词统计并不严谨,只是为了让key比较随机
	 * 
	 * @param client
	 * @throws Exception
	 */
	public static Set<String> init(MemcachedClient client) throws Exception {
		// BufferedReader reader = new BufferedReader(
		// ResourcesUtils.getResourceAsReader("a.txt"));
		File file = new File("a.txt");
		Scanner cin = new Scanner(file);
		String line = null;
		Map<String, Integer> counters = new HashMap<String, Integer>();
		int i = 0;
		while (i++ != 20) {
			line = cin.nextLine();
			String[] words = line.split("[\\s,.,\"'?\t]+");
			for (String word : words) {
				word = word.trim();
				if (word.length() == 0)
					continue;
				if (counters.containsKey(word)) {
					counters.put(word, counters.get(word).intValue() + 1);
				} else {
					counters.put(word, 1);
				}
			}
		}
		System.out.println("words number=" + counters.keySet().size());
		Iterator<Map.Entry<String, Integer>> it = counters.entrySet()
				.iterator();
		while (it.hasNext()) {
			Map.Entry<String, Integer> entry = it.next();
			if (!client.set(entry.getKey(), 0, entry.getValue()))
				System.err.println("put error");
		}
		System.out.println("initialize successfully!");
		cin.close();
		return counters.keySet();
	}
}

输出:

words number=196
initialize successfully!
hit rate=1.0
hit rate=0.8877551020408163

可以看到,命中率在添加一个节点之后,仍然会达到88%以上。如果是按照取余的算法,那么可能就只有10-20%多了。

------------------------------------------------------

上面的这段代码是借鉴别人的 。在基础上改了一点地方,就是构建一致性哈希的那三句代码。

别人本来的意思是,测试哈希性能的。就是上面被注释掉的部分。

哈希性能,mysql_hash据说是从mysql中取出的哈希源码。性能最好的是native_hash。默认是KETAMA_HASH,它维持了一个最佳平衡,在增加两个节点后还能访问到绝大部分单词,并且数据分布在各个节点上的数目也相对平均,难怪作为默认散列算法。

你可能感兴趣的:(Linux安装memcached)