Memcached 原理剖析.ppt_第1页
Memcached 原理剖析.ppt_第2页
Memcached 原理剖析.ppt_第3页
Memcached 原理剖析.ppt_第4页
Memcached 原理剖析.ppt_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Memcached入门,作者:,2009-01,2,Memcache是什么Memcache,ehcache的比较Memcache原理分析Memcache安装和基本配置Memcache的在大型网站中的使用策略Memcache的一些经验和技巧Memcache一致性算法(consistenthasing),TechTalk目录索引,3,Memcache是什么:,Memcache是国外社区网站LiveJournal的开发团队开发的高性能的分布式内存缓存服务器。一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。Memcache可以对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcache自管理这些HashTable.Memcache的官方网站:,4,Memcache,EhCache的比较,5,Memcache原理分析,Memcache工作方式?,6,Memcache原理分析,7,Memcache原理分析,自主的内存存储处理数据存储方式:SlabAllocation数据过期方式:LazyExpiration+LRU,8,Memcache原理分析,数据存储方式:SlabAllocationSlabAlloction构造图,SlabAllocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,以完全解决内存碎片问题。SlabAllocation的原理相当简单。将分配的内存分割成各种尺寸的块(chunk),并把尺寸相同的块分成组(chunk的集合),9,Memcache原理分析,数据存储方式:SlabAllocationSlabClasses分配图,Page:分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。Chunk:用于缓存记录的内存空间。SlabClass:特定大小的chunk的组。memcached根据收到的数据的大小,选择最适合数据大小的slab。memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。,10,Memcache原理分析:,数据存储方式:SlabAllocationSlabAlloction缺点,这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了。,11,Memcache原理分析:,数据过期方式LazyExpirationmemcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术被称为lazy(惰性)expiration。因此,memcached不会在过期监视上耗费CPU时间。LRUmemcached会优先使用已超时的记录的空间,但即使如此,也会发生追加新记录时空间不足的情况,此时就要使用名为LeastRecentlyUsed(LRU)机制来分配空间。顾名思义,这是删除“最近最少使用”的记录的机制。因此,当memcached的内存空间不足时(无法从slabclass获取到新的空间时),就从最近未被使用的记录中搜索,并将其空间分配给新的记录。从缓存的实用角度来看,该模型十分理想。,12,Memcache原理分析:,基于客户端的Memcached分布式,13,Memcache原理分析:,基于客户端的Memcached分布式,/按照Key值,获取一个服务器IDintgetServerId(char*key,intserverTotal)intc,hash=0;while(c=*key+)hash+=c;returnhash%serverTotal;/服务器列表node0=:11211node1=:11211node2=:11211/获取key是tokyo的节点ID(服务器ID)intid=getServerId(test,3);/得出的结果是1,那么对应的机器就是nodeid=node1,14,Memcache原理分析:,基于客户端的Memcached分布式写入操作读取操作,15,Memcache原理分析:,Memcache的理论参数计算方式常量REALTIME_MAXDELTA60*60*24*30最大30天的过期时间conn_init()中的freetotal(=200)最大同时连接数常量KEY_MAX_LENGTH250最大键长settings.factor(=1.25)factor将影响chunk的步进大小settings.maxconns(=1024)最大软连接settings.chunk_size(=48)一个保守估计的key+value长度,用来生成id1中的chunk长度(1.2)。id1的chunk长度等于这个数值加上item结构体的长度(32),即默认的80字节。常量POWER_SMALLEST1最小classid(1.2)常量POWER_LARGEST200最大classid(1.2),16,Memcache原理分析:,常量POWER_BLOCK1048576默认slab大小常量CHUNK_ALIGN_BYTES(sizeof(void*)保证chunk大小是这个数值的整数倍,防止越界(void*的长度在不同系统上不一样,在标准32位系统上是4)常量ITEM_UPDATE_INTERVAL60队列刷新间隔常量LARGEST_ID255最大item链表数(这个值不能比最大的classid小)变量hashpower(在1.1中是常量HASHPOWER)决定hashtable的大小根据上面介绍的内容及参数设定,可以计算出的一些结果:1、在memcached中可以保存的item个数是没有软件上限的,之前我的100万的说法是错误的。2、假设NewHash算法碰撞均匀,查找item的循环次数是item总数除以hashtable大小(由hashpower决定),是线性的。3、Memcached限制了可以接受的最大item是1MB,大于1MB的数据不予理会。4、Memcached的空间利用率和数据特性有很大的关系,又与DONT_PREALLOC_SLABS常量有关。在最差情况下,有198个slab会被浪费(所有item都集中在一个slab中,199个id全部分配满)。,17,Memcache原理分析:,Memcache的定长优化根据上面几节的描述,多少对memcached有了一个比较深入的认识。在深入认识的基础上才好对它进行优化。Memcached本身是为变长数据设计的,根据数据特性,可以说它是“面向大众”的设计,但是很多时候,我们的数据并不是这样的“普遍”,典型的情况中,一种是非均匀分布,即数据长度集中在几个区域内(如保存用户Session);另一种更极端的状态是等长数据(如定长键值,定长数据,多见于访问、在线统计或执行锁)。这里主要研究一下定长数据的优化方案(1.2),集中分布的变长数据仅供参考,实现起来也很容易。解决定长数据,首先需要解决的是slab的分配问题,第一个需要确认的是我们不需要那么多不同chunk长度的slab,为了最大限度地利用资源,最好chunk和item等长,所以首先要计算item长度。在之前已经有了计算item长度的算法,需要注意的是,除了字符串长度外,还要加上item结构的长度32字节。假设我们已经计算出需要保存200字节的等长数据。接下来是要修改slab的classid和chunk长度的关系。在原始版本中,chunk长度和classid是有对应关系的,现在如果把所有的chunk都定为200个字节,那么这个关系就不存在了,我们需要重新确定这二者的关系。一种方法是,整个存储结构只使用一个固定的id,即只使用199个槽中的1个,在这种条件下,就一定,18,Memcache原理分析:,要定义DONT_PREALLOC_SLABS来避免另外的预分配浪费。另一种方法是建立一个hash关系,来从item确定classid,不能使用长度来做键,可以使用key的NewHash结果等不定数据,或者直接根据key来做hash(定长数据的key也一定等长)。这里简单起见,选择第一种方法,这种方法的不足之处在于只使用一个id,在数据量非常大的情况下,slab链会很长(因为所有数据都挤在一条链上了),遍历起来的代价比较高。前面介绍了三种空间冗余,设置chunk长度等于item长度,解决了第一种空间浪费问题,不预申请空间解决了第二种空间浪费问题,那么对于第一种问题(slab内剩余)如何解决呢,这就需要修改POWER_BLOCK常量,使得每一个slab大小正好等于chunk长度的整数倍,这样一个slab就可以正好划分成n个chunk。这个数值应该比较接近1MB,过大的话同样会造成冗余,过小的话会造成次数过多的alloc,根据chunk长度为200,选择1000000作为POWER_BLOCK的值,这样一个slab就是100万字节,不是1048576。三个冗余问题都解决了,空间利用率会大大提升。修改slabs_clsid函数,让它直接返回一个定值(比如1)unsignedintslabs_clsid(size_tsize)return1;修改slabs_init函数,去掉循环创建所有classid属性的部分,直接添加slabclass1:CODE:slabclass1.size=200;/每chunk200字节slabclass1.perslab=5000;/1000000/200,19,Memcache安装、配置和使用:,Memcache安装Memcache配置Memcache结合java客户端的使用,20,Memcache安装和使用:,Memcachewindows安装,1.下载Memcache的window稳定版,解压到某个盘下面。2.Cmd找到解压目录,输入memcached.exedinsatll安装为windows服务.(如果是win7,要以administrator方式启动cmd).3.再输入memcached.exedstart启动。,21,Memcached安装和使用:,Memcachedlinux安装,安装步骤:先安装libevent再安装Memcached主程序源码下载:(最新版)libevent官网:/provos/libevent/libevent下载:/provos/libevent-1.4.9-stable.tar.gzMemcached官网:,22,Memcached安装和使用:,Memcached安装,安装libevent#tarzxvflibevent-1.4.9-stable.tar.gz#cdlibevent-1.4.9-stable#./configure-prefix=/usr#make#makeinstall安装Memcached#tarzxvfmemcached-1.2.6.tar.gz#cdmemcached-1.2.6#./configure-prefix=/usr/local#make#makeinstall,23,Memcached安装和使用:,Memcached运行,试运行Memcached#/usr/local/bin/memcached-uhualiangxie,24,Memcached安装和使用:,Memcached运行,查看Memcached帮助信息#/usr/local/bin/memcached-h,25,Memcached安装和使用:,Memcached运行,关注基本选项-p监听的TCP端口(缺省:11211)-d以守护进程方式运行Memcached-u运行Memcached的账户,非root用户-m最大的内存使用,单位是MB,缺省是64MB-c软连接数量,缺省是1024-v输出警告和错误信息-vv打印客户端的请求和返回信息-h打印帮助信息-i打印memcached和libevent的版权信息运行Memcached目标:使用11211端口、hualiangxie用户、最大占用512M内存、1024个软连接,输出客户端请求,以守护进程方式运行#/usr/local/bin/memcached-p11211-d-uhualiangxie-m512-c1024-vvv,26,Memcached安装和使用:,Memcached运行,检查是否正常启动#paauxxww|grepmemcached100144020.00.02296900pts/0S+19:240:00/usr/local/bin/memcached-uhualiangxieroot45470.00.01892668pts/3S+19:420:00grepmemcached#telnetlocalhost11211Trying.Connectedtolocalhost.Escapecharacteris.statsSTATpid4402STATuptime1032STATtime1231155683STATversion1.2.6STATpointer_size32.END,27,28,stats命令memcache的stats命令包括:1.stats2.statsreset清空统计信息3.statsmalloc显示内存分配数据4.statsmaps动态库的映射地址5.statssizes6.statsslabs7.statsitems8.statscachedumpslab_idlimit_num示某个slab中的前limit_num个key列表9.statsdetailon|off|dump设置或显示详细操作信息,29,Memcached安装和使用:,Memcached命令,数据存取setkey101803abcSTOREDaddkey101803xyzNOT_STOREDgetkey1VALUEkey103abcENDreplacekey101803xyzSTOREDgetkey1VALUEkey103xyzENDdeletekey1DELETED,数字加减setkey2018041234STOREDincrkey231237getkey2VALUEkey2041237ENDdecrkey211236getkey2VALUEkey2041236END,30,memcached的客户端使用TCP链接与服务器通讯。(UDP接口也同样有效)一个运行中的memcached服务器监视一些(可设置)端口。客户端连接这些端口,发送命令到服务器,读取回应,最后关闭连接。结束会话不需要发送任何命令。当不再需memcached服务时,要客户端可以在任何时候关闭连接。需要注意的是,鼓励客户端缓存这些连接,而不是每次需要存取数据时都重新打开连接。这是因为memcached被特意设计成及时开启很多连接也能够高效的工作(数百个,上千个如果需要的话)。缓存这些连接,可以消除建立连接所带来的开销(/*/相对而言,在服务器端建立一个新连接的准备工作所带来的开销,可以忽略不计。)。在memcache协议中发送的数据分两种:文本行和自由数据。文本行被用于来自客户端的命令和服务器的回应。自由数据用于客户端从服务器端存取数据时。同样服务器会以字节流的方式传回自由数据。/*/服务器不用关心自由数据的字节顺序。自由数据的特征没有任何限制;但是通过前文提到的文本行,这项数据的接受者(服务器或客户端),便能够精确地获知所发送的数据库的长度。文本行固定以“rn”(回车符紧跟一个换行符)结束。自由数据也是同样会以“rn”结束,但是r(回车符)、n(换行符),以及任何其他8位字符,均可出现在数据中。因此,当客户端从服务器取回数据时,必须使用数据区块的长度来确定数据区块的结束位置,而不要依据数据区块末尾的“rn”,即使它们固定存在于此,Memcached安装和使用:,Memcached基本协议,31,Memcached安装和使用:,Memcached和java结合使用,下载memcachedjavaclient:解压后将java_memcached-release_2.0.1.jarjar包添加到工程的classpath中,/*Memcache服务器默认端口是11211*/Stringservers=:11211;SockIOPoolpool=SockIOPool.getInstance();pool.setServers(servers);pool.setFailover(true);pool.setInitConn(10);pool.setMinConn(5);pool.setMaxConn(250);pool.setMaintSleep(30);pool.setNagle(false);pool.setSocketTO(3000);pool.setAliveCheck(true);pool.initialize();,MemCachedClientmemCachedClient=newMemCachedClient();for(inti=0;i10;i+)/*将对象加入到memcached缓存*/booleansuccess=memCachedClient.set(+i,Hello!);/*从memcached缓存中按key值取对象*/Stringresult=(String)memCachedClient.get(+i);System.out.println(String.format(set(%d):%s,i,success);System.out.println(String.format(get(%d):%s,i,result);,32,Memcache三种java客户端的比较Memcacheclientforjava:较早推出的memcachejava客户端API,应用广泛,运行比较稳定。spymemcached:Asimple,asynchronous,single-threadedmemcachedclientwritteninjava.支持异步,单线程的memcached客户端,用到了java1.5版本的concurrent和nio,存取速度会高于前者,但是稳定性不好,测试中常报timeOut等相关异常Xmemcached是基于javanio实现的高性能可扩展的memcached客户端。实际上是基于我实现的一个nio框架,Memcached安装和使用:,33,Memcache在大型网站中的使用策略:,Memcache在大型网站中的部署策略基于memcached的slab和dump的内存管理方式,它产生的内存碎片比较少,不需要OS去做繁杂的内存回收,所以它对CPU的占用率那是相当的低。所以建议将它跟占用CPU较高的WEB服务器一起使用来节省成本。当然如果你有大量的廉价PC,那用来专门做memcached服务器也不错。由于32位操作系统中,每个进程最多只能使用2GB内存,所以如果你有大内存的话,可以以daemon的方式启动两个以上的memcached服务,或者干脆用64位的CPU和OS。,34,Memcache缓存使用策略:,memcached主要的作用是为减轻大访问量对数据库的冲击,所以一般的逻辑是首先从memcached中读取数据,如果没有就从数据库中读取数据写入到memcache中,等下一次读取的时候就可以从memcached中读取了。但在项目中的具体应用策略(也就是哪些数据应该缓存?怎么样缓存?过期策略?)就是个问题了。它的一个总原则是将经常需要从数据库读取的数据缓存在memcached中。这些数据也分为几类:一、经常被读取并且实时性要求不强可以等到自动过期的数据。例如网站首页最新文章列表、某某排行等数据。也就是虽然新数据产生了,但对用户体验不会产生任何影响的场景。这类数据就使用典型的缓存策略,设置一过合理的过期时间,当数据过期以后再从数据库中读取。当然你得制定一个缓存清除策略,便于编辑或者其它人员能马上看到效果。二、经常被读取并且实时性要求强的数据。比如用户的好友列表,用户文章列表,用户阅读记录等。这类数据首先被载入到memcached中,当发生更改(添加、修改、删除)时就清除缓存。在缓存的时候,我将查询的SQL语句md5()得到它的hash值作为key,结果数组作为值写入memcached,并且将该SQL涉及的table_name以及hash值配对存入memcached中。当更改了这个表时,我就将与此表相配对的key的缓存全部删除。,35,Memcache缓存使用策略:,三、统计类缓存,比如文章浏览数、网站PV等此类缓存是将在数据库的中来累加的数据放在memcached来累加。获取也通过memcached来获取。但这样就产生了一个问题,如果memcached服务器down掉的话这些数据就有可能丢失,所以一般使用memcached的永固性存储,这方面我们新浪使用memcachedb。四、活跃用户的基本信息或者某篇热门文章。此类数据的一个特点就是数据都是一行,也就是一个一维数组,当数据被update时(比如修改昵称、文章的评论数),在更改数据库数据的同时,使用Memcache:replace替换掉缓存里的数据。这样就有效了避免了再次查询数据库。五、session数据使用memcached来存储session的效率是最高的。memcached本身也是非常稳定的,不太用担心它会突然down掉引起session数据的丢失,即使丢失就重新登录了,也没啥。见多服务器session共享之memcache共享,36,一些经验和技巧:,Memcached一些特性和限制,在Memcached中可以保存的item数据量是没有限制的,只有内存足够Memcached单进程最大使用内存为2G,要使用更多内存,可以分多个端口开启多个Memcached进程最大30天的数据过期时间,设置为永久的也会在这个时间过期,常量REALTIME_MAXDELTA60*60*24*30控制最大键长为250字节,大于该长度无法存储,常量KEY_MAX_LENGTH250控制,客户端可以加上自己的前缀,所以最大长度是可以超过50的。单个item最大数据是1MB,超过1MB数据不予存储,常量POWER_BLOCK1048576进行控制,它是默认的slab大小最大同时连接数是200,通过conn_init()中的freetotal进行控制,最大软连接数是1024,通过settings.maxconns=1024进行控制,这跟操作系统有关,linux好像最大就是200。跟空间占用相关的参数:settings.factor=1.25,settings.chunk_size=48,影响slab的数据占用和步进方式,37,一些经验和技巧:,查看Memcached内部工作状态,访问Memcached:telnet主机名端口号查看总状态:stats查看某项状态:statscurr_connections,禁止LRU,有些情况下LRU机制反倒会造成麻烦。memcached启动时通过“-M”参数可以禁止LRU,如下所示:$memcached-M-m1024启动时必须注意的是,小写的“-m”选项是用来指定最大内存大小的。不指定具体数值则使用默认值64MB。指定“-M”参数启动后,内存用尽时memcached会返回错误。话说回来,memcached毕竟不是存储器,而是缓存,所以推荐使用LRU。,38,一些经验和技巧:,Memcached使用线程模式工作,在安装的时候必须打开:./configure-enable-threads安装完之后,启动的时候看看帮助信息有没有这条:-tnumberofthreadstouse,default4如果存在该选项,说明已经支持了线程,就可以在启动的时候使用-t选项来启动多线程然后启动的时候必须加上你需要支持的线程数量:/usr/local/memcache/bin/memcached-t1024,39,一些经验和技巧:,调优Slab和内存分配1,memcached在启动时指定GrowthFactor因子(通过-f选项),就可以在某种程度上控制slab之间的差异。默认值为1.25。但是,在该选项出现之前,这个因子曾经固定为2,称为“powersof2”策略。让我们用以前的设置,以verbose模式启动memcached试试看:$memcached-f2-vvslabclass1:chunksize128perslab8192slabclass2:chunksize256perslab4096slabclass3:chunksize512perslab2048slabclass4:chunksize1024perslab1024slabclass5:chunksize2048perslab512slabclass6:chunksize4096perslab256slabclass7:ch

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论