Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。
它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。
Memcached基于一个存储键值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
下面来了解下Memcached怎么用~~
一、准备工作
到http://code.jellycan.com/memcached/
下载memcached的windows版
再下载一个java_memcached-release.jar
二、安装
解压memcached-1.2.5-win32-bin.zip,CMD进入其目录,然后执行如下命令:
c:>memcached.exe -d install c:>memcached.exe -l 127.0.0.1 -m 32 -d start
第一行是安装memcached成为服务,这样才能正常运行,否则运行失败!
第二行是启动memcached的,这里简单的只分配32M内存了(默认64M),然后监听本机端口和以守护进行运行。
执行完毕后,我们就可以在任务管理器中看到memcached.exe这个进程了。
如果想要在同一台Windows机器中安装2个Memcached,请看这里
三、使用
现在服务器已经正常运行了,下面我们就来写java的客户端连接程序。
将java_memcached-release.zip解压,把java_memcached-release.jar文件复制到java项目的lib目录下,
然后我们来编写代码,比如我提供的一个应用类如下:
写个Main方法测试下:
public static void main(String[] args) { MemCached cache = MemCached.getInstance(); boolean result1 = cache.add("hello", 1234, new Date(1000 * 2));// 设置2秒后过期 System.out.println("第一次add : " + result1); System.out.println("Value : " + cache.get("hello")); boolean result2 =cache.add("hello", 12345, new Date(1000 * 2));// add fail System.out.println("第二次add : " + result2); boolean result3 =cache.set("hello", 12345, new Date(1000 * 2));// set successes System.out.println("调用set : " + result3); System.out.println("Value : " + cache.get("hello")); try { Thread.sleep(1000 * 2); System.out.println("已经sleep2秒了...."); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Value : " + cache.get("hello")); }
执行结果如下:
说明:
- 第二次add失败是因为"hello"这个key已经存在了。
- 调用set成功,是因为set的时候覆盖了已存在的键值对,这正是add和set的不同之处
- 设置过期之间之后,cache按时自动失效
上面的例子是对于基本数据类型,对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口。
因为memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的(java.io.NotSerializableException
下面来试试POJO的存储:
Main方法如下:
public static void main(String[] args) { MemCached cache = MemCached.getInstance(); Person p1 = new Person(); p1.setName("Jack"); cache.add("bean", p1); Person p2 = (Person) cache.get("bean"); System.out.println("name=" + p2.getName());//Jack p2.setName("Rose"); // cache.replace("bean", p2); Person p3 = (Person) cache.get("bean"); System.out.println("name=" + p3.getName()); }
上面的代码中,我们通过p2.setName("Rose")修改了对象的名字,
最后一行打印的会是什么呢?
name=Jack
name=Jack
Why?
这是因为我们修改的对象并不是缓存中的对象,而是通过序列化过来的一个实例对象
那么要修改怎么办?使用replace,注释掉的那一行把注释去掉就可以了。
四、其他
Memcached的命令参数说明
-p
-l
-d
start
-d
restart
-d
stop|shutdown
-d
install
-d
uninstall
-u
-m
-M
-c
-f
-n
-h
然后使用set、
add、
replace、
get、
delete来操作。
更详细操作可参照这里
五、Memcached的优势和不足
说到Memcached的优势,那当然是:速度快,操作简便,易扩展
不足的话,主要有2点:
- 数据的临时性(数据仅保存在内存中)
- 只能通过指定键来读取数据,不支持模糊查询
六、Memcached停止时的保障措施
如果数据库的访问量比较大,就需要提前做好准备,以便应对在memcached停止时发生的负载问题。
如果能在停止memcached之前,把数据复制到其他的server就好了。恩,这个可以通过repcached来实现。
repcached是日本人开发的实现memcached复制功能,
它是一个单master、单slave的方案,但它的master/slave都是可读写的,而且可以相互同步
如果master坏掉,slave侦测到连接断了,它会自动listen而成为master