• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

Memcached缓存数据库介绍

Memcached 彭东稳 9年前 (2016-01-21) 28767次浏览 已收录 0个评论

Memcache介绍

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

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

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

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

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

Memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe 传递给worker线程,进行读写IO, 网络层使用libevent封装的事件库,多线程模型可以发挥多核作用,但是引入了cache coherency和锁的问题,比如,Memcached最常用的stats 命令,实际Memcached所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。

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

memcache缓存图解

Memcached缓存数据库介绍

这里先说一下,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客户端API

许多语言都实现了连接memcached的客户端,以Perl和php为主,仅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源码定义的。


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!