分布式缓存系统Memcached学习心得

xinanrusu 2012-11-28

分布式缓存系统Memcached学习心得--JavaEye技术网站(转)

默认分类2008-08-2915:16:46阅读98评论0字号:大中小订阅

缘起:在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。

Memcached是什么?

Memcached是由DangaInteractive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。

Memcached能缓存什么?

通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。

Memcached快么?

非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)来均衡任何数量的打开链接,使用非阻塞的网络I/O,对内部对象实现引用计数(因此,针对多样的客户端,对象可以处在多样的状态),使用自己的页块分配器和哈希表,因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。

DangaInteractive为提升DangaInteractive的速度研发了Memcached。目前,LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。而这些,是由一个由web服务器和数据库服务器组成的集群完成的。Memcached几乎完全放弃了任何数据都从数据库读取的方式,同时,它还缩短了用户查看页面的速度、更好的资源分配方式,以及Memcache失效时对数据库的访问速度。

Memcached的特点

Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问,因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。

Memcached的使用

一、Memcached服务器端的安装(此处将其作为系统服务安装)

下载文件:memcached1.2.1forWin32binaries(Dec23,2006)

1解压缩文件到c:\memcached

2命令行输入'c:\memcached\memcached.exe-dinstall'

3命令行输入'c:\memcached\memcached.exe-dstart',该命令启动Memcached,默认监听端口为11211

通过memcached.exe-h可以查看其帮助

二、客户端使用

下载memcachedjavaclient:http://www.whalin.com/memcached/#download

1解压后将java_memcached-release_2.0.1.jarjar包添加到工程的classpath中

2利用memcachedjavaclient一个简单的应用

packagecom.danga.MemCached.test;importjava.util.Date;importcom.danga.MemCached.MemCachedClient;importcom.danga.MemCached.SockIOPool;publicclassTest{protectedstaticMemCachedClientmcc=newMemCachedClient();String[]servers={"192.168.40.4:12000"};Integer[]weights={3};SockIOPoolpool=SockIOPool.getInstance();//settheserversandtheweightspool.setServers(servers);pool.setWeights(weights);//setsomebasicpoolsettings//5initial,5min,and250maxconns//andsetthemaxidletimeforaconnpool.setInitConn(5);pool.setMinConn(5);pool.setMaxConn(250);pool.setMaxIdle(1000*60*60*6);//setthesleepforthemaintthread//itwillwakeupeveryxsecondsand//maintainthepoolsizepool.setMaintSleep(30);//对上一次发送的包的确认信息到来;这个方法就可以关闭套接字的缓存,pool.setNagle(false);pool.setSocketTO(3000);pool.setSocketConnectTO(0);//initializetheconnectionpoolpool.initialize();//letssetsomecompressiononfortheclient//compressanythinglargerthan64kmcc.setCompressEnable(true);mcc.setCompressThreshold(64*1024);}publicstaticvoidbulidCache(){//set(key,value,Date),Date是一个过期时间,如果想让这个过期时间生效的话,这里传递的newDate(longdate)中参数date,需要是个大于或等于1000的值。//因为javaclient的实现源码里是这样实现的expiry.getTime()/1000,也就是说,如果小于1000的值,除以1000以后都是0,即永不过期mcc.set("test","ThisisatestString",newDate(11211));}publicstaticvoidoutput(){Stringvalue=(String)mcc.get("test");System.out.println(value);}publicstaticvoidmain(String[]args){bulidCache();output();}}评论有个问题, 感觉memcache只是解决了大数据量的查询问题,不存在更新。

如果在另一种情况下,我需要频繁的对cache中的内容查询,再更新,再set到memcahe中。

而同时,这些更新的数据也要写回数据库,否则数据库中的数据不是最新的。

想问下,从cache中不停的写回DB的性能消耗大吗? 也就是,memcache能不能满足这种应用需求。

还有,在查询、更新的时候,memcache是不是能保障线程的安全?bottom写道

memcached非常快,但我没说过比本机的ehcache还快,但用本地缓存有两点不爽:

1.缓存放在内存or放在磁盘?应用重启会导致内存缓存丢失,放在磁盘又不够快。内存开多大合适?如果是大访问量应用,缓存对象集中淘汰可能引起服务器load急剧波动(我们吃过亏,现在也开ehcache,但缓存对象的上限开的很小)

2.集群应用里缓存对象如何共享?jbosscache用的是广播,访问量大的时候,可以把你的服务拖死,这个我们也吃过亏

当然,有人谈到了sohu的例子,一旦访问量大了,各种缓存都得用着,目前我们就是squid+memcached+ehcache。squid也是好东西,但缓存内容删除不太灵活,比较适合web1.0,比如新浪搜狐的新闻

另外,javamemcachedclient用1.6好了,没必要升级到2.1,2.X似乎还不太稳定。论坛、sns这样的应用,会使用多种技术进行缓存。

拿sohu的bbs来说吧,pv为5000w,峰值8000w

其中帖子、评论读写频繁,其他部分读频繁。

帖子列表、评论列表使用c开发(其中排序算法很巧妙),socket调用

帖子、评论内容使用squid缓存

其他读频繁的部分使用memcached、squid、定时生成静态页面等多种技术。

数据库用mysql,分表。

个人认为,小规模应用中,jvm级别的cache可以用用,memcached可用可不用

大规模网站应用,肯定是系统水平切分,多种cache结合。javaeyename写道woodless写道caoyangx写道robbin写道xtcn写道

CacheServer的可靠性比DBServer还要高,你这种假设不成立。或者你应该这样假设:

所以不能过于依赖于数据库,

你的设计要保证没有数据库的情况下,网站能够照常提供服务,

不然,万一出现大规模的数据库服务器的问题,后果会很严重:)

