MemCached缓存使用试验
一.基本原理
Memcached是一种分布式数据缓存技术,其基本原理是预先分配合理适当的内存空间,保存数据时根据保存Key的哈希码除模取余数的方法来选择分布式网络中的一台服务器保存数据。当需要查询数据时候使用同样的算法来取值。同JBoss Cache或EHCache比较,个人认为有如下有点:
(1)。配置使用简单,没有JBoss Cache,EHCache配置那样复杂,特别是相对于JbossCache来说,不需要配置复杂的JGoss TCP和UTP通讯;它只需要简单地给出多个服务器的IP地址就可以了。
(2)。可以异步查询或保存根据数据;也可以同步执行,这一步是由spymemcached来完成,其主要原理是使用了JDK5的java.util.concurrent包下的相关技术到达异步执行;
二.实验:
(1)安装Memcached服务端;
?? (2)启动Memcached服务端:
?
(3)查询MemCached服务端信息:
?
?
再输入:
Stats Slabs
得到如下:
?
(3)下载spymemcached客户端jar包,建立一个工程:
源码包:
本测试的做法是使用多个线程同时使用HttpClient去请求{ "http://www.sina.com/",
?????????? "http://www.yahoo.com/", "http://www.sohu.com/" };中的任意随机一个,Memcached缓冲时间为12秒。
初始化服务端:本机测试
String[] servers = { "127.0.0.1:11211" };
?????? Integer[] weights = { 3 };
?????? SockIOPool pool = SockIOPool.getInstance();
?????? pool.setServers(servers);
?????? pool.setWeights(weights);
设置最小最大初始Memcached连接线程大小
?????? pool.setInitConn(5);
?????? pool.setMinConn(5);?
pool.setMaxConn(250);
//线程空闲时间
?????? pool.setMaxIdle(1000 * 60 * 60 * 6);
?????? pool.setMaintSleep(30);
?????? pool.setNagle(false);
?????? pool.setSocketTO(3000);
?????? pool.setSocketConnectTO(0);
?????? pool.initialize();
//启用压缩缓冲
?????? mcc.setCompressEnable(true);
?????? mcc.setCompressThreshold(64 * 1024);?
? pool.initialize();
//启用压缩缓冲
?????? mcc.setCompressEnable(true);
?????? mcc.setCompressThreshold(64 * 1024);
测试的主函数:
TestCached tt = new TestCached();
每次一百个线程,每个线程连续50个Http请求
?????? int count = 100;
//不使用缓冲请求,false表示非false
?????? MemCachedThread r = new MemCachedThread(tt, false);
?????? long begin = System.currentTimeMillis();
?????? Thread[] ths = new Thread[count];
?????? for (int i = 0; i < count; i++)
?????? {
?????????? ths = new Thread(r);
?????????? ths.start();
?????? }
等待所有的线程执行完毕统计时间
?????? for (int i = 0; i < count; i++)
?????? {
?????????? ths.join();?
}
? long end = System.currentTimeMillis();
?????? long f = (end - begin) / 1000;
//先清除MemCached服务端对应值,这一部及时是多余,我们还没有缓冲
?????? for (int i = 0; i < urls.length; i++)
?????? {
?????????? mcc.delete(urls);
?????? }
//使用缓冲请求,true表示使用缓冲
?????? tt.time = 0;
?????? r = new MemCachedThread(tt, true);
?????? begin = System.currentTimeMillis();
?????? ths = new Thread[count];
?????? for (int i = 0; i < count; i++)
for (int i = 0; i < count; i++)
?????? {
?????????? ths.join();
?????? }
?????? end = System.currentTimeMillis();
?????? System.out.println("没有使用MemCached缓冲机制时间 time is??-------:????" + f);
?????? System.out.println("使用MemCached缓冲机制时间?? time is??-------:????" + (end - begin)
??????????????/ 1000);
????
public class MemCachedThread implements Runnable {
????TestCached??tt;
????boolean useCahced;??
????public void run() {
if(!useCahced)
?????? {
?????????? for(int i=0;i<50;i++)
????????{
????????????????tt.unUseCahceOutput();??
????????}
?????? }
?????? else
?????? {
?????????? for(int i=0;i<50;i++)
????????{
????????????????tt.useCahceOutput();
????????}
?????? }?
?}
保存缓冲,每个url和对应值保存时间
public void bulidCache(String key, String response)
????{
?????? mcc.set(key, response, new Date(12000));
????}
使用缓冲,从缓冲先得到数据,如果没有则http请求。得到之后保存
public void useCahceOutput()
????{
String url = urls[rd.nextInt(urls.length)];
?????? String response = (String) mcc.get(url);
?????? if (response == null)
?????? {
?????????? bulidCache(url, httpConnect(url));
?????? }
?????? output();
????}
10个线程,每个线程10个随机请求测试结果:
?
50个线程,每个线程10个随机请求测试结果:
?
100个线程,每个线程10个随机请求测试结果:
?
200个线程,每个线程10个随机请求测试结果,这时内存溢出。
解决办法,修改Eclipse启动参数:
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
缓冲优化方法:
(1)适当提高服务器连接数:pool.setMaxConn();
(2)改变Memcached服务端缓冲启动大小: Memcached .exe –m??128??默认64
总结:
通过Memcached缓存数据查询结果,减少数据库等访问次数,以提高动态Web应用的速度、提高可扩展性。