0
在Scala里面玩XMemcached
1. 什么是memcache?什么是XMemcached?
基本上玩WEB开发的人都应该听说过memcache,简单说来,就是一种key-value式的分布式存储服务。一般用来做SQL的前端缓存,对于减轻数据库压力很有帮助。尽管叫mem,其I/O效率不能与内存I/O同日而语,主要是基于网络的,因此一般的共享内存数据,还是不推荐用memcache存储。XMemcached号称三大Java Memcached Client之一,貌似是中国人开发的,是个开源项目,比另外两个的优势可以去他们官网看看。因为JavaEye经常跟进这个项目,所以比较熟悉,就选它来做我的memcache client。
2. 为啥用Scala?
我无意挑起语言大战,之所以选用Scala,是因为我不想用最熟悉的Java,而且有好多年没碰Scala了,都快忘了,最近拣拣好了。连Gosling都离职了,不知道Java前途如何,而且用了一段时间的Python后,也觉得Java在有些方面比较烦。不过好在Oracle之前还握着BEA的JVM,相信JVM平台的前途还是无量的。用Scala玩一玩也好,Scala可以无缝使用Java的类库,因此虽然说XMemcached是Java的客户端,也可以说是Scala的客户端。
3. 那我们开始吧?
废话少说,直接上代码:
1 2 3 4 5 6 7 8 9 |
package org.odichy.memt import java.io.Serializable class Person(age: Int, name: String) extends Serializable { def age(): Int = age def name(): String = name override def toString() = "I am " + name +", I am " + age + " years old." } |
这个是我们要作为存储对象的类,因为memcached实际上存储的是字符串,所以要存对象的话,需要实现java.io.Serializable接口。本来一直以为interface可以和trait一样用with,但是IDE总报错,看来还是要extends。接下来是实际使用的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package org.odichy.memt import net.rubyeye.xmemcached.MemcachedClientBuilder import net.rubyeye.xmemcached.XMemcachedClientBuilder import net.rubyeye.xmemcached.utils.AddrUtil import net.rubyeye.xmemcached.MemcachedClient import net.rubyeye.xmemcached.exception.MemcachedException import java.util.concurrent.TimeoutException import java.io.IOException object Test { def main(args: Array[String]) { //添加一个memcache server地址到MemcachedClientBuilder val builder: MemcachedClientBuilder = new XMemcachedClientBuilder(AddrUtil.getAddresses("localhost:11211")) val mc: MemcachedClient = builder.build; val odin = new Person(22, "Odin Liu") try { //第二个参数是过期时间,0代表不设置,单位是秒 mc.set("key", 0, odin) val s: Person = mc.get("key") println("1:"+s.toString) //把"key"作为key的记录删掉 mc.delete("key") val t: Person = mc.get("key") if(t==null) { println("t is null") } else { println("2:"+t.toString) } } //Scala的try-catch实在太优雅了。。。。。 catch { case ex: MemcachedException => ex.printStackTrace case ex: TimeoutException => ex.printStackTrace case ex: InterruptedException => ex.printStackTrace } try { mc.shutdown } catch { case ex: IOException => ex.printStackTrace } } } |
得到输出如下:
1:I am Odin Liu, I am 22years old. t is null
4. 实际中怎么用?
一般来说比如我们要从数据库中查一组记录出来,如果频繁访问数据库,肯定影响性能,所以在访问数据库前,先去memcache server里面找找,看看有没有已经缓存了的记录,如果有直接返回给client,如果没有再去数据库里取,取回来之后先存到memcache server里面,然后再给client返回,这样下次再做查询时就可以直接返回了。当然根据更新频率,可以设置一个合适的过期时间,并且当更新数据时,就把缓存的记录删除,这样等到下次读取时,就可以得到最新的数据了。
对于一个读>写的网站来说,做了memcache的负载能力肯定要远比直接读SQL强得多。这也就是NoSQL vs SQL时,前者所说的,如果没有memcache,mysql很难用于生产环境当中。当然,这也是要访问量达到一定程度。
原文链接: http://blog.odichy.org/2010/04/12/%e5%9c%a8scala%e9%87%8c%e9%9d%a2%e7%8e%a9xmemcached.html