Memcached介绍

2022-04-13 00:00:00 数据 客户端 分布式 缓存 服务器

Memcache介绍

首先说一下,Memcache是项目名称,Memcached是服务器端程序,有时候Memcache也是客户端名称。

Memcached是一款开源、高性能、分布式内存对象缓存系统,可应用各种需要缓存的场景,其主要目的是通过降低对Database的访问来加速web应用程序。它是一个基于内存的键值对存储,用于存储数据库调用、API调用或页面引用结果的直接数据,如字符串、对象等。

memcached是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款软件。现在已成为mixihatenaFacebookVoxLiveJournal等众多服务中提高Web应用扩展性的重要因素。

Memcache是一个高性能的不通信(各服务器间彼此无视:不在服务器间进行数据同步)分布式的内存对象缓存系统,O(1)的执行效率;通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。

Memcached是以守护程序方式运行于一个或多个服务器中,随时会接收客户端的连接和操作。memcached是一种无阻塞的socket通信方式服务,基于libevent(redhat系统中支持事件驱动I/O的库)库,由于无阻塞通信,对内存读写速度非常之快。Memcached是一个缓存服务器但本身无法决定缓存任何数据一半依赖于客户端(软件开发时是否支持memcached客户端库)一半依赖于服务器。Memcached是一个内存缓存服务器存储键值一一对应;它的下线是key默认大不能超过128bytes数据小48bytes1MB也就是一个slabs如果要存2M的值不能使用两个slabs因为两个slabs不是连续的无法再内存中存储故需要修改slabs的大小;多个keyvalue进行存储时即使这个slabs没有利用完那么也不会存放别的数据。

Memcached是一款开发工具,它既不是一个代码加速器,也不是数据库中间件。其设计哲学思想主要反映在如下方面:

1简单key/value存储

服务器不关心数据本身的意义及结构,只要是可序列化数据即可。存储项由键、过期时间、可选的标志及数据四个部分组成;

2协议简单

Memcached的服务器客户端通信并不使用复杂的XML等格式,而使用简单的基于文本行的协议。因此,通过telnet也能在memcached上保存数据、取得数据。如下:

3功能的实现一半依赖于客户端,一半基于服务器端

客户负责发送存储项至服务器端、从服务端获取数据以及无法连接至服务器时采用相应的动作;服务端负责接收、存储数据,并负责数据项的超时过期;

4内置内存存储方式

为了提高性能,memcached 中保存的数据都存储在memcached 内置的内存存储空间中。由于数据仅存在于内存中,因此重启 memcached、重启操作系统会导致全部数据消失。另外,内容容量达到指定值之后,就基于 LRU(Least Recently Used)算法自动删除不使用的缓存。memcached 本身是为缓存而设计的服务器,因此并没有过多考虑数据的性问题。

5互不通信的分布式

memcached尽管是分布式缓存服务器,但服务器端并没有分布式功能。各个 memcached 不会互相通信以共享信息。那么,怎样进行分布式呢?这完全取决于客户端的实现。

6基于libevent的事件处理

libevent是个程序库,它将 Linux  epollBSD 类操作系统的 kqueue 等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥 O(1)的性能。memcached 使用这个 libevent 库,因此能在 LinuxBSDSolaris 等操作系统上发挥其高性能。关于事件处理这里就不再详细介绍,可以参考 Dan Kegel  The C10K Problem


memcache缓存图解


这里先说一下,memcached虽然被称为“分布式缓存”,但是memcached本身完全不具备分布式的功能,memcached集群之间不会相互通信,所谓的“分布式”完全依赖于客户端程序的实现,就像上面的流程图一样。

基于上面这幅图,介绍一个Memcache读取写入的流程:

写入操作

1)应用程序输入需要写缓存的数据。

2)调用Memcache API将Key输入路由算法模块,路由算法根据Key和MemCache集群服务器列表得到一台服务器编号。

3)由服务器编号得到MemCache及其的IP地址和端口号。

4)MemCache API调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓存的写操作。

但执行写操作时,会将之前缓存的任何受此写入操作影响的结果设定为。此过程有助于防止缓存和数据库之间出现数据不一致性。

读取操作

读取操作和写入操作方式是一样,只要使用相同的路由算法和服务器列表,且应用程序查询的Key跟写入的Key是相同的,Memcache客户端总是会访问相同的服务器端去读取数据,只要服务器中还缓存着该数据,就能保证缓存命中。

这种Memcache集群的方式也是从分区容错性的方面考虑的,假如node2宕机了,那么node2上面存储的数据都不可用了,此时由于集群中node0和node1还存在,下一次请求node2中存储的Key值得时候,肯定是没有命中的。这时先从数据库中拿到要缓存的数据,然后路由算法模块根据Key值在node0和node1中选取一个节点,把对应的数据放进去,这样下一次就又可以走缓存了。这种集群的做法很好,但是缺点是成本比较大。


Memcached客户端调用接口库

许多语言都实现了连接memcached的客户端,Perlphp为主,仅memcached网站上列出来的语言就有:

●Perl- cache::memcached

●Php- memcached

●C/C++- libmemcached

●Python

●Ruby

●C#

●Lua

等等….


Memcached的特性和限制

先说一下:对于Memcached的特性和限制说明,可以在看完整个Memcached所有章节后来回来看,那个时候你才可能对以下说明更能理解。

1)Memcached中可以保存的item数据量是没有限制的,只要你的内存足够大。

2)Memcached单进程在32位机中大使用内存为2G,64位机则没有限制。

3)Key大为250个字节,超过该长度无法存储。

4)单个item大数据是1MB,超过1MB的数据不予存储。

5)Memcahced是不安全的,比如已知某个Memcache节点,可以直接telnet过去,并通过flush_all所有键值失效。

6)不能够遍历Memcache中素有的item,因为这个操作的速度相对缓慢且会阻塞其他的操作。

7)Memcached的高性能源自两个阶段哈希结构:阶段在客户端,通过hash算法根据key值算出一个节点;第二阶段在服务端,通过一个内部hash算法,查找真正的item并返回给客户端。

8)Memcached设置添加某一个key值的时候,传入expiry为0表示这个key值有效,但这个key值也会在30天之后失效,这个是Memcached源码定义的。

相关文章