分布式存储及应用系统架构分析文件更改摘要:修订记录日期修订说明修订人批准人2010-4-4创建龙兴平龙兴平(MSN:lxp8@sina.com)第2页共83页2010-7-16目录1Memcached1.1Memcached架构memcached是高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。龙兴平(MSN:lxp8@sina.com)第3页共83页2010-7-161.2Memcache实现分析理解1.2.1实现结构SpeedOfcourse,theprimarymotivationforcachingisspeed,soMemcachedisdesignedtobeasfastaspossible.TheinitialprototypeofMemcachedwaswritteninPerl.AlthoughIlovePerl,theprototypewaslaughablyslowandbloated.Perltradesoffmemoryusageforeverything,soalotofpreciousmemorywaswasted,andPerlcan'thandletonsofnetworkconnectionsatonce.ThecurrentversioniswritteninCasasingle-process,single-threaded,asynchronousI/O,event-basedd?mon.Forportabilityandspeed,weuselibevent(seetheon-lineResourcessection)foreventnotification.Theadvantageoflibeventisthatitpicksthebestavailablestrategyfordealingwithfiledescriptorsatruntime.Forexample,itchooseskqueueonBSDandepollonLinux2.6,whichareefficientwhendealingwiththousandsofconcurrentconnections.Onothersystems,libeventfallsbacktothetraditionalpollandselectmethods.InsideMemcached,allalgorithmsareO(1).Thatis,theruntimeofthealgorithmsandCPUusednevervarieswiththenumberofconcurrentclients,atleastwhenusingkqueueorepoll,orwiththesizeofthedataoranyotherfactor.Ofnote,Memcachedusesaslaballocatorformemoryallocation.EarlyversionsofMemcachedusedthemallocfromglibcandendedupfallingontheirfacesafteraboutaweek,eatingupalotofCPUspaceduetoaddressspacefragmentation.Aslaballocatorallocatesonlylargechunksofmemory,slicingthemupintolittlechunksforparticularclassesofitems,thenmaintaining龙兴平(MSN:lxp8@sina.com)第4页共83页2010-7-16freelistsforeachclasswheneveranobjectisfreed.SeetheBonwickpaperinResourcesformoredetails.Memcachedcurrentlygeneratesslabclassesforallpower-of-twosizesfrom64bytesto1MB,anditallocatesanobjectofthesmallestsizethatcanholdasubmitteditem.Asaresultofusingaslaballocator,wecanguaranteeperformanceoveranylengthoftime.Indeed,we'vehadproductionMemcachedserversupfor4–5monthsatatime,averaging7,000queries/second,withoutproblemsandmaintainingconsistentlylowCPUusage.AnotherkeyrequirementforMemcachedwasthatitbelockless.Allobjectsaremultiversionedinternallyandreferencecounted,sonoclientcanblockanyotherclient'sactions.IfoneclientisupdatinganobjectstoredinMemcachedwhileadozenothersaredownloadingit,evenwithoneclientonalossynetworkconnectiondroppinghalfitspackets,nobodyhastowaitforanybodyelse.Afinaloptimizationworthnotingisthattheprotocolallowsfetchingmultiplekeysatonce.Thisisusefulifyourapplicationknowsitneedstoloadafewhundredkeys.Insteadofretrievingthemallsequentially,whichwouldtakeafractionofasecondinnetworkround-trips,theapplicationcanfetchthemallinonerequest.Whennecessary,theclientlibrariesautomaticallysplitmulti-keyloadsfromtheapplicationintoseparateparallelmulti-keyloadstotheMemcachedinstances.Alternatively,applicationscanprovideexplicithashvalueswithkeystokeepgroupsofdataonthesameinstance.ThatalsosavestheclientlibraryabitofCPUtimebynotneedingtocalculatehashvalues.Ref:=0,2Memcached是danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能。关于这个东西,相信很多人都用过,本文意在通过对memcached的实现及代码分析,获得对这个出色的开源软件更深入的了解,并可以根据我们的需要对其进行更进一步的优化。末了将通过对BSM_Memcache扩展的分析,加深对memcached的使用方式理解。本文的部分内容可能需要比较好的数学基础作为辅助。◎Memcached是什么在阐述这个问题之前,我们首先要清楚它“不是什么”。很多人把它当作和SharedMemory那种形式的存储载体来使用,虽然memcached使用了同样的“Key=Value”方式组织数据,但是它和共享内存、APC等本地缓存有非常大的区别。Memcached是分布式的,也就是说它不是本地的。它基于网络连接(当然它也可以使用localhost)方式完成服务,本身它是一个独立于应用的程序或守护进程(Daemon方式)。Memcached使用libevent库实现网络连接服务,理论上可以处理无限多的连接,但是它和Apache不同,它更多的时候是面向稳定的持续连接的,所以它实际的并发能力是有限制的。在保守情况下memcached的最大同时连接数为200,这和Linux线程能力有关系,这个数值龙兴平(MSN:lxp8@sina.com)第5页共83页2010-7-16是可以调整的。关于libevent可以参考相关文档。Memcached内存使用方式也和APC不同。APC是基于共享内存和MMAP的,memcachd有自己的内存分配算法和管理方式,它和共享内存没有关系,也没有共享内存的限制,通常情况下,每个memcached进程可以管理2GB的内存空间,如果需要更多的空间,可以增加进程数。◎Memcached适合什么场合在很多时候,memcached都被滥用了,这当然少不了对它的抱怨。我经常在论坛上看见有人发贴,类似于“如何提高效率”,回复是“用memcached”,至于怎么用,用在哪里,用来干什么一句没有。memcached不是万能的,它也不是适用在所有场合。Memcached是“分布式”的内存对象缓存系统,那么就是说,那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源,即使是UNIX本地连接也一样。在我之前的测试数据中显示,memcached本地读写速度要比直接PHP内存数组慢几十倍,而APC、共享内存方式都和直接数组差不多。可见,如果只是本地级缓存,使用memcached是非常不划算的。Memcached在很多时候都是作为数据库前端cache使用的。因为它比数据库少了很多SQL解析、磁盘操作等开销,而且它是使用内存来管理数据的,所以它可以提供比直接读取数据库更好的性能,在大型系统中,访问同样的数据是很频繁的,memcached可以大大降低数据库压力,使系统执行效率提升。另外,memcached也经常作为服务器之间数据共享的存储媒介,例如在SSO系统中保存系统单点登陆状态的数据就可以保存在memcached中,被多个应用共享。需要注意的是,memcached使用内存管理数据,所以它是易失的,当服务器重启,或者memcached进程中止,数据便会丢失,所以memcached不能用来持久保存数据。很多人的错误理解,memcached的性能非常好,好到了内存和硬盘的对比程度,其实memcached使用内存并不会得到成百上千的读写速度提高,它的实际瓶颈在于网络连接,它和使用磁盘的数据库系统相比,好处在于它本身非常“轻”,因为没有过多的开销和直接的读写方式,它可以轻松应付非常大的数据交换量,所以经常会出现两条千兆网络带宽都满负荷了,memcached进程本身并不占用多少CPU资源的情况。◎Memcached的工作方式以下的部分中,读者最好能准备一份memcached的源代码。Memcached是传统的网络服务程序,如果启动的时候使用了-d参数,它会以守护进程的方式执行。创建守护进程由daemon.c完成,这个程序只有一个daemon函数,这个函数很简单(如无特殊说明,代码以1.2.1为准):CODE:#includefcntl.h#includestdlib.h龙兴平(MSN:lxp8@sina.com)第6页共83页2010-7-16#includeunistd.hintdaemon(nochdir,noclose)intnochdir,noclose;{intfd;switch(fork()){case-1:return(-1);case0: