MemCache设计理念便是小而强大,它大略的设计促进了快速支配、易于开拓并办理面对大规模的数据缓存的许多难题,而所开放的API使得MemCache能用于Java、C/C++/C#、Perl、Python、PHP、Ruby等大部分盛行的程序措辞。
memcache事情流程客户端要求数据检讨MemCached中是否有对应数据有的话直接返回,结束没有的话,去数据库里要求数据将数据写入MemCached,供下次要求时利用返回数据,结束(把稳:缓存到MemCached中的数据库数据,在更新数据库时要把稳同时更新MemCached)
memcache访问模型
MemCache虽然被称为\"大众分布式缓存\"大众,但是MemCache本身完备不具备分布式的功能,MemCache集群之间不会相互通信(与之形成比拟的,比如JBoss Cache,某台做事器有缓存数据更新时,会关照集群中其他机器更新缓存或打消缓存数据),所谓的\"大众分布式\"大众,完备依赖于客户端程序的实现,就像上面这张图的流程一样。
同时基于这张图,理一下MemCache一次写缓存的流程:
1、运用程序输入须要写缓存的数据
2、API将Key输入路由算法模块,路由算法根据Key和MemCache集群做事器列表得到一台做事器编号
3、由做事器编号得到MemCache及其的ip地址和端口号
4、API调用通信模块和指定编号的做事器通信,将数据写入该做事器,完成一次分布式缓存的写操作
读缓存和写缓存一样,只要利用相同的路由算法和做事器列表,只要运用程序查询的是相同的Key,MemCache客户端总是访问相同的客户端去读取数据,只要做事器中还缓存着该数据,就能担保缓存命中。
这种MemCache集群的办法也是从分区容错性的方面考虑的,如果Node2宕机了,那么Node2上面存储的数据都不可用了,此时由于集群中Node0和Node1还存在,下一次要求Node2中存储的Key值的时候,肯定是没有命中的,这时先从数据库中拿到要缓存的数据,然后路由算法模块根据Key值在Node0和Node1中选取一个节点,把对应的数据放进去,这样下一次就又可以走缓存了,这种集群的做法很好,但是缺陷是本钱比较大。
memcache实现事理这张图片里面涉及了slab_class、slab、page、chunk四个观点,它们之间的关系是:
1、MemCache将内存空间分为一组slab
2、每个slab下又有多少个page,每个page默认是1M,如果一个slab占用100M内存的话,那么这个slab下该当有100个page
3、每个page里面包含一组chunk,chunk是真正存放数据的地方,同一个slab里面的chunk的大小是固定的
4、有相同大小chunk的slab被组织在一起,称为slab_class
MemCache内存分配的办法称为allocator,slab的数量是有限的,几个、十几个或者几十个,这个和启动参数的配置干系。
MemCache中的value过来存放的地方是由value的大小决定的,value总是会被存放到与chunk大小最靠近的一个slab中,比如slab[1]的chunk大小为80字节、slab[2]的chunk大小为100字节、slab[3]的chunk大小为128字节(相邻slab内的chunk基本以1.25为比例进行增长,MemCache启动时可以用-f指定这个比例),那么过来一个88字节的value,这个value将被放到2号slab中。放slab的时候,首先slab要申请内存,申请内存因此page为单位的,以是在放入第一个数据的时候,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk数组,末了从这个chunk数组中选择一个用于存储数据。
如果这个slab中没有chunk可以分配了怎么办,如果MemCache启动没有追加-M(禁止LRU,这种情形下内存不足会报Out Of Memory缺点),那么MemCache会把这个slab中最近最少利用的chunk中的数据清理掉,然后放上最新的数据。
常见指令汇总篇幅有限,关于memcache方面的内容就总结到这了,后面会分享更多关于devops和DBA内容,感兴趣的朋友可以关注下~