Memecached是以liveJournal 旗下Danga Interactive 公司的Brad Fitzpatric 为首开发的一款内存缓存软件,现在已在Mixi、Haterna、Facebook、VOX、LiveJournal等众多服务中用于提高web应用扩展性。
为什么要用Memcached
随着互联网的发展,特别是web2.0网站的兴起,传统的关系型数据库(如MySQL、Oracle)开始出现瓶颈,很多方面不能满足我们的需求,例如:
1) 对数据库的并发读写。
关系型数据库本生就是个庞然大物,处理过程非常复杂和耗时(如解析SQL语句,事务处理等)。如果对关系型数据库进行高并发读写(每秒上万次的访问),那么关系型数据库是不能承受的。
2)对海量数据的处理
对于大型的SNS网络,每天有上万条的数据缠上(如微博)。对于关系型数据库,如果在一个有上亿条数据的数据表中查找某条记录,效率会变得低的难以忍受。
使用Memcached能够很好的解决以上问题。
memcache的安装和使用
memcached 是高性能的分布式内存缓存服务器,通过缓存数据库查询结果,减少数据库访问次数,以提高动态web应用的速度和可扩展性。
memcached 有如下特点
- 协议简单;
- 基于libevent的事件处理;
- 内置内存存储方式;
- 采用不互相通信的分布式。
memcached 以守护进程的形式运行于一个或者多个服务器中,随时接受客户端的连接操作,客户端可以由多种语言写成,如perl、 php、 python、ruby、java、C#、C 等。客户端在与memcached服务建立连接之后,接下来的事情就是存取对象了。每个被存储的对象都有一个唯一的标识符key 与之相关联,通过key可以对对象进行读取操作。保存在memcached的对象实际上放置在内存中,这也是memcached如此高效快速的原因。
要注意的是,存储这些对象并不是持久的,服务停止之后,里边的数据就会丢失。典型的应用模型如图所示:
为了提高性能,memcached 把数据存储在内存中。由于数据仅存在于内存之中,因此重启memcached或者操作系统会导致全部数据丢失。另外内存容量达到指定值之后,就会使用LRU(least recently used) 算法自动删除不使用的(或者很少使用的)缓存。memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的持久化问题。
安装memcached 服务器
安装memcached 服务器比较简单,这里以Ubuntu系统作为安装平台,安装的步骤如下。
- 在安装memcached 之前,必须先安装依赖库libevent,安装方法如下:
wget https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/libevent-2.1.8-stable.tar.gz
tar -zxvf libevent-2.1.8-stable.tar.gz
cd libevent-2.1.8-stable
./configure --prefix=/usr/local/
make
sudo make install
echo "/usr/local/bin" >>/etc/ld.so.conf
ldconfig
- libevent 安装完毕,开始安装memcached服务器,安装过程如下:
wget https://memcached.org/files/memcached-1.4.36.tar.gz
tar xf memcached-1.4.36.tar.gz
cd memcached-1.4.36
./configure --prefix=/usr/local/memcached && make && make install
- memcached 安装完毕,使用以下命令启动memcached 服务器:
/usr/local/memcached/bin/memcached -d -m 128 -u root -p 11211
memcache 常用启动选项及其描述如下所示:
-d 以守护程序(daemon)方式运行memcached
-m 设置memacached可以使用的内存大小,单位为MB
-l 设置监听的IP地址,如果是本机的话,通常不设置此参数
-p 设置监听的端口,默认为11211,也可以不设置此参数
-u 指定用户,如果当前为root,需要使用此参数指定用户
除以上5个常用启动选项外,还有很多其他选项,通过一下命令可以了解更多的启动选项信息:
/usr/local/memcached/bin/memcached -h
安装memacached 客户端
memcached客户端非常丰富,本节使用php的memcache扩展进行解说。
- 安装php的memcache扩展过程如下:
wget http://pecl.php.net/get/memcache-2.2.5.tgz
tar -zxvf memcache-2.2.5.tgz
cd memcache-2.2.5
phpize
./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with zlib-dir
make
sudo make install
- 在php 配置文件php.ini中加入以下配置:
extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20120625/memcache.so
- 重启web服务器
如果安装成功,可以通过phpinfo()获得该扩展的相关信息。
安装完成之后,便可以使用memcache 扩展与memcached服务器进行交互了。
下面使用memcache 扩展编写一个简单例子:
connect('127.0.0.1',11211); //连接memcached 服务器
$mc->set('key','value',0,10); //存储数据
$val = $mc->get('key'); //获取数据
$mc->delete('key'); //删除数据
$mc->flush(); //强制刷新全部缓存,即清空memcached 服务器
$mc->close(); //断开memacached 服务器的连接
?>
可以看出,使用memcache扩展非常简单。
memcache 扩展还有很多有用的方法,下面就介绍这些方法。
使用memcache扩展访问memcached服务器
memcache扩展提供了非常丰富的方法访问memcached服务器。下面介绍memcached扩展的一些常用方法。
- Memcache::connect
connect 方法用于连接Memcached服务器,用法如下:
bool Memcache::connect( string $host[,int $port[,int $timeout ]] )
- $host:服务器域名或ip
- $port: 服务器TCP 端口号,默认值是11211.
- $timeout: 连接持续(超时)时间,单位为秒。默认值1秒,修改此值之前要慎重,过长的连接持续时间可能会导致失去所有的缓存优势。
- Memcache::addServer
addServer 方法用于向对象添加一个服务器(注:addServer没有连接到服务器的动作,所以在Memcached进程没有启动的时候,执行addServer成功也会返回True),用法如下:
bool Memcache::addServer( string $host [, host [, int $port [, bool $persistent [, int $weight [, int $timeout [, int $retry _interval [, bool $status [, callback $failure _ callback]]]]]]]])
- $host: 服务器域名或ip
- $port:端口号,默认为11211.
- $persistent:是否使用常连接,默认为TRUE。
- $weight:权重,在多个翻译我也去设置中占的比重
- $timeout:连接Memcached服务器失效的描述。
- $retry_interval:服务器连接士百士的重试频率,默认是15秒一次,如果设置为-1将禁止自动重试。
- $status:控制服务器是否被标记位online,设置这个参数为FALSE并设置retry_interval为-1 可以是连接失败的服务器被放倒一个描述不响应请求的服务器池中,对这个服务器的请求将失。默认参数为TRUE,代表该服务器可以被定义为online。
- $failure_calback:失败时的回调函数,函数的两个参数为失败服务器的hostname和port。
3.Memcache::add
add 方法用于向Memcached服务器添加一个要缓存的数据(如果Memcached服务器已经存在要存储的key,add方法调用失败)。用法如下:
bool Memcache::add( string $key, mixed $var [, int $flag [, int $expire ]])
- $key: 缓存数据的键,其长度不能超过250字节
- $var:缓存数据库的值,其值最大为1MB。
- $flag:是否使用ZLib压缩。把 flag设置为MEMCACHE_COMPRESSED时,如果要缓存的数据很小,不会采用ZLib压缩,还有数据达到一定大小时才对数据进行ZLib压缩。
- $expire: 缓存数据的过期时间。0为永不过期,可使用UNIX时间戳格式或距离当前时间的描述,设为秒数时不能大于2592000(30天)。
注意 key的最大长度为250字节可以从memcached源码中看到(版本1.2.8):
static void process_update_command(conn *c ,token_t *tokens, const size_t ntokens, int comm,bool handle_cas) {
...
if (tokens [KEY_TOKEN].length> KEY_MAX_LENGTH){
out_string(c, "CLIENT_ERROR bad command line format");
return;
}
...
}
代码中的tokens[KEY_TOKEN].length
就是key的长度,而KEY_MAX_LENGTH
被定义为250,即key的长度不能大于250字节。因此,为了节省内存和带宽,我们应该尽量使用较短的key