减少数据库的IO是正确的。

但是没有数据库的情况下,网站还要照常提供服务也太牛x了把!

门户级别的网站,数据库正如其名:数据库,只是负责保存数据

页面使用cms发布成静态页,要么放squid,要么放cdn

门户的更新相对慢一些,比如sns,论坛这种要及时更新,全静态化恐怕不行吧!

那要看颗粒度,如果你理解的cache总是page级别的那么就无话可说了.woodless写道caoyangx写道robbin写道xtcn写道

CacheServer的可靠性比DBServer还要高,你这种假设不成立。或者你应该这样假设:

所以不能过于依赖于数据库,

你的设计要保证没有数据库的情况下,网站能够照常提供服务,

不然,万一出现大规模的数据库服务器的问题,后果会很严重:)

减少数据库的IO是正确的。

但是没有数据库的情况下,网站还要照常提供服务也太牛x了把!

门户级别的网站,数据库正如其名:数据库,只是负责保存数据

页面使用cms发布成静态页,要么放squid,要么放cdn

门户的更新相对慢一些,比如sns,论坛这种要及时更新,全静态化恐怕不行吧!caoyangx写道robbin写道xtcn写道

CacheServer的可靠性比DBServer还要高,你这种假设不成立。或者你应该这样假设:

所以不能过于依赖于数据库,

你的设计要保证没有数据库的情况下,网站能够照常提供服务,

不然,万一出现大规模的数据库服务器的问题,后果会很严重:)

减少数据库的IO是正确的。

但是没有数据库的情况下,网站还要照常提供服务也太牛x了把!

门户级别的网站,数据库正如其名:数据库,只是负责保存数据

页面使用cms发布成静态页,要么放squid,要么放cdnrobbin写道xtcn写道

CacheServer的可靠性比DBServer还要高,你这种假设不成立。或者你应该这样假设:

所以不能过于依赖于数据库,

你的设计要保证没有数据库的情况下,网站能够照常提供服务,

不然,万一出现大规模的数据库服务器的问题,后果会很严重:)

减少数据库的IO是正确的。

但是没有数据库的情况下,网站还要照常提供服务也太牛x了把!wangzy写道

hi,你们在使用spymemcached的时候,貌似他的binaryprotocol支持并不可用,在最新稳定版的memcached上,还是我用错啦?bottom写道

并不需要那么快。我们的应用读取memcached的网络流量是每秒有2MB的流量,是读取数据库的网络流量的大约5倍。但是你要知道现在随便的PC机都是千兆网卡,因此memcached的get/set操作的延时非常少,并不比echache的get/set慢多少。在一个完整的web应用当中,我的压力测试表明,性能差异<=5%楼主好像并不很了解memcached,我们公司已经用了好久,非常稳定,非常快,并发连接可以上到1w,我手头的应用常常保持在3-5k;它的快不仅是因为用了libevent,还因为它采取了“用内存冗余换存取速度”的内存管理策略,网上有文章专门分析它的内存分配回收管理的源码,讲的很清楚,在这上面jbosscache、ehcache、oscache跟它没法比;memcached的集群也非常好,听说国外有200+的memcached集群,我们也有这方面的尝试,效果也很好,一台down掉根本不会引起其他机器down掉,只是这台的数据丢了,需要慢慢积累回来;而且支持多客户端,java、php、python、ruby可以共享数据,就把它当作数据库用。

我的建议是:你的应用访问量比较大,对响应速度要求很高,对数据一致性要求一般时,用它,挡在数据库前面,非常爽(memcached是互联网公司开发的,正好满足这三个条件);如果应用不忙,用用ehcache就行了。刚刚发现的问题:

如果有人碰到将对象写入Memcached的时候,出现:

(CLIENT_ERRORbaddatachunk)

错误的时候,请检查一下你的KEY。看看里面有没有空格。

如果有空格的话会出现上面的错误。xtcn写道

CacheServer的可靠性比DBServer还要高,你这种假设不成立。或者你应该这样假设:

所以不能过于依赖于数据库,

你的设计要保证没有数据库的情况下,网站能够照常提供服务,

不然,万一出现大规模的数据库服务器的问题,后果会很严重:)nowonder写道之前调研memcached最大的问题是它是一个单点,是一种集中式的分布式,组成它的n台机器里只要有一个down了,整个就挂了...

1、并不会整个挂掉,只会访问某些cache内容无法命中

2、就算全部挂掉,Cache就是减少对数据库访问的,所以无非就是对数据库压力大一些而已,能有什么影响?

3、如果你希望Cache持久化,或者带有故障切换功能,可以用memcachedb。

相关推荐