`
hongtoushizi
  • 浏览: 378498 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

memcached一些应用点滴

 
阅读更多

 

 

大名鼎鼎的分布式缓存系统memcached,在开源社区中可谓是无人不知无人不晓,memcached支持分布式的横向扩展,但memcached的服 务端却是单实例,并无"分布式"的功能,所谓的分布式只是客户端在存储的主键做分布的存储;还有memcached组件缓存对象,如果组件无进行序列化必 定无法正确取得数据;如何使用memcached的java组件来监控memcached的运行状态;以上等等的问题是我在日常的工作中碰到并解决的,拿 出来跟大家做个分享^_^



对象的序列化
首先memcached是独立的服务器组件,独立于应用系统,从客户端保存和读取对象到memcached是必须通过网络传输,因为网络传输都是二进制的数据,所以所有的对象都必须经过序列化,否则无法存储到memcahced的服务器端.
正如我们以往在集群中应用的序列化一样,memcached的序列化的性能也是往往让大家头疼,如果我们对我们的domain类进行对象的序列化,第一次 序列化时间会比较长,但后续会优化,也就是说序列化最大的消耗不是对象的序列化,而是类的序列化,如果存储的只是一个String对象,这种情况是最理想 的,省去了序列化的操作.实际上String对象本身已经实现了序列化接口,无法我们再次去进行序列化操作.



memcached的原子加法
记录一下上次犯得一个错误

<%
static int count = 0;
count
++;
MemCachedClient mcc 
= new MemCachedClient();
mcc.add(
"test.html", count);
%>


这段代码的作用是将test.html的用户访问次数保存到memcached中,粗劣一看好像并无错误,但在高并发时的出来的访问数据一定是小于实际的 访问数量,当然这里并不是memcached对象锁的问题,主要还是程序中线程的同步问题,但是如果使用java的synchronized或lock那 么在性能上肯定是无法忍受的,memcached客户端组件带有原子性的加法和减法

<%
MemCachedClient mcc 
= new MemCachedClient();
System.out.println(mcc.addOrIncr(
"test.html",1));
%>


long addORIncr(String key,long inc)为计数器值增加inc,如果计数器不存在,则保存inc为计数器的值,必须注意的是服务器端不会对超过2的32次方的行为进行检查




分布式的mencached
memcached虽然是属于分布式的缓存服务器,但实际上memcached服务端之间并无分布式的功能,不会互相通信共享数据,如何进行分布式,这完全是取决于客户端的实现



假设我们现在有三台memcached服务器分别为node1,node2,node3,应用程序要保存键名分别 为"test1","test2","test3",客户端实现的算法就是根据键名来决定保存数据的memcached服务器,我们将"test1"保存 到node1,"test2"保存到node2,"test3"保存到node3,并且在读取缓存数据也是通过一样的算法从各台服务器上读取相应的 key,这样通过一个最简单的算法将不同的键保存到不同的服务器上,实现了memcached的分布式.
但是这种算法很难确保每台服务器得到较为平均的数据量,我们需要改变一下客户端的算法,简单来说,就是根据服务器的台数的余数进行分散

<%
"
test1".hashCode()%3
%>


根据key的java.lang.String.hashCode()取得散列值,再将值模服务器的台数得到余数值,我们再根据这个余数值来判定这个 key要存入哪一台服务器,当key的数量越来越大,对key的散列取模也会趋向平均,基本可以保证几台memcached服务器所存储的缓存量趋向平均
似乎很完美,余数计算的方法很简单,数据的分散性也很优秀,但也有其缺点,就是当需要添加或移除服务器时,缓存的重组代价是相当巨大的,添加或移除服务器时,余数就会发生变化,这样就无法取到与原来缓存时相同的服务器.
网上介绍的Consistent Hashing算法基本上可以解决这个问题,这里做个简单的说明,首先是求出memcached服务器节点的哈希值,并将其配置到0-2的32次方的圆 上,然后用同样的方法求出存储数据的键的哈希值,并映射到圆上.然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上.如果超过2的 32次方仍然找不到服务器,就会保存到第一台memcached服务器上


从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响



几种连接客户端的对比
目前java的memcached主要有Java-Memcached-Client,Xmemached,Spymemcached三种,这三个客户端的性能测试可以看
http://xmemcached.googlecode.com/svn/trunk/benchmark/benchmark.html


请求的资源为64Bytes,在低并发Java-Memcached-Client是占有一定的优势,但在并发数超过100以后,Java- Memcached-Client是呈现直线下跌,并发数达到300已经无法承受,Spymemcached和Xmemached表现相对稳定,特别是 Xmemached无论在低并发或高并发都保持优秀的性能表现



并发数固定为100时,在小文件的请求Java-Memcached-Client还是占有优势,当随着请求的size越来越大,三者趋向于同一点
如果你对memcached访问的负载不高,那么Java-Memcached-Client是一个不错的选择,如果你对memcached访问的负载要 求较高,推荐使用Xmemached,如果需要异步的批量处理,可以选择Spymemcached,如果你什么都不知道,那么建议使用 Xmemached,因为无论在何种情况,它都可以表现出较好的性能,虽然不是最好



监控memcached
推荐使用nagios或cactis进行监控,nagios没有配置过,cactis是需要下载一个脚本插件
这里推荐一个从网上淘来的php,只要把它放到你的机器中,当然你的机器要支持php环境,将此php放入你的网页访问网络就可以访问
下载
http://www.blogjava.net/Files/dongbule/cacti/memcache.rar
修改php以下几个选项

define('ADMIN_USERNAME','memcache');    // Admin Username
define('ADMIN_PASSWORD','password');    // Admin Password

$MEMCACHE_SERVERS[] = '192.168.1.100:11211'// add more as an array
#
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11211'; // add more as an array


监控的平台



理解memcached的删除机制
memcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期, 这种技术被称为lazy(惰性)expiration.因此,memcached不会在过期监视上耗费CPU时间
memcached会优先使用已超时的记录的空间,并使用LRU算法来分配空间,因此当memcached的内存空间不足,就从最近违背使用的记录中搜索,并将空间分配给新的记录
不过在某些情况下LRU机制会造成某些麻烦,如你并不想要淘汰已被缓存过的记录,可以在memcached启动时添加 -M 参数来禁止LRU,但这样在memcached的内存用尽时,memcached会返回错误,是否使用LRU,在于你的需求

分享到:
评论

相关推荐

    Memcached使用点滴总结分享.docx

    Memcached 使用点滴总结分享 Memcached 是一种高性能的缓存系统,可以用来存储数据,以减少数据库的查询次数和提高应用程序的性能。本文总结了作者对 Memcached 的使用经验和实践,包括封装 Memcached Java 客户端...

    Memcached使用点滴.docx

    Memcached 是一款广泛使用的分布式内存缓存系统,它能够有效地缓解数据库的压力,提高应用程序的性能。在本文中,我们将探讨 Memcached 的使用及其在服务访问控制中的应用。 首先,Memcached 的客户端库是其易用性...

    Memcached使用点滴

    通过对Memcached的深入了解和实践,作者不仅解决了服务访问控制的问题,还进一步揭示了Memcached的一些高级特性及其在实际项目中的应用场景。通过上述方法和策略的应用,不仅提高了服务的性能和稳定性,也为后续的...

    Memcached使用点滴 服务集成平台需要对服务有所监控,包括访问频率控制以及访问次数控制

    Memcached 在服务集成平台中的应用 Memcached 是一种高性能的分布式内存对象缓存系统,可以用来加速动态 Web 应用程序的开发过程。 Memcached 的主要特点是可以将数据存储在内存中,从而减少对数据库的访问次数,...

    java_memcached-release_2.5.1

    这里还是通过一些点滴的启示来介绍优化的一些心得,很多时候还是要根据具体情况来判断如何去具体实施,因此这里所说的仅仅是在一些场景下适用,并非放之四海皆准的教条。同时也希望看此文的各位同学,如果有更好的...

    ucenter home utf8英文版

    同时,为了提高性能,开发者还可以进行缓存配置,利用Memcached或Redis等缓存服务,减少数据库访问压力。 7. 扩展与定制: Ucenter Home提供丰富的API和模板机制,允许开发者进行二次开发,自定义界面风格,或者...

    Mblog微博系统

    "Mblog微博系统"是一款基于PHP开发的单用户微型博客软件,设计目标是提供一个轻量级、简洁且界面美观的平台,让用户能够方便地分享生活点滴、观点想法或者信息。这款系统深受那些喜欢简洁设计和高效互动的用户喜爱。...

    KingCat SNS

    这些功能使得用户能够创建个人档案,寻找志同道合的朋友,分享生活点滴,并参与各种社交活动。 "Program"这个文件名可能指的是该系统的程序代码或者安装包。在开发过程中,程序通常由前端和后端两部分组成。前端...

    social-network-app

    在当今数字化的世界里,这类应用已经成为人们日常生活的一部分,为用户提供了一个虚拟空间来交流思想、分享生活点滴和建立社区。 在开发一个社交网络应用时,其体系结构的设计至关重要,因为它决定了应用的性能、可...

    免费的cs freecs

    J2EE是一个用于开发和部署企业级应用的开放标准,它包括一系列的框架和服务,如Servlet、JSP(JavaServer Pages)、EJB(Enterprise JavaBeans)等,提供了服务器端应用程序的完整解决方案。开发者可以利用J2EE平台...

    Bug-e-Code_Blog:我的个性化博客

    这个系统很可能采用开源技术栈构建,旨在提供一个定制化、可自定义的个人在线空间,用于分享技术文章、个人见解或生活点滴。下面我们将详细探讨PHP在构建博客系统中的应用以及相关知识点。 PHP(Hypertext ...

    BS:个人博客系统

    通过它,个人可以展示自己的思考、技术分享、生活点滴,或者建立一个专业的技术博客,提升个人在线影响力。 在描述中提到的“BS:个人博客系统源码”,意味着该压缩包包含的是整个博客系统的原始代码。源码对于...

Global site tag (gtag.js) - Google Analytics