Memcached 学习笔记一
(2010-03-26 17:03:19)
转载1???????Memcache是什么Memcache是danga.com的一个项目,最早是为?LiveJournal?服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。
它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。
???
为什么会有Memcache和memcached两种名称?
其实Memcache是这个项目的名称,而memcached是它服务器端的主程序文件名,
????
Memcache官方网站:http://www.danga.com/memcached,
?
2???????Memcache工作原理
首先?memcached?是以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,客户端可以由各种语言编写,目前已知的客户端?API?包括?Perl/PHP/Python/Ruby/Java/C#/C?等等。客户端在与?memcached?服务建立连接之后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符?key,存取操作均通过这个?key?进行,保存到?memcached?中的对象实际上是放置内存中的,并不是保存在?cache?文件中的,这也是为什么memcached?能够如此高效快速的原因。注意,这些对象并不是持久的,服务停止之后,里边的数据就会丢失。
?
与许多?cache?工具类似,Memcached?的原理并不复杂。它采用了C/S的模式,在?server?端启动服务进程,在启动时可以指定监听的?ip,自己的端口号,所使用的内存大小等几个关键参数。一旦启动,服务就一直处于可用状态。Memcached?的目前版本是通过C实现,采用了单进程,单线程,异步I/O,基于事件?(event_based)?的服务方式.使用?libevent?作为事件通知实现。多个?Server?可以协同工作,但这些?Server?之间是没有任何通讯联系的,每个?Server?只是对自己的数据进行管理。Client?端通过指定?Server?端的?ip?地址(通过域名应该也可以)。需要缓存的对象或数据是以?key->value?对的形式保存在Server端。key?的值通过?hash?进行转换,根据?hash?值把?value?传递到对应的具体的某个?Server?上。当需要获取对象数据时,也根据?key?进行。首先对?key?进行?hash,通过获得的值可以确定它被保存在了哪台?Server?上,然后再向该?Server?发出请求。Client?端只需要知道保存?hash(key)?的值在哪台服务器上就可以了。
?
????????其实说到底,memcache?的工作就是在专门的机器的内存里维护一张巨大的?hash?表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。
?
3???????如何使用建立Manager类??Java代码- package?com.alisoft.sme.memcached; ??
- ??
- import?java.util.Date; ??
- ??
- import?com.danga.MemCached.MemCachedClient; ??
- import?com.danga.MemCached.SockIOPool; ??
- ??
- public?class?MemCachedManager?{ ??
- ??
- ????//?创建全局的唯一实例???
- ????protected?static?MemCachedClient?mcc?=?new?MemCachedClient(); ??
- ??
- ????protected?static?MemCachedManager?memCachedManager?=?new?MemCachedManager(); ??
- ??
- ????//?设置与缓存服务器的连接池???
- ????static?{ ??
- ????????//?服务器列表和其权重???
- ????????String[]?servers?=?{?"127.0.0.1:11211"?}; ??
- ????????Integer[]?weights?=?{?3?}; ??
- ??
- ????????//?获取socke连接池的实例对象???
- ????????SockIOPool?pool?=?SockIOPool. getInstance_r(); ??
- ??
- ????????//?设置服务器信息???
- ????????pool.setServers(servers); ??
- ????????pool.setWeights(weights); ??
- ??
- ????????//?设置初始连接数、最小和最大连接数以及最大处理时间???
- ????????pool.setInitConn(5); ??
- ????????pool.setMinConn(5); ??
- ????????pool.setMaxConn(250); ??
- ????????pool.setMaxIdle(1000?*?60?*?60?*?6); ??
- ??
- ????????//?设置主线程的睡眠时间???
- ????????pool.setMaintSleep(30); ??
- ??
- ????????//?设置TCP的参数,连接超时等???
- ????????pool.setNagle(false); ??
- ????????pool.setSocketTO(3000); ??
- ????????pool.setSocketConnectTO(0); ??
- ??
- ????????//?初始化连接池???
- ????????pool.initialize(); ??
- ??
- ????????//?压缩设置,超过指定大小(单位为K)的数据都会被压缩???
- ????????mcc.setCompressEnable(true); ??
- ????????mcc.setCompressThreshold(64?*?1024); ??
- ????} ??
- ??
- ??????
- ????protected?MemCachedManager()?{ ??
- ??
- ????} ??
- ??
- ??????
- ????public?static?MemCachedManager??getInstance_r()?{ ??
- ????????return?memCachedManager; ??
- ????} ??
- ??
- ??????
- ????public?boolean?add(String?key,?Object?value)?{ ??
- ????????return?mcc.add(key,?value); ??
- ????} ??
- ??
- ????public?boolean?add(String?key,?Object?value,?Date?expiry)?{ ??
- ????????return?mcc.add(key,?value,?expiry); ??
- ????} ??
- ??
- ????public?boolean?replace(String?key,?Object?value)?{ ??
- ????????return?mcc.replace(key,?value); ??
- ????} ??
- ??
- ????public?boolean?replace(String?key,?Object?value,?Date?expiry)?{ ??
- ????????return?mcc.replace(key,?value,?expiry); ??
- ????} ??
- ??
- ??????
- ????public?Object??get_r(String?key)?{ ??
- ????????return?mcc. get_r(key); ??
- ????} ??
- ??
- ????public?static?void?main(String[]?args)?{ ??
- ????????MemCachedManager?cache?=?MemCachedManager. getInstance_r(); ??
- ????????cache.add("hello",?234); ??
- ????????System.out.print("get?value?:?"?+?cache. get_r("hello")); ??
- ????} ??
- }??
?建立数据对象Java代码- package?com.alisoft.sme.memcached; ??
- ??
- import?java.io.Serializable; ??
- ??
- public?class?TBean?implements?Serializable?{ ??
- ???????
- ????private?static?final?long?serialVersionUID?=?1945562032261336919L; ??
- ??
- ????private?String?name; ??
- ??
- ????public?String??getName_r()?{ ??
- ????????return?name; ??
- ????} ??
- ??
- ????public?void?setName(String?name)?{ ??
- ????????this.name?=?name; ??
- ????} ??
- }??
Java代码- </SPAN></SPAN> ??
- <PRE?class=java?name="code">?</PRE> ??
- </H1> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt"><SPAN?lang=EN-US><SPAN><SPAN?style="FONT-FAMILY:?&apos">???</SPAN></SPAN></SPAN><SPAN><SPAN?style="FONT-SIZE:?large">创建测试用例</SPAN></SPAN></H2> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt">?</H2> ??
- <PRE?class=java?name="code">package?com.alisoft.sme.memcached.test; ??
- ??
- import?junit.framework.TestCase; ??
- ??
- import?org.junit.Test; ??
- ??
- import?com.alisoft.sme.memcached.MemCachedManager; ??
- import?com.alisoft.sme.memcached.TBean; ??
- ??
- public?class?TestMemcached?extends?TestCase?{ ??
- ??
- ????private?static?MemCachedManager?cache; ??
- ??
- ????@Test??
- ????public?void?testCache()?{ ??
- ???????????
- ????????TBean?tb?=?new?TBean(); ??
- ????????tb.setName("E网打进"); ??
- ????????cache.add("bean",?tb); ??
- ???????????
- ????????TBean?tb1?=?(TBean)?cache. get_r("bean"); ??
- ????????System.out.println("name="?+?tb1. getName_r()); ??
- ????????tb1.setName("E网打进_修改的"); ??
- ???????????
- ????????tb1?=?(TBean)?cache. get_r("bean"); ??
- ????????System.out.println("name="?+?tb1. getName_r()); ??
- ????} ??
- ??
- ????@Override??
- ????protected?void?setUp()?throws?Exception?{ ??
- ????????super.setUp(); ??
- ????????cache?=?MemCachedManager. getInstance_r(); ??
- ????} ??
- ??
- ????@Override??
- ????protected?void?tearDown()?throws?Exception?{ ??
- ????????super.tearDown(); ??
- ????????cache?=?null; ??
- ????} ??
- ??
- } ??
- </PRE> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt">?<SPAN>测试结果</SPAN></H2> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt"><SPAN> ??
- <PRE?class=java?name="code">[INFO]?++++?serializing?for?key:?bean?for?class:?com.alisoft.sme.memcached.TBean ??
- [INFO]?++++?memcache?cmd?(result?code):?add?bean?8?0?93?(NOT_STORED) ??
- [INFO]?++++?data?not?stored?in?cache?for?key:?bean ??
- [INFO]?++++?deserializing?class?com.alisoft.sme.memcached.TBean ??
- name=E网打进 ??
- [INFO]?++++?deserializing?class?com.alisoft.sme.memcached.TBean ??
- name=E网打进 ??
- </PRE> ??
- ?</SPAN></H2> ??
?
建立Manager类
??
Java代码
- package?com.alisoft.sme.memcached; ??
- ??
- import?java.util.Date; ??
- ??
- import?com.danga.MemCached.MemCachedClient; ??
- import?com.danga.MemCached.SockIOPool; ??
- ??
- public?class?MemCachedManager?{ ??
- ??
- ????//?创建全局的唯一实例???
- ????protected?static?MemCachedClient?mcc?=?new?MemCachedClient(); ??
- ??
- ????protected?static?MemCachedManager?memCachedManager?=?new?MemCachedManager(); ??
- ??
- ????//?设置与缓存服务器的连接池???
- ????static?{ ??
- ????????//?服务器列表和其权重???
- ????????String[]?servers?=?{?"127.0.0.1:11211"?}; ??
- ????????Integer[]?weights?=?{?3?}; ??
- ??
- ????????//?获取socke连接池的实例对象???
- ????????SockIOPool?pool?=?SockIOPool. getInstance_r(); ??
- ??
- ????????//?设置服务器信息???
- ????????pool.setServers(servers); ??
- ????????pool.setWeights(weights); ??
- ??
- ????????//?设置初始连接数、最小和最大连接数以及最大处理时间???
- ????????pool.setInitConn(5); ??
- ????????pool.setMinConn(5); ??
- ????????pool.setMaxConn(250); ??
- ????????pool.setMaxIdle(1000?*?60?*?60?*?6); ??
- ??
- ????????//?设置主线程的睡眠时间???
- ????????pool.setMaintSleep(30); ??
- ??
- ????????//?设置TCP的参数,连接超时等???
- ????????pool.setNagle(false); ??
- ????????pool.setSocketTO(3000); ??
- ????????pool.setSocketConnectTO(0); ??
- ??
- ????????//?初始化连接池???
- ????????pool.initialize(); ??
- ??
- ????????//?压缩设置,超过指定大小(单位为K)的数据都会被压缩???
- ????????mcc.setCompressEnable(true); ??
- ????????mcc.setCompressThreshold(64?*?1024); ??
- ????} ??
- ??
- ??????
- ????protected?MemCachedManager()?{ ??
- ??
- ????} ??
- ??
- ??????
- ????public?static?MemCachedManager??getInstance_r()?{ ??
- ????????return?memCachedManager; ??
- ????} ??
- ??
- ??????
- ????public?boolean?add(String?key,?Object?value)?{ ??
- ????????return?mcc.add(key,?value); ??
- ????} ??
- ??
- ????public?boolean?add(String?key,?Object?value,?Date?expiry)?{ ??
- ????????return?mcc.add(key,?value,?expiry); ??
- ????} ??
- ??
- ????public?boolean?replace(String?key,?Object?value)?{ ??
- ????????return?mcc.replace(key,?value); ??
- ????} ??
- ??
- ????public?boolean?replace(String?key,?Object?value,?Date?expiry)?{ ??
- ????????return?mcc.replace(key,?value,?expiry); ??
- ????} ??
- ??
- ??????
- ????public?Object??get_r(String?key)?{ ??
- ????????return?mcc. get_r(key); ??
- ????} ??
- ??
- ????public?static?void?main(String[]?args)?{ ??
- ????????MemCachedManager?cache?=?MemCachedManager. getInstance_r(); ??
- ????????cache.add("hello",?234); ??
- ????????System.out.print("get?value?:?"?+?cache. get_r("hello")); ??
- ????} ??
- }??
?建立数据对象Java代码
- package?com.alisoft.sme.memcached; ??
- ??
- import?java.io.Serializable; ??
- ??
- public?class?TBean?implements?Serializable?{ ??
- ???????
- ????private?static?final?long?serialVersionUID?=?1945562032261336919L; ??
- ??
- ????private?String?name; ??
- ??
- ????public?String??getName_r()?{ ??
- ????????return?name; ??
- ????} ??
- ??
- ????public?void?setName(String?name)?{ ??
- ????????this.name?=?name; ??
- ????} ??
- }??
- </SPAN></SPAN> ??
- <PRE?class=java?name="code">?</PRE> ??
- </H1> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt"><SPAN?lang=EN-US><SPAN><SPAN?style="FONT-FAMILY:?&apos">???</SPAN></SPAN></SPAN><SPAN><SPAN?style="FONT-SIZE:?large">创建测试用例</SPAN></SPAN></H2> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt">?</H2> ??
- <PRE?class=java?name="code">package?com.alisoft.sme.memcached.test; ??
- ??
- import?junit.framework.TestCase; ??
- ??
- import?org.junit.Test; ??
- ??
- import?com.alisoft.sme.memcached.MemCachedManager; ??
- import?com.alisoft.sme.memcached.TBean; ??
- ??
- public?class?TestMemcached?extends?TestCase?{ ??
- ??
- ????private?static?MemCachedManager?cache; ??
- ??
- ????@Test??
- ????public?void?testCache()?{ ??
- ???????????
- ????????TBean?tb?=?new?TBean(); ??
- ????????tb.setName("E网打进"); ??
- ????????cache.add("bean",?tb); ??
- ???????????
- ????????TBean?tb1?=?(TBean)?cache. get_r("bean"); ??
- ????????System.out.println("name="?+?tb1. getName_r()); ??
- ????????tb1.setName("E网打进_修改的"); ??
- ???????????
- ????????tb1?=?(TBean)?cache. get_r("bean"); ??
- ????????System.out.println("name="?+?tb1. getName_r()); ??
- ????} ??
- ??
- ????@Override??
- ????protected?void?setUp()?throws?Exception?{ ??
- ????????super.setUp(); ??
- ????????cache?=?MemCachedManager. getInstance_r(); ??
- ????} ??
- ??
- ????@Override??
- ????protected?void?tearDown()?throws?Exception?{ ??
- ????????super.tearDown(); ??
- ????????cache?=?null; ??
- ????} ??
- ??
- } ??
- </PRE> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt">?<SPAN>测试结果</SPAN></H2> ??
- <H2?style="MARGIN:?13pt?0cm?13pt?28.8pt"><SPAN> ??
- <PRE?class=java?name="code">[INFO]?++++?serializing?for?key:?bean?for?class:?com.alisoft.sme.memcached.TBean ??
- [INFO]?++++?memcache?cmd?(result?code):?add?bean?8?0?93?(NOT_STORED) ??
- [INFO]?++++?data?not?stored?in?cache?for?key:?bean ??
- [INFO]?++++?deserializing?class?com.alisoft.sme.memcached.TBean ??
- name=E网打进 ??
- [INFO]?++++?deserializing?class?com.alisoft.sme.memcached.TBean ??
- name=E网打进 ??
- </PRE> ??
- ?</SPAN></H2> ??
?