在GAE/J中使用memcache
memcache其实也不算是一个很新的概念了,在各种大型网站中是运用的非常的多的。著名的Twitter的白鲸事件,也和memcache有着巨大的关系。想了解其背景概念的和八卦的,不妨Google一下。简而言之,memcache就是将那些经常需要查询的数据或者经常需要调用的外部文件,存在缓存之中,来减少数据库查询或者远程网络调用的浪费。这个概念在数据库的缓存中已经十分的悠久了,但是由于涉及到太多极低层次的代码编写,一般的程序员是不会接触到这的。现在有了memcache的帮助,能够很好的将这一思想移植到应用层面来,对大型项目的开发有着很大的帮助。
Google App Engine很早就有了memcache的支持,算是其天生的一个优势,在这里我简单的介绍一下如何在GAE/J中使用memcache。对Python感兴趣的同学就十分抱歉了。
首先我们假象一个例子,在GAE/J中有一个学校的学生系统,在一个有着4-5万人的大学里,如果该系统包括了所有的诸如选课,学习,注册,论坛等等各种信息,对于数据库的查询需求是非常的大的。不过,这种网虫又往往局限在部分学生之中,就比如学校邮箱,喜欢经常去check的和很少去check的都会存在。于是怎么能让那些经常使用的数据能够得到更好的利用呢?我们假定数据库中存有一个表,是Student表专门存放学生信息,学生无论是登录,还是做什么也好,都需要查询其Student信息。于是,我们来看memcache如何实现对Student的缓存。
首先我们生成一个JDO的POJO类,来存放学生信息,在这里简单开来:
[java]@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Inheritance(customStrategy = “complete-table”)
public class Student implements Serializable{
@PrimaryKey
@Persistent
private String uuid;
@Persistent
private String name;
@Persistent
private String email;
@Persistent
private String address;
public Student(){
this.uuid = UUID.randomUUID().toString();
//setter&getter
}[/java]
接着,我们需要创立一个Cache类,来负责缓存层的操作:
[java]
public class QueryCache {
private static final Logger log = Logger.getLogger(QueryCache.class
.getName());
private static QueryCache instance;
private Cache cache;
private QueryCache(){
try{
CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
cache = cacheFactory.createCache(Collections.emptyMap());
}catch(CacheException e){
log.severe(”Error in creating the cache”);
}
}
public static synchronized QueryCache getInstance(){
if(instance==null){
instance = new QueryCache();
}
return instance;
}
public void putInCache(String address, String student){
cache.put(address, student);
}
public String findInCache(String address){
if(cache.containsKey(address)){
return (String)cache.get(address);
}else{
return null;
}
}
}
[/java]
在这个类中,其单例模式下的构造函数生成了一个新的Cache,它的内部结构是一个Map。同时我们定义了两个方法,一个是将学生信息放进cache,一个是从cache中取出学生信息。
最后,我们创建一个Servlet,来进行学生信息的查询:
public class QueryServlet extends HttpServlet{
private static final Logger log = Logger.getLogger(QueryServlet.class.getName());
@Override
protected void doGet(HttpServletRequest req, HttpServletResposne resp) throws ServletException, IOException{
log.info(”Now start……”);
QueryCache cache = QueryCache.getInstance();
String studentC = cache.findInCache(”Address7694″);
if(studentC!=null){
resp.getWriter().write(”Found the item in cache!”);
}else{
resp.getWriter().write(”No hit in cache!”);
PersistenceManager pm = PMF.get().getPersistenceManager();
Query query = pm.newQuery(Student.class);
query.setFilter(”address==’Address7694′”);
List students = List query.execute();
if(students.iterator().hasNext()){
log.info(”Found one:”+student.toString());
resp.getWriter().write(”Found one:”+student.toString());
cache.putInCache(”Address7694″, student.toString());
}else{
log.info(”None found!”);
resp.getWriter().write(”None Found!”);
}
}
}
这样一个很简单的例子,显示出了整个memcache在GAE/J中的运用方法。当然这只是最最基础的,还有许多的东西需要思考,比如该在什么样的地方使用memcache,memcache的有效时间是多少等等。



