memcached精讲第一部
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了memcached精讲第一部相关的知识,希望对你有一定的参考价值。
1.Memcache是什么,有什么作用?
答:是一款开源的,高性能的纯内存缓存服务软件
Mem就是内存的意思,cache缓存的意思,d就是daemon的意思服务端守护进程。
Memcache整个项目的名字,Memcache服务分为客户端和服务端的两部分
client/server b/s
客户端软件:Memcache-2.25.tar.gz
服务端软件:Memcached-1.4.13.tar.gz(你大概要记住带有D的就是服务端)
Memcache项目诞生于2003年。
Memcache作用:
再启动Memcache时,会制定一个内存大小的参数,会被分配一个内存空间。我们读取数据库后的各类业务数据,放入MC缓存当中,下一次请求同样的数据的用户,直接去MC取数据就返回用户:
有什么好处?
(1),对用户来讲,用户访问网站更快了,体验更好了。
(2),数据库的压力降低了。当内存没有的时候就会请求数据库,第一次写入数据会写入数据库。
(3),提升了网站的并发访问。服务器数量变少。
缓存的软件对比:
expires Web上配置浏览器端缓存 静态的图片,JS,CSS,html。
Memcache 纯内存 用来缓存后端数据库的数据 博文、帖子、用户信息。
Memcachedb 内存加磁盘sina,Memcached+B(伯克利)DB。用来缓存后端数据库(博文、帖子、用户信息),的数据直接做数据库用(微博粉丝,统计),mysql补充。
Redis内存加磁盘,作用同Memcachedb。支持主从复制,它的数据类型(集合,哈希等类型)更丰富,作为Mysql的补充,redis。(可以当做数据库)
squid,nginx,varnish,ats Web缓存。放在Web的前端,内存或者squid是内存加磁盘。
静态图片,JS,CSS,HTML,视频。CDN就是利用这类软件做的分布式缓存。
期末架构:
2.描述Memcahed服务在企业集群架构的应用场景。
3.Memcached服务在不同企业业务应用场景中的工作流程。
4.Memcache服务分布式集群是如何实现?
5.Memcache服务特点以及工作原理
6.简述Memcache内存管理机制原理?
7.Memcached的删除原理与删除机制?
1.1.1Memcached服务在企业集群架构中的应用的角色
(1)作为数据库前端缓存应用
1.完整缓存(易)
例如:京东的商品分类,就可以事先放在内存里,然后在对外提供数据访问。这个被称之为预热
此时可以只读去缓存就能读到商品分类数据,无需读取数据库了,所以数据库的压力就降下来了。为什么商品分类可以事先先放在缓存里面呐?
因为,商品分类是由内部员工管理的,可以增加编辑后推送到Memcached内存里。
2.热点缓存(难)热点缓存一般是指由用户更新的商品美丽如淘宝的卖家,当卖家新增商品后,淘宝网的程序就会把商品写入数据库,然后读取写入的数据,把这部分数据,放入Memcached内存中,下次访问这个商品的请求直接从Memcached内存中取走了。这个方法用来缓存网站热点的数据,即Memcached中缓存经常被访问的数据。
特别提示:这个过程可以通过程序来实现,也可以在数据库上安装Memcache插件,直接由数据库出发更新内容到Memcached中。
错误的图:
图1由程序来进行控制读取数据的一般情况流程:
2.图二由程序进行控制数据流写数据的方案:
3.图三由软件来进行控制数据流读数据方案:
淘宝京东电商双11,秒杀的场景:
如果碰到双11、秒杀高并发的业务场景,要事先预热Memcached。
先把数据放入内存预热,然后在逐步动态更新。先读取缓存,如果缓存里面没有数据,再去读取数据库,然后把读取数据放入缓存。如果数据库里的数据更新,实时出发缓存更新,防止给用户过期的数据。
3、持久化存储系统
对于持久化存储系统,除了做内存缓存外,还可以做数据库的存储补充,例如可以替代一部分数据库的存储。投票,统计,关注等业务。nosql=not only sql
下面是常见持久化存储Key-value数据库的图:
4、MemcacheDB:它是新浪互动社区事业部在Memcache基础上。增加Berkeley DB储存层而开发的一筐支持高并发的持久存储系统。它的数据是可以持久化存储的。
4、减少数据库被大量访问的压力
这个是非常重要的,所有的网站动态数据都是保存在数据库当中,每次频繁的访问数据库,会导致数据库性能的急剧的下降,无法同时服务更多的用户,比如Mysql,那么,就可以让Memcache来分担数据库的压力。增加memcached服务的,这样就可以分担数据库的压力,增加memcached架构也无需改动真个网站架构,只需要排序让程序首先读取cache查询数据就好了,当然别忘了,更新数据时也要更新缓存memcahce。
(2)作为集群中的session会话共享存储
http://oldboy.blog.51cto.com/2561410/1331316
http://oldboy.blog.51cto.com/2561410/1323468
缺点:数据一致性问题很头疼,特别是大网站。
配置Memcache的在你的Web服务器上面的php模块的配置文件里面
一般的路径是/applocations/php/lib/php.ini文件里面找到session.save_handler = memcahce 和 session.save_path = "tcp://127.0.0.1:11211" 第一个的意思是指定session 的类型第二个指定的是memcache的服务器的地址的和端口是多少。
有关sesson和cookies概念及应用的介绍见:
Memcached服务应用中的工作流程
Memcached是一种内存缓存,在工作中经常用来缓存数据库中的数据,数据被缓存到实现分配的memcached管理内存中,可以通过API的方式存取内存中的缓存的这些数据,Memcached服务内存中缓存的数据就像一张巨大的HASH表,每条数据都是key-value的形式存储的。
Memcached通过缓存经常被读取数据库中的数据,当程序需要访问后端数据库获得数据时会优先访问Memcached内存缓存,如果缓存有数据就直接返回前段服务应用,如果没有数据(没有命中)再转发给后端数据库服务器,程序服务取到Memcached内存中没有的对应的数据后,除了返回给用户数据外,还会把数据内存中的进行缓存,等到下次被访问,从而大大的减轻数据库的压力米挑高真个网站架构的响应速度,提升用户的体验。
当程序更新,删除数据库中的已有的数据时,会同时发送请求通知Memcached已经缓存过的同一个ID内容的就数据失效,从而保证Memcache中的数据和数据库中的数据一致
如果在高并发的场合,除了通知Memcached过期的缓存失效外,还通过相关机制使得在用户访问新数据钱,通过程序预先把更新过得数据推送到Memcached中缓存起来这样可以减少数据库压力,提升memcached缓存的命中率。
图下方展示了Memcached缓存系统数据库的写作流程。
上图利用Memcached来尽情数据库压力的具体工作流程描述如下:
1)程序首先检查前端应用服务请求的数据是否在Memcached缓存中存在,如果存在直接把请求的数据返回,不在请求后端数据库。
2)如果请求的数据不在Memcached缓存中,请求将被转发去查询数据库服务,把从数据库中取得的数据返回给前端,同时把新取到的数据新缓存一份到Memcached缓存中。
3)当程序更新,删除数据库已经有的数据的同时,也会更新Memcached中的旧数据,从而保证Memcache中缓存的数据和数据库中的数据一致,这个一致是非常重要的。
4)当分配给Memcached内存空间用完之后,Memcached自身会使用LRU(Least Recent Used,最近最少使用)加到失效策略,失效的数据首先被替换掉,然后是最近未使用的数据被替换掉。
1.1.5Memcached服务在大型网站额应用
几乎所有网站当访问量增大的时候,在整个网站集群架构中最先出现的瓶颈的一定是数据库角色的服务器以及存储角色的服务器,在工作中我们是尽量把用户的请求往前推,当用户请求数据时,越是在靠近用户的一端把数据返回就越好。
千万级PV/IP规模高性能高并发网站架构:http://oldboy.blog.52cto.com/2561410/736710
那么,为了缓解数据库的高并发访问压力,我们可以在数据库层配置数据读写分离,读数据库做负载均衡,但是更有效更简单的策略是,部署Memcache服务作为一个缓存区域,把部分数据库的是信息保存在内存中,这样前端的服务能够迅速的读取到原本在数据库中才能读取到的数据。那么,最重要的就是如何通过memcached服务分担数据库系统的能力,由于单台Memcached的内存容量有限的,并且单台也是单点,因此,memcached也有负载均衡及分布式应用的场景。
【分布式应用1】
Memcahce支持分布式,我们在应用服务器程序上改造,就可以更好的支持。例如:可以根据key适当进行有规律的封装,比如以用户为主的网站来说,每个用户都有UserID那么可以按照固定的ID来进行提取和存取,比如1开头的用户保存在第一台Memcached服务器上,以2开头的用户数据保存在第二台Memcache服务器上,存取数据都先安装UserID来进行相应的转换和存取。
【分布式应用2】
在应用服务器上通过程序以URL_HASH,一致性哈希算法去访问Memcache服务所有Memcached服务器的地址池可以简单的配在每个程序的配置文件里。
【分布式应用3】
门户如百度,会通过一个中间件代理(透明)负责请求后端cache服务。
【分布式应用4】
可以通常见的LVS,haproxy做cache的负载均衡,和普通的web应用服务相比,这里的重点是调度算法,Cache一般会选择url_hash及一致性hash算法
1、完整缓存,如果十多台就直接负载均衡。特点所有缓存数据都一样。百度的memcached TB级别。一台机器的内存没那么大。就必须分布式。
2、热点缓存,分布式缓存。
分布式缓存集群小节:
1.所有MC服务器的内存缓存内容都是不一样的。这些服务器内容加起来可以接近数据库的容量。
2.通过在WEB客户端程序或者MC的负载均衡上应用HASH算法,让同一内容都分配到一个MC服务器。
3.普通的这种HASH算法对于节点宕机会带来大量的数据流动(失效),可能会引起雪崩效应。
4.一致性HASH算法可以让节点宕机对节点的数据流动(失效)降到最低。
1.1.6Memcache的特性:
Memcached作为高并发,高性能的缓存服务,具有如下特征:
C/S模式
Memcached是一套C/S模式架构软件,有C语言编写,总共2000多行代码。
协议简单:
Memcached的协议实现简单,使用的是基于文本行的协议,能通过telnet/nc直接操作Memcached服务存取数据。
异步I/O模型,使用libevent作为时间处理通知机制。
简单的说,lievent是一套利用C开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等时间处理功能封装成一个接口确保即使服务器端连接数增加也能发挥很好的性能。
Memcached就是利用这个库进行异步事件处理,关于这个库的更详细内容,有兴趣的读者可以查看文档。
key/value 键值数据类型
被缓存的数据以KEY/value键值的形式存在的
Oldboy01 --- 29
Oldboy02 --- 25
纯内存存取管理模式
Memcached有一套自己管理内存的方式,这套管理方式非常高效,及全部数据都存放于Memcached服务实现分配好的内存中,和系统内存一样,重启系统或者Memcached服务,Memcached内存中的数据及丢失。
如果希望重启后,数据依然能保留,那么就需要sina网开发的memcachedb持久性内存缓存系统,当然还有常见的NOSQL软件redis
NOSQL常见软件:
memcached*,memcachedb*,TokyoTyrant*MongoDB,Cassandra,redis,tair,couchDB
更多开源软件件:http://oldboy.blog.51cto.com/2561410/775056
当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU(最近最少使用的就删除掉)算法删除过期的数据,也可以对存储的数据设置过期时间,这样过期后数据自动被清除,服务本身不会监控过期,而是在访问的时候查看KEY的时间戳判断是否过期。
多个Memcached集群节点互不通信。
各个Memcached服务器之间互不通信,都是独立的存储数据,不共享任何信息。通过对客户端的设计支持海量缓存和大规模应用,让Memcached具有分布式功能。
memcached可以做成集群,可以单点,部署多台数据可以同步,并且配置memcached的还是在程序代码中配置比较好:
负载均衡一致性HASH
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.htmlworker_processes 1;
http {
upstream test {
consistent_hash $request_uri;
server 127.0.0.1:9001 id=1001 weight=3;
server 127.0.0.1:9002 id=1002 weight=10;
server 127.0.0.1:9003 id=1003 weight=20;
}
}
1.1.7Memcached软件工作原理
Memcached是一套C/S模式架构的软件,在服务器端启动服务守护进程,可以为memcached服务器指定监听的IP地址,端口号,并发访问连接数以及分配多少内存来处理客户端的请求的参数。
Memcached软件是有C语言来实现的,全部代码仅有2000多行,采用的是异步I/O模式,其实现方式是基于libevent时间的单进程,单线程的。使用libevent作为时间通知机制,多个服务器端可以协同工作,但这些服务器端之间是没有任何通信联系,每个服务器端只对自己的数据进行管理。应用程序端通过制定缓存服务器的IP地址和端口,就可以连接memcached服务互相通信。
需要被缓存的数据以key/value键值对的形式保存在服务器端预分配的内存区中,每个被缓存的数据都是唯一标示key,操作Memcached中的数据通过这个唯一标识的key进行。缓存到Memcached中的数据仅放置在Memcached服务预分配的内存中,而非存储在Memcached所在的磁盘上,因此存取速度非常快。由于Memcached服务自身没有对缓存的数据进行持久性存储设计,因此,在服务器端的memcached服务进程重启之后,存储在内存中的这些数据就会丢失。且当内存中缓存的数据容量达到启动时设定的内存值的是,就自动使用LRU算法删除过期缓存数据。
开发Memcached的初衷就是仅为内存缓存而设计的,因此并没有过多考虑数据的永久存储问题。因此,如果使用memcached作为缓存数据服务,要考虑数据丢失后带来的问题,例如:是否可以重新生成数据,还有,在高并发场合数据丢失会不会导致网站架构雪崩(不久前百度的架构师就讲解过此类的问题)。
企业场景如何正确重启Memcached集群服务?在前端控制入口访问量。然后,启动Memcached集群并进行数据预热,所有数据都预热完毕之后,在逐步的放开前段的流量。为了满足数据可以持久性的保留的需求,sina网基于memcached服务开发了一款noSQL软件,名字MemcachedDB,可以实现在缓存的基础上增加了持久缓存的特性。
Memcached支持各种语言编写的客户端API,包括shell,php,python,java,和C等。
如何正确关闭网站集群服务器?从前端往后端依次关闭。
如何正确开启网站集群服务器?从后端依次往前端开启,缓存服务器要预热。
工作原理:
1)C/S架构,2000多行代码,C语言编写。
2)基于libevent(c编写的程序库把epoll模型封装了一个接口,memcached通过这个来进行处理)库事件处理的,异步I/O模型。
3)数据以key/value键值对存在的。
4)纯内存访问,重启数据都丢失。
5)多个集群节点互不联系,(集群调度算法一致性HASH)
1.1.8Memcached内存管理机制深入剖析
在讲解Memcached内存管理机制前,先了解一下malloc。
malloc的全称就是memory allocation,中文叫做动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态分配内存。
早期的Memcached内存管理方式是通过malloc分配的内存,使用完后通过free来回收内存。这个方式容易产生内存碎片并降低操作系统对内存的管理效率。加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢,为了解决上述问题,Slab Allocator内存分配机制就诞生了。
现在Memcached利用Slab Allocation机制来分配和管理内存的。
Slab Allocation 内存分配机制原理是按照预先规定的大小,将分配给Memcached服务的内存预先分割成特定长度的内存块(chunk),再把尺寸相同的内存块(chunk)分成组(chunks slab class),这些内存块不会释放,可以重复利用。
Memcached服务器中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。当有内存存入时,Memcahed根据接收到的数据大小,选择最合适数据大小的slab(图2.2)分配一个能存下这个数据的最小内存块(chunk)。例如有100字节的一个数据,就会被分配存入下面112字节的内存块中,这样会有12字节被浪费掉,这部分空间不能被使用了,这也是Slab Allocator机制的一个缺点。
slab allocator还有重复使用已分配内存的作用。也就是说,分配到的内存不会释放,而是重复使用。
Slab Allocation的主要术语。
Page:分配给slab的内存空间,默认1MB。分配给slab之后根据slab的大小切分成chunk。
chunk:用于缓存数据的内存空间或者内存块,相当于磁盘的block,只不过磁盘的每一个都是相等的,而chunk只有同一个 slab class 内才是相等的。
slab class:特定的大小的多个chunk的集合或者组。一个Memcached包含多个Slabcalss,每个Slab class包含多个相同大小的chunk。
小结:
1.mc的早期内存管理机制为malloc(动态内存分配)。
2.malloc(动态内存分配)产生内存碎片,导致操作系统性能急剧下降。
3.Slab内存分配机制就产生了,可以解决内存碎片的问题。
4.Memcached服务的内存预先分割成特定长度的内存块(chunk),再把尺寸相同的内存块(chunk)分成组(chunks slab class),这些内存块不会释放,可以重复利用。chunk:用于缓存数据的内存空间或者内存块,相当于磁盘的block,只不过磁盘的每一个都是相等的,chunk只有同一个 slab class 内才是相等的。
5.slab class:特定的大小的多个chunk的集合或者组。一个Memcached包含多个Slabcalss,每个Slab class包含多个相同大小的chunk。
6.Slab机制也有缺点,例如:chunk空间也会浪费(通过调优因子以及大小接近的数据放入MC实例)。
1.1.9Memcached Slab Allocator 内存管理机制缺点
Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。这个问题就是,由于分配的特定长度的内存,因此无法有效利用分配的内存。例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(如下图)
避免浪费内存的办法是,预先计算出应用存入的数据大小,或把同一业务类型的数据存入一个Memcached服务器中,确保存入的数据大小相当匀称,这样就可以减少内存的浪费,还有一个办法是,再启动时指定“-f”参数,能在某种程度上控制内存组之间的大小差异。在应用中使用Memcached时,通常可以不重新设置这个参数,使用默认值1.25进行部署。如果想优化Memcached对内存的使用,可以考虑重新计算数据的语气平均长度,调整这个参数来获得合适的设置值。
1.1.10 使用Growth Factor对slab Allocator 内存管理机制调优
memcached再启动时指定Growth Factor因子(通过f选项),就可以在某种程度上控制slab之间的差异。默认值为1.25.但是,在该选项出现之前,这个因子曾经固定为2,称为“powers of 2”策略。让我们利用以前的设置,以verbose模式启动memcached试试看:
#memcached -f 2 vv
可见,从128字节的组开始,组的大小一次增大为原来的2倍。这样设置的问题slab之间的差别比较大,有些情况就相当浪费内存。因此,为尽量减少内存浪费前追加了growth factor这个选项
小结:
1.每个slab是大小一样的。
可见,组间差距比因子为2时小得多,更适合缓存几百字节的记录。从上面的结果来看,可能会觉得有些计算误差,这些误差是为了保持字节数的对齐而故意设置
将memcached引入产品,或是直接使用默认值进行部署时,最好重新计算一个的语言平均长度,调整growth factor一伙的最恰当的设置。内存是珍贵的资源,浪费太可惜了。
1.1.11Memcached的删除机制
前面已经介绍过了。Memcached不会释放已分配的内存空间(除非添加数据设定过期或者内存缓存满了),在数据过期后,客户端不能通过key取出它的值,其存储空间被重新利用。
memcached使用的是一种Lazy Expiration策略,自己不会监控存入的key/value对是否过期,而是在获取key值时查看记录的时间戳(sed key flag exptime bytes),检查key/value对空间是否过期。这种策略不会在过期检测上浪费CPU资源。
Memcached在分配空间时,有限使用过期的key/value对空间,当分配的内存空间已占满时,Memcached就会使用LRU算法来分配空间,删除最近最少使用的key/value对将其空间分配给新的key/value对。在某些情况下(完整缓存),如果不想使用LRU算法,那么可以通过“-M”参数来启动Memcached,这样,Memcached在内存耗尽时,会返回一个报错信息。
总结:
1.Memcached的删除机制主要是LRU算法加上item过期失效。
2.当内存空间满的时候,会根据LRU算法把最近最少使用的Item删除。
3.数据存入实惠设定一个过期时间,当数据过期不会被立即删除,而是当下一次访问这个数据时,删除该数据重新缓存。
4.如果不希望系统使用LRU算法清除数据,可以用使用-M参数。不会删除数据。
以上是关于memcached精讲第一部的主要内容,如果未能解决你的问题,请参考以下文章