深入了解Memcache(原理、机制详细介绍)

        Web应用程序都需要与数据打交道,它要能够处理数据:既要存储一个用户提交的数据,又要检索要显示的数据,这是一个Web应用程序的主要功能。数据是关系到可伸缩性方面最重要的议题,它决定了应用程序能够达到多快的速度和多高的效率。我们知道MySQL是一个关系型的数据库系统,组织数据并存储在MySQL中,而且它也是Web应用程序最主要的数据源。数据库是持久的数据存储,其中存储着我们所有的数据,而且Web应用程序也可以使用数据库中的数据,但是,要从一个数据库中检索数据确实需要付出一些代价,这取决于所执行的数据库查询的类型及其后续检索的结果集。

        为了让应用程序能够正常运行,我们经常需要从数据库中检索各种类型的数据,包括频繁变化的数据,如用户或者会话数据;以及不经常变化的数据,如实际的页面内容。为了得到这些数据必须访问数据库,这样将严重影响性能,从而也成为需要考虑的主要问题所在。这就是不要总是去访问数据库来获取所需的数据,而是使用缓存的原因。这正是memcached要解决的问题。

        memcached是一个高性能、分布式的内存对象缓存系统,它实际上就是一个简单的内存服务器,能够为应用程序存储数据提供一个缓存层,从而减轻数据库的负担。存储在memcached中的数据并不持久,这意味着当memcached的服务器关机或者重新启动时,它的内容就消失了,而且它没有故障转移或者认证,因此完全由应用程序使用memcached来实现数据的管理和不断更新。

        memcached有一个称为最近最少使用(Least Recently Used LRU)的缓存的结构,从而当memcached的存储空间满时,最早存储和刚被访问过的数据将会被更新的内容替换。另外,memcached对于存储的数据还提供到期的超时设定,从而可以把数据存储设置为到将来某个时间到期,也可以什么也不设置。当memcached达到它的存储容量时,将会先替换到期的数据,然后替换刚被使用过的数据。

        memcached可以运行在任何配置类型中:一台或者多台服务器上,或者甚至在同一台服务器上运行多个实例。memcached的服务器只提供一个存储结构,在这个存储结构中,数据按照键值存储,而检索功能则通过使用一个散列查找表来实现。从真正意义上把它们全部粘连在一起的工作是在memcached的客户端实现的,在那里把一个散列的键值引用到正在被存储或者检索的数据上。它使用一种特殊的散列算法来决定某一个或者多个键的请求应该被发送到哪几台服务器中。一旦客户端知道某一特定条目请求的是哪台服务器,它就会以并行的方式把请求发送到相应的服务器上。然后每台服务器使用它自己的散列键查找表来检索存储条目,随后把结果发送回客户端。接着客户端把这些结果聚集在一起以供应用程序使用。

        由于memcached使用内存而不是磁盘来存储数据,因而它存储与检索数据的速度是特别快捷的(本站的http://www.tonitech.com/?p=263一文有详细讲解这一原理)。它对CPU的要求也不太高,在同一台运行Apache Web服务的服务器上也可以运行memcached,或者在有空闲内存可用的任何服务器上也能运行memcached。

        对于memcached,一种普通的体系架构设置是拥有许多简单配置的服务器,而每台服务器的唯一目的就是提供内存。因为,相对于数据库对CPU能力的需求更大而言,memcached却是对于内存容量需求更大,所以,在针对服务器的硬件投入方面,更容易满足memcached的要求。这样,就可以使用多台较低端的服务器来为应用程序提供一个分布式内存缓存层,从而在可伸缩性方面更容易实现,费用也不太昂贵。

        在memcached出现之前,开发人员想避免通过访问数据库来获取数据,曾经使用过各种模式来缓存数据。其中有一种方法是在Web进程中缓存数据(因为mod-perl是持久的)。这种方法的一个致命问题是,每个子进程最后都拥有一份其他进程己经缓存的数据副本,从而导致重复数据填充在各个线程及其子线程中。无论如何,最佳的缓存方法当然是使用内存,而不是磁盘。

        随着技术的发展,出现了memcached,当初,Brad Fitzpatrick开发的memcached只是用于Livej ournal.com网站,他想要有一个比那些当时已经存在的方案更好的缓存解决方案。Livejournal是一个社交网站,这个网站每天有成千上万的用户和动态页面流量。原先成千上万的页面流量的所有这些数据都是通过访问数据库来实现的,而通过使用memcached现在只需要一个轻量级的缓存就可以获取数据了,从而减轻了数据库的负担,可以说数据库几乎没有任何负担。

Linux中PHP的Memcache扩展安装

  最开始我先说一句,以下很多的安装路径视每台机器的情况而定,文中的路径是我电脑的路径,大家如果跟我的不一样可以使用find来查找路径。

PHP的Memcache扩展安装分为三个步骤:

第一个步骤是:安装libevent

第二个步骤是:安装Memcached

第三个步骤是:安装PHP的Memcache模块

 

下载软件

所需软件(去以下网址中下载最新版本)

libevent-2.0.19-stable.tar.gz (http://libevent.org/)

memcache-3.0.6.tgz (http://pecl.php.net/package/memcache)

memcached-1.4.13.tar.gz (http://www.danga.com/memcached/)

将文件上传到服务器中,我存放的位置是/usr/local/src/

 

安装libevent

libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。因此很多的服务器可能已经安装了libevent,所以先测试libevent是否已经安装:

# ls -al /usr/lib | grep libevent

 

lrwxrwxrwx.   1 root root       21 7?. 23 01:04 libevent-1.4.so.2 -> libevent-1.4.so.2.1.3

-rwxr-xr-x.   1 root root   108948 6?. 22 19:55 libevent-1.4.so.2.1.3

-rw-r–r–.   1 root root   133014 6?. 22 19:55 libevent.a

lrwxrwxrwx.   1 root root       26 7?. 23 01:04 libevent_core-1.4.so.2 -> libevent_core-1.4.so.2.1.3

-rwxr-xr-x.   1 root root    37080 6?. 22 19:55 libevent_core-1.4.so.2.1.3

-rw-r–r–.   1 root root    47248 6?. 22 19:55 libevent_core.a

lrwxrwxrwx.   1 root root       26 7?. 23 01:04 libevent_core.so -> libevent_core-1.4.so.2.1.3

lrwxrwxrwx.   1 root root       27 7?. 23 01:04 libevent_extra-1.4.so.2 -> libevent_extra-1.4.so.2.1.3

-rwxr-xr-x.   1 root root    84228 6?. 22 19:55 libevent_extra-1.4.so.2.1.3

-rw-r–r–.   1 root root   103130 6?. 22 19:55 libevent_extra.a

lrwxrwxrwx.   1 root root       27 7?. 23 01:04 libevent_extra.so -> libevent_extra-1.4.so.2.1.3

lrwxrwxrwx.   1 root root       21 7?. 23 01:04 libevent.so -> libevent-1.4.so.2.1.3

 

如果没有以上的内容,那么你就要安装libevent了,先解压缩libevent-2.0.19-stable.tar.gz,再编译安装:

# cd /usr/local/src

# tar zxvf libevent-2.0.19-stable.tar.gz

# cd libevent-2.0.19-stable

# ./configure –prefix=/usr/local/libevent

# make && make install

安装好可以再用上面的方式检查一下。

 

安装memcached

解压缩 memcached-1.4.13.tar.gz, 编译安装

# cd /usr/local/src

# tar zxvf memcached-1.4.13.tar.gz

# cd cd memcached-1.4.13

# ./configure –prefix=/usr/local/memchached –with-libevent=/usr/local/libevent

# make && make install

 

启动memcached

# /usr/local/memchached/bin/memcached -d start -m 128 -p 11211 -u root

附:

以下是memcache启动、关闭参数:

-p 指定端口号(默认11211)

-m 指定最大使用内存大小(默认64MB)

-t 线程数(默认4)

-l 连接的IP地址, 默认是本机

-d start 启动memcached服务

-d restart 重启memcached服务

-d stop|shutdown 关闭正在运行的memcached服务

-m 最大内存使用,单位MB。默认64MB

-M 内存耗尽时返回错误,而不是删除项

-c 最大同时连接数,默认是1024

-f 块大小增长因子,默认是1.25

-n 最小分配空间,key+value+flags默认是48

值得注意的是重启memcache:

先找到memcache的pid:

# ps -ef|grep memcache

再kill掉进程,再执行启动相关参数的memcache,可以重新设置memcache的占用的内存。

 

安装php的memcache模块

# cd /usr/local/src

# tar zxvf memcache-3.0.6.tgz# cd memcache-3.0.6# /usr/local/php/bin/phpize# ./configure –enable-memcache –with-php-config=/usr/local/php/bin/php-config –with-zlib-dir# make && make install

安装完后会有类似这样的提示:

Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/

把这个路径记住,然后修改php.ini

添加一行

extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20090626/memcache.so

这时候就大功告成了!

 

检查memcache是否正常工作

部署好Memcached之后,需要对Memcached的使用情况进行跟踪:监控Memcached的状态信息、内存使用情况、hit/miss的值。通过对Memcached的监控不仅能立刻了解Memcached出现问题,还能够利用状态信息来分析业务数据的增长并为未来的容量规划提供依据。本文推荐使用memcache.php作为memcache监控来检查memcache是否正常工作以及跟踪使用情况:

到以下这个网址下载这个工具:

http://book.51cto.com/art/201202/314917.htm

将这个文件放到localhost下,并修改以下这部分的内容:

define(‘ADMIN_USERNAME’,’memcache’);  // Admin Username

define(‘ADMIN_PASSWORD’,’password’);   // Admin Password

define(‘DATE_FORMAT’,’Y/m/d H:i:s’);

define(‘GRAPH_SIZE’,200);

define(‘MAX_ITEM_DUMP’,50);

 

$MEMCACHE_SERVERS[] = ‘mymemcache-server1:11211’; // add more as an array

$MEMCACHE_SERVERS[] = ‘mymemcache-server2:11211’; // add more as an array

 

改成:

define(‘ADMIN_USERNAME’,’admin’);       // 我的管理用户名:admin,你可以随便设置

define(‘ADMIN_PASSWORD’,’123456′);      // 我的管理员密码:123456,你可以随便设置

define(‘DATE_FORMAT’,’Y/m/d H:i:s’);

define(‘GRAPH_SIZE’,200);

define(‘MAX_ITEM_DUMP’,50);

 

$MEMCACHE_SERVERS[] = ‘localhost:11211’; // 将前面的mymemcache-server1改成localhost

$MEMCACHE_SERVERS[] = ‘mymemcache-server2:11211’; // 这一行可以删除掉

 

最后打开http//:localhost/memcache.php,查看是否有下图的内容:

 

 

 

 

 

如果没有这内容,重启一下php或者服务器试试,重启之后一般都可以解决了。

机械硬盘、固态硬盘、内存虚拟硬盘——Memcache介绍(Tony原创)

近几年来,计算机的CPU、内存和显卡等主要配件的性能都提升得很快,而与之相对应的磁盘系统性能正越来越严重地成为整个电脑系统性能提升的瓶颈。

首先,我们看看机械硬盘、固态硬盘和内存虚拟硬盘的读写速度比较:

1.机械硬盘测试

机械硬盘的读写速度

测试使用的机械硬盘属性如下:

产品西数 WDC WD5000AAKX-001CA0 (蓝盘)

大小500 GB

转速7200 /

缓存16 MB

硬盘已使用共 117 次,累计 571 小时

固件15.01H15

接口SATA III

数据传输率600 MB/

特征S.M.A.R.T,  48-bit LBA,  NCQ

从测试的结果可以看出该机械硬盘的最快读写速度大概在110~120MB/秒左右。

2.固态硬盘测试

固态硬盘的读写速度

固态硬盘最大的特点就是读写速度快。采用闪存作为存储介质,读取速度相对机械硬盘更快。固态硬盘不用磁头,寻道时间几乎为0,持续写入的速度非常惊人。 

固态硬盘使用的是DELL XPS13D-2701 SSD固态硬盘。

可以看出固态硬盘的最快读写速度大概在300~500MB/秒左右。

3.内存虚拟硬盘测试

内存虚拟硬盘的读写速度

内存虚拟硬盘(ramdisk)是指通过软件技术,将物理内存进行分割,将一部分内存通过虚拟技术转变为硬盘以较大幅度提升计算机数据读取速度和保护硬盘。

测试使用的内存属性如下:

金士顿 DDR3 1333MHz 2GB

制造日期2011 年 07 

型号7F98 99P5471-002.A01LF

序列号:35D2268E

可以看出内存虚拟硬盘的最快读写速度在3000MB/秒以上。

4.Memcache介绍

从以上测试的结果可以看出,现在内存的读写速度比固态硬盘的读写速度快三四十倍,比如今堪称神速的固态硬盘要快10倍。现在我们很多的网站都会将数据存储在数据库中,虽然数据库有很多的优点,但数据库也有致命的缺点,例如:数据库的并发量是有限制的,如果有很多的用户访问,服务器就会瘫痪;数据库是存储在硬盘中的,数据的读写速度太慢会造成用户体验的降低。如果一个网站没有解决这两个问题,很可能造成大量的用户流失,我曾经的http://www.xiahuimingcheng.com就是因为这样的问题造成了很多用户不喜欢访问。

现在,我给大家介绍一个能减轻数据库负担的内存对象缓存系统——Memcache,以下是百度百科的解释:Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。简单的说就是将数据调用到内存中,然后从内存中读取,从而大大提高读取速度。 

通过上面对硬盘和内存的存储介质的分析,不难推出Memcache的读写速度有多快。本人亲自测试过,原来使用handle socket写入数据库需要91秒的大量数据,改成使用Memcache之后,只需要8秒钟。在未来,还会详细对比MemcachettServerHandle Socket以及文件系统的读写速度,敬请关注!