`
qqzhuping
  • 浏览: 3318 次
文章分类
社区版块
存档分类
最新评论

memcached下集合对象的缓存

    博客分类:
  • java
阅读更多
memcached作为当下比较流行的缓存利器,有很多很多优点,也有一些自身的缺点。
很多时候,需要缓存一个list,可是Memcached颗粒度并不支持修改其中的元素,所以只能采用replace,就是把list整个取出,然后add/remove/modify之类再set回去。
这种解决方案不是很好,比如list增长的很大,又比如list内的对象都比较大。
很多时候可能存在这样的需求,list内的对象都有一定时效,比如30分钟,如果整个list存入memcached显然很难做到这一点,随着set整个List操作,list的时效会恢复成30分钟,虽然可能list内的部分元素你已经不再需要了,可是怎么把它们remove是个问题,这个问题可以在把整个List取出来进行一堆复杂算法之后可以实现,不过这种方法显然很糟糕。
这里提供了一种方法,可以尝试一下。
原本的数据结构式key-value(list);
现修改为 key_index - list[index]。
很显然这样设计的话,需要维护这个index。可能你觉得可以用List下标来实现。可是随着里面元素的增加修改删除或者失效,这样并不起作用,而且运用于分布式系统下这种方法并不明智。
这样的话我们需要一个东西来存储index。 memcached自身提供了一个counter功能。我们可以利用起来。
另外如果批量存进去之后,如何批量取出又是个问题了。还好memcached为我们提供了get(Collection)方法。
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.Counter;
import net.rubyeye.xmemcached.GetsResponse;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MemcachedClientManager{

	private static final MemcachedClientManager instance = new MemcachedClientManager();
	
	private static final int storeTime = 5 * 60;
	
	//待更新列表保存时效
	private static final String updateObjKey = "UpdateObj_";
	
	private static MemcachedClient memcachedClient;
	private static final long counterInitValue = 1;
	private static final long maxavilableValue = 10000;
	
	private static final String UpdateObjCounter = "UpdateObjCounter";
	
	public static List<String> UpdateObjList = new ArrayList<String>((int)maxavilableValue);
	
	static{
		for( long i = counterInitValue ; i <= maxavilableValue ; i++ ){
			UpdateObjList.add(new StringBuffer(updateObjKey).append(i).toString());
		}
	}
	
	private MemcachedClientManager()
	{
		ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
		memcachedClient = (MemcachedClient) app.getBean("memcachedClient");
	}
	
	public static MemcachedClientManager getInstance()
	{
		return instance;
	}

	/**
	 * 封装delete方法
	 */
	public void delete(String arg0) {
		
		try {
			memcachedClient.deleteWithNoReply(arg0);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 封装gets方法
	 */
	public <T> T get(String arg0) {
		
		try {
			return memcachedClient.get(arg0);
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public void replace(String arg0, int arg1, Object arg2) {
		try {
			memcachedClient.replaceWithNoReply(arg0, arg1, arg2);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void set(String arg0, int arg1, Object arg2) {
		try {
			memcachedClient.setWithNoReply(arg0, arg1, arg2);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public <T> Map<String, GetsResponse<T>> gets(Collection<String> arg0) {
		// TODO Auto-generated method stub
		try {
			return memcachedClient.gets(arg0);
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 计数器取值,支持分布式系统
	 */
	private long getCount(long min,long max,String key) {
		long count = min;
		Counter counter = memcachedClient.getCounter(key);
		try {
			count = counter.incrementAndGet();
			if(count > max){
				counter.set(min);
				count = min;
			}
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (TimeoutException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return count;
	}
	
	/**
	 * 存入list_index-value
	 */
	public void storeUpdateList(Bean obj)
	{
		try {
			long count = getCount(counterInitValue,maxavilableValue,UpdateObjCounter);
			String key = new StringBuffer(updateObjKey).append(count).toString();
			memcachedClient.setWithNoReply(key, storeTime, obj);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MemcachedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 根据键集获取值集
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> getKeys(List<String> keylist){
		List<T> rt = new ArrayList<T>();
		Map<String, GetsResponse<Object>>  map = gets(keylist);
		if( null != map && map.size() > 0 )
		{
			List<GetsResponse<Object>> list = new ArrayList<GetsResponse<Object>>(map.values());
			for(GetsResponse<Object> temp : list){
				T t = (T) temp.getValue();
				rt.add(t);
			}
		}
		return rt;
	}
}


application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
	<!-- http://code.google.com/p/xmemcached/wiki/Spring_Integration -->
	<context:property-placeholder location="memcache.properties" />
	<bean
		id="memcachedClientBuilder"
		class="net.rubyeye.xmemcached.XMemcachedClientBuilder"
		p:connectionPoolSize="${memcached.connectionPoolSize}"
		p:failureMode="${memcached.failureMode}"
		p:healSessionInterval="${memcached.healSessionInterval}">
		<!-- XMemcachedClientBuilder have two arguments.First is server list,and 
			second is weights array. -->
		<constructor-arg>
			<list>
				<bean class="java.net.InetSocketAddress">
					<constructor-arg>
						<value>${memcached.server1.host}</value>
					</constructor-arg>
					<constructor-arg>
						<value>${memcached.server1.port}</value>
					</constructor-arg>
				</bean>
				<!-- <bean class="java.net.InetSocketAddress">
					<constructor-arg>
						<value>${memcached.server2.host}</value>
					</constructor-arg>
					<constructor-arg>
						<value>${memcached.server2.port}</value>
					</constructor-arg>
				</bean> -->
			</list>
		</constructor-arg>
		<constructor-arg>
			<list>
				<value>${memcached.server1.weight}</value>
				<!-- <value>${memcached.server2.weight}</value> -->
			</list>
		</constructor-arg>
		<property name="commandFactory">
			<bean class="net.rubyeye.xmemcached.command.TextCommandFactory" />
		</property>
		<property name="sessionLocator">
			<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator" />
		</property>
		<property name="transcoder">
			<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
		</property>
	</bean>
	<!-- Use factory bean to build memcached client -->
	<bean
		id="memcachedClient"
		factory-bean="memcachedClientBuilder"
		factory-method="build"
		destroy-method="shutdown" />
</beans>


memcache.properties
#连接池大小即客户端个数
memcached.connectionPoolSize=50
memcached.failureMode=true
memcached.healSessionInterval=60000
#server1
memcached.server1.host=127.0.0.1
memcached.server1.port=11211
memcached.server1.weight=6
#server2
#memcached.server2.host=127.0.0.1
#memcached.server2.port=11212
#memcached.server2.weight=4			 	 


附上测试代码
public static void main(String[] args) {
		long beginTime = System.currentTimeMillis();
		MemcachedClientManager manager = MemcachedClientManager.getInstance();
		for( int i = 0 ; i< 12000 ; i ++ ){
			Bean obj = new Bean();
			obj.setName(String.valueOf(i));
			manager.storeUpdateList(obj);
		}
		
		List<Bean> rtList = manager.getKeys(MemcachedClientManager.UpdateObjList);
		
		long endTime = System.currentTimeMillis();
		
		//因为keylist设置了10000个 counter最大值也是10000 所以取出的列表最大为10000个
		System.out.println(rtList.size());
		System.out.println(endTime - beginTime);
	}
分享到:
评论

相关推荐

    memcached缓存使用演示

    Memcached是一款高性能、分布式内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问速度。它通过将数据存储在内存中,使得数据的读取速度大大提高,尤其在处理高并发请求时表现卓越。 ### ...

    韩顺平 PHP Memcached缓存技术资料源码笔记图解PPT_Ady

    Memcached是一款分布式内存对象缓存系统,广泛应用于高性能网站和应用中。它设计的目标是简化并加速动态Web应用程序的数据存储,通过将数据存储在内存中,避免频繁读取或写入数据库,从而提高系统响应速度。 二、...

    dot net memcached 分布式缓存应用类库

    Memcached是一款广泛使用的开源高性能分布式内存对象缓存系统,它能够减轻数据库的负载,提高应用程序的响应速度。在.NET环境中,开发人员可以借助特定的类库来集成Memcached,实现.NET应用的分布式缓存功能。本文将...

    分布式缓存 Redis + Memcached 经典面试题!.zip

    答:Memcached 以轻量级设计,快速响应,简单操作为特点,特别适合处理大量小对象的缓存需求。 - Redis 和 Memcached 各自适合什么场景? 答:Redis 适合需要复杂数据结构、持久化和高可用性的场景;Memcached ...

    .net memcached 分布式缓存应用类库

    Memcached是一个高性能、分布式内存对象缓存系统,常用于加速动态Web应用,通过将数据存储在内存中,减少对数据库的直接访问,从而提高了应用性能。 一、Memcached的基本概念与工作原理 1. **分布式**: Memcached...

    memcached完全剖析ehcache memcached redis 缓存技术总结

    1. **简介**:Memcached是一款高性能、分布式内存对象缓存系统,用于临时存储数据以提高网站的响应速度。 2. **工作原理**:基于键值对的存储,通过内存缓存数据,减少数据库查询。 3. **优点**:简单易用、高并发、...

    tomcat7+整合memcached jar包集合

    Memcached是一种分布式内存对象缓存系统,广泛用于减轻数据库压力,提高Web应用的性能。在这个场景中,jar包集合可能包含了实现这种集成所需的Java库。 描述中提到的“tomcat 整合nginx + memcache 进行负载均衡...

    memcached缓存

    `memcached` 是一个高性能、分布式的内存对象缓存系统,广泛应用于Web应用中,用于减轻数据库的负载,提高数据访问的速度。它通过将数据存储在内存中,使得数据访问几乎达到内存的速度,从而显著提升了应用的响应...

    多台tomcat服务的session共享 memcached

    Memcached是一种高性能的分布式内存对象缓存系统,可以用来实现多台Tomcat服务的Session共享。 Memcached是一个开源的、基于内存的对象缓存系统,使用 protocol-based 的方式来存储和检索数据。Memcached的优点是:...

    .NET分布式缓存Memcached从入门到实战源码下载

    Memcached是一款轻量级、高性能的分布式内存对象缓存系统,广泛应用于Web应用中。本文将深入探讨.NET环境下使用Memcached作为分布式缓存的实践,基于提供的源码进行分析。 首先,`ABenNet.Knowledge.Memcached.sln`...

    memcached配置session共享依赖jar包集合

    Memcached是一种高性能、分布式的内存对象缓存系统,常被用来解决session共享的问题。本篇将详细阐述如何利用Memcached配置session共享,并涉及所需依赖的jar包。 首先,Memcached作为一个缓存服务,能够存储会话...

    memcached_functions_mysql

    1. **Memcached**:这是一个分布式内存对象缓存系统,广泛用于Web应用中,用来缓存数据库查询结果,减少对数据库的访问,从而提高性能。 2. **MySQL**:这是一种流行的关系型数据库管理系统,常用于存储、管理和...

    memcached数据完整迁移到redis

    Memcached 是一个广泛使用的分布式内存对象缓存系统,它能提高 Web 应用程序的性能。它通过将数据存储在内存中,提供快速的访问速度。Memcached 的主要特点包括简单的键值对存储、内存优化的数据结构以及基于内存的...

    memcached jar 最新 tomcat 8.0 8.5

    Memcached是一种高性能、分布式内存对象缓存系统,用于在分布式环境中快速存储和检索数据。它通过将数据存储在内存中,极大地提高了数据访问速度,减轻了数据库的负载。在Java Web应用中,尤其是在使用Tomcat作为...

    memcached全部的jar包2.5.1.rar

    Memcached是一款高性能、分布式内存对象缓存系统,用于在分布式环境中快速存储和检索数据。它通过将数据存储在内存中,显著提高了数据访问速度,减轻了数据库的压力。在这个"memcached全部的jar包2.5.1.rar"压缩包中...

    memcached.zip

    **memcached** 是一个高性能、分布式内存对象缓存系统,常用于减轻数据库的负载,提高Web应用的响应速度。它将数据存储在内存中,而不是持久化到磁盘,因此可以实现快速读取。memcached的设计简单而高效,广泛应用于...

    memcached和redis比较

    Memcached和Redis是两种广泛使用的缓存解决方案,它们各有特点,在不同的场景下发挥着独特的作用。本文将详细比较这两种技术在可靠性、数据一致性、内存管理、内存使用率、应用场景、性能以及数据恢复等方面的不同之...

    memcached-1.4.22.tar.gz,magent6,memadmin

    Memcached是一款高性能、分布式内存对象缓存系统,常用于减轻数据库的负载,提高网站或应用的响应速度。它通过将数据存储在内存中,提供快速的数据访问,尤其适用于读取密集型应用。Memcached采用键值对(key-value...

    memcached学习总结

    Memcached是一款由Danga Interactive公司(LiveJournal的技术团队)所研发的分布式内存对象缓存系统,它最初是为了减轻数据库负载和提升动态网站性能而设计的。Memcached通过缓存数据库查询结果或者其他频繁访问的...

    Memcached_Session_Manager jar

    **Memcached** 是一个高性能、分布式内存对象缓存系统,它可以存储任意的数据类型,包括字符串、整数、对象等,并且适用于缓解数据库负载,提高网站性能。在Web应用中,Memcached常用来存储会话数据,以实现跨服务器...

Global site tag (gtag.js) - Google Analytics