[缓存加速]eAccelerator与memcached的区别与用途

eAccelerator和memcached,是目前较为主流的两个可使用在PHP之中的缓存加速工具.

eAccelerator专门为PHP开发,而memcached不仅仅用在PHP之中,其他所有的语言都可以使用.

eAccelerator的主要功能:
1. 缓存PHP文件的执行代码:在被缓存的代码再次被调用时,将直接从内存读取,从而在很大程度了PHP运行的速度.
2. 提供了共享内存操作函数:用户可以将自己的常见非资源对像,保存到内存之中,并可以随时读取出来.

memcached的主要功能:
提供共享内存操作函数,可以保存和读取数据

两者的共同点:
共同点:都提供了共享内存操作函数,可以用来保存和读取自己的数据

两者的区别
eAccelerator作为PHP的扩展库存在,那么仅在PHP运行时,可以操作和读写共享内存,一般情况,只能由操作共享内存的程序自己调用.同时,eAccelerator可以缓存PHP程序的执行代码,提升程序的调入和执行速度.
memcached主要作为一个共享内存服务器,其PHP扩展库仅仅作为PHP到memcached的连接库存在,类似MySQL扩展库.因而,memcached可以完全脱离PHP,其共享的数据,可以被不同的程序调用.

根据两者的不同,我们将他们使用在真真需要的地方:
eAccelerator主要用于单机PHP提速,缓存中间数据.对于实时性高,但数据操作量小的情况下,非常实用.
memcached用于分布式或者集群系统,多台服务器可以共享数据.对于实时性高,同时数据操作量大的情况下,非常实用.

memcached安装+php使用手记

http://blog.csdn.net/felio/archive/2006/09/29/1303647.aspx

本文简要介绍一下安装的情况,以及PHP模块memcache使用情况:

提要:
1。安装memcached服务器端
2。安装phpmemcache支持模块
3。使用memcache情况,计数器、数据压缩
4。Memcache内存的更新清理(delete flush)
5。内存超量的测试(set)

1。安装memcached服务器端
memcached
安装说明(北南南北的站)
http://www.linuxsir.org/main/?q=node/184 

Linux下缓存服务器的应用
作者:tonyvicky
来自:LinuxSir.Org
摘要:由于数据库存储的数据量越来越大,查询速度也就变的越来越慢,因此就有了缓存服务器应用的必要,本文是介绍Memcached的安装以及简单的使用。

本文只介绍memcached的PHP的API,想查看其他关于Memcached的API文档案,请访问 http:
//www.danga.com/memcached/

目录

一、环境需求
二、下载相关软件
三、安装和配置

1、安装Memcached
2、安装memcache PHP模块
3、测试脚本
四、关于本文


++++++++++++++++++++++++++++++++++++++++
正文
++++++++++++++++++++++++++++++++++++++++


一、环境需求
安装Memcached需要libevent库的支持,所以请在安装Memcached之前检查有没有安装libevent。测试环境还需要PHP的支持,本文假设PHP已经安装到
/usr/local/php目录下,也就是在编译PHP的时候使用perfix参数指定目录(--prefix=/usr/local/php)

二、下载相关软件

Memcached下载地址:http:
//www.danga.com/memcached/
memcache PHP模块下载地址: http:
//pecl.php.net/package/memcache 推荐使用1.5版
libevent 下载地址: http:
//www.monkey.org/~provos/libevent/

本文不再讲述如何安装libevent,可以参考:http://blog.haohtml.com/archives/364

三、安装和配置

1、安装Memcached


root@tonyvicky:
# tar vxzf memcached-1.1.12.tar.gz
root@tonyvicky:# cd memcached-1.1.12
root@tonyvicky:# ./configure --prefix=/usr/local/memcached
root@tonyvicky:# make
root@tonyvicky:# make install

安装完之后要启动服务


root@tonyvicky:
# cd /usr/local/memcached/bin
root@tonyvicky:# ./memcached -d -m 50 -p 11211 -u root

参数说明 
-m 指定使用多少兆的缓存空间;-p 指定要监听的端口; -u 指定以哪个用户来运行

2、安装memcache PHP模块


root@tonyvicky:
# tar vxzf memcache-1.5.tgz
root@tonyvicky:# cd memcache-1.5
root@tonyvicky:# /usr/local/php/bin/phpize
root@tonyvicky:# ./configure --enable-memcache --with-php-config=/usr/local/php/bin/php-config --with-zlib-dir
root@tonyvicky:# make
root@tonyvicky:# make install

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


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

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


extension_dir 
= "./"

修改为


extension_dir 
= "/usr/local/php/lib/php/extensions/no-debug-non-zts-20050922/"

并添加一行


extension
=memcache.so

3、测试脚本

自己写一个PHP程序测试一下吧


<?php
$memcache 
= new Memcache; //创建一个memcache对象
$memcache
->connect('localhost'11211or die ("Could not connect"); //连接Memcached服务器
$memcache
->set('key''test'); //设置一个变量到内存中,名称是key 值是test
$get_value 
= $memcache->get('key'); //从内存中取出key的值
echo $get_value;
?
>

注意的是:如果你安装过程中出现错误,请看看是不是有模块没装:
autoconf
zlib (
压缩数据用

)

2。安装phpmemcache支持模块
PHP
老家:
http://cn.php.net/manual/zh/ref.memcache.php

 

Memcache Functions
简介
Memcache module provides handy procedural and 
object oriented interface to memcached, highly effective caching daemon, which was especially designed to decrease database load in dynamic web applications.

This module doesn
't have native support of multiple servers, but you still can implement it yourself in your application. Establish several memcached connections, set priority level for each server etc.

More information about memcached can be found at http://www.danga.com/memcached/.

需求
This module uses functions of zlib to support on-the-fly data compression. Zlib is required to install this module.

PHP 4.3.3 or newer is required to use the memcache extension.

安装
本 PECL 扩展未绑定于 PHP 中。 进一步信息例如新版本,下载,源程序,维护者信息以及更新日志可以在此找到: http://pecl.php.net/package/memcache.

In order to use these functions you must compile PHP with Memcache support by using the --enable-memcache[=DIR] option.

Windows users will enable php_memcache.dll inside of php.ini in order to use these functions. 可以从 PHP 下载页面或者 http://snaps.php.net/ 下载此 PECL 扩展的 DLL 文件。

预定义常量
表格 1. MemCache Constants

Name Description
MEMCACHE_COMPRESSED (integer)  Used to turn on-the-fly data compression on with Memcache::set(), Memcache::add() 和 Memcache::replace().

运行时配置
本扩展模块在 php.ini 中未定义任何配置选项。

资源类型
There is only one resource type used in memcache module - it
's the link identifier for a cache server connection.

范例
例子 
1. memcache extension overview example

<?php

$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

$version = $memcache->getVersion();
echo "Server's version: ".$version."<br/> ";

$tmp_object = new stdClass;
$tmp_object->str_attr = 'test';
$tmp_object->int_attr = 123;

$memcache->set('key', $tmp_object, false, 10) or die ("Failed to save data at the server");
echo "Store data in the cache (data will expire in 10 seconds)<br/> ";

$get_result = $memcache->get('key');
echo "Data from the cache:<br/> ";

var_dump($get_result);

?>



In the above example
, an object is being saved in the cache and then retrieved back. Object and other non-scalar types are serialized before saving, so it's impossible to store resources (i.e. connection identifiers and others) in the cache.

目录
Memcache::add -- Add an item to the server
Memcache::close -- Close memcached server connection
Memcache::connect -- Open memcached server connection
memcache_debug -- Turn debug output on/off
Memcache::decrement -- Decrement item
's value
Memcache
::delete -- Delete item from the server
Memcache
::flush -- Flush all existing items at the server
Memcache
::get -- Retrieve item from the server
Memcache
::getStats -- Get statistics of the server
Memcache
::getVersion -- Return version of the server
Memcache
::increment -- Increment item's value
Memcache::pconnect -- Open memcached server persistent connection
Memcache::replace -- Replace value of the existing item
Memcache::set -- Store data at the server



 add a note User Contributed Notes
Memcache Functions
ed at me3inc dot com
27-Oct-2006 05:47
Re. Installing the memcache extension:

I had all kinds of troubles getting it hooked up, because in all of the instructions I read I never got the last, most important step - you must have a php.ini and have in it "extension=memcache.so."

So, the steps:
First - ./configure with --enable-memcache. This should show in your phpinfo() at the top (even though nothing of the memcache extension works yet).

Second:
either pecl install memcache
OR
download the source
tar -xzvf [thesourcetarball]
phpize
./configure
make
make install

Finally: Add extension=memcache.so to your php.ini. (If you don
't have one, it should go in the root of where php is called ie., /usr/local/lib)

Call 
phpinfo() and you should see a memcache section.
iliya at pisem dot net
20-Jan-2006 04:35
one more 
"intelligent" cache aggregator:
https
://svn.shadanakar.org/onPHP/ trunk/core/Cache/AggregateCache.class.php
can be used with several cache connectors - memcached, filesystem, etc.
(remove whitespace manually)
Gregor J
. Rothfuss
22-Nov-2005 01:18
The 
next version will have failover. It's been committed three weeks ago. Usage notes here: http://www.codecomments.com/archive367-2005-10-659421.html
Ron
15-Sep-2005 04:19
An improvement to the above:

The above class will cause an error if all cache servers are down.  The preferred behavior is to just have a cache miss (or take no action in the case of write operations) and return false, so the app can run in non-cached mode if all cache servers are down.

To make this happen, simply change the connection usage to look something like this in each affected function.  This code is for the get() function:

       $con = $this->_getConForKey($key);
       if ($con === false) return false;
       return $con->get($key);

Similarly, the affected code in the set() function would look like this:
   $con = $this->_getConForKey($key);
   if ($con === false) return false;
   return $con->set($key, $var, $compress, $expire);

Modify each function accordingly, and if all of your cache servers are down, you can still function (although more slowly due to the 100% cache miss rate).
Ron
15-Sep-2005 01:20
Here is a simple memcached aggregator class which distributes the cache among multiple cache servers.  If a server fails, the load is redistributed automatically.  It uses persistent connections.

The constructor takes an array of arrays, with each inner array representing a server, with a 
'server' (string) attribute that is the IP addres or host name of the memcached server, and a 'port' (int) attribute that is the port number on which memcached is running on the server.

All of the existing memcached API functions are implemented except getStats() and getVersion(), which are server-specific.

<?php
class MemcachedAggregator {
   var $connections;

   public function __construct($servers) {
   // Attempt to establish/retrieve persistent connections to all servers.
   // If any of them fail, they just don
't get put into our list of active
   
// connections.
   $this->connections = array();
   
for ($i = 0, $n = count($servers); $i < $n$i++) {
       
$server = $servers[$i];
       
$con = memcache_pconnect($server['host'], $server['port']);
       
if (!($con == false)) {
       
$this->connections[] = $con;
       }
   }
   }

   
private function _getConForKey($key) {
   
$hashCode = 0;
   
for ($i = 0, $len = strlen($key); $i < $len$i++) {
       
$hashCode = (int)(($hashCode*33)+ord($key[$i])) & 0x7fffffff;
   }
   
if (($ns = count($this->connections)) > 0) {
       
return $this->connections[$hashCode%$ns];
   }
   
return false;
   }

   
public function debug($on_off) {
   
$result = false;
   
for ($i = 0$i < count($connections); $i++) {
       
if ($this->connections[$i]->debug($on_off)) $result = true;
   }
   
return $result;
   }

   
public function flush() {
   
$result = false;
   
for ($i = 0$i < count($connections); $i++) {
       
if ($this->connections[$i]->flush()) $result = true;
   }
   
return $result;
   }

/// The following are not implemented:
//
/getStats()
//
/getVersion()

   
public function get($key) {
   
if (is_array($key)) {
       
$dest = array();
       
foreach ($key as $subkey) {
       
$val = get($subkey);
       
if (!($val === false)) $dest[$subkey= $val;
       }
       
return $dest;
   } 
else {
       
return $this->_getConForKey($key)->get($key);
   }
   }

   
public function set($key, $var, $compress=0, $expire=0) {
   
return $this->_getConForKey($key)->set($key, $var, $compress, $expire);
   }

   
public function add($key, $var, $compress=0, $expire=0) {
   
return $this->_getConForKey($key)->add($key, $var, $compress, $expire);
   }

   
public function replace($key, $var, $compress=0, $expire=0) {
   
return $this->_getConForKey($key)->replace
       (
$key, $var, $compress, $expire);
   }

   
public function delete($key, $timeout=0) {
   
return $this->_getConForKey($key)->delete($key, $timeout);
   }

   
public function increment($key, $value=1) {
   
return $this->_getConForKey($key)->increment($key, $value);
   }

   
public function decrement($key, $value=1) {
   
return $this->_getConForKey($key)->decrement($key, $value);
   }

}
?>

难道,4.3.3都装上了吗?好像没有吧,用4.4.4好像都要另外装的

)

3。使用memcache情况,计数器、数据压缩
使用情况一:统计

 

(PHP 4.3.3 or newer is required to use the memcache extension.

<?php
//
访问统计
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
if($s=$memcache->get('a')) {
$s=$s+1;
$memcache->set('a',$s);
}
else
$memcache->set('a',1);
echo '访问结果为:'.$s;
?>

其实我们可以用increment方法代替上面的做法

<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

if($s=$memcache->increment('a',1)) {
echo $s;
}
else
$memcache->set('a',1);
?>

 

 

数据压缩 

<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$test=(str_repeat('jetwong',100000));
$memcache->set('b',($test));
?>
使用压缩:
<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");
$test=(str_repeat('jetwong',100000));
$memcache->set('b',($test),MEMCACHE_COMPRESSED);
?>


使用情况说明:

前台比较

目前内存
bytes

总共读取
bytes_read

总共写入
bytes_written

压缩前

700085

700081

416

压缩后

1131

1125

13

可能看到压缩后明显占用内存少了不少

 

4。Memcache内存的更新清理(delete flush)

<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

/*设置值*/
$status = $memcache->getStats();
echo '设置前内存使用情况'.$status['bytes'].'<br>';
echo '设置后';
for($i=0;$i<9;$i++) {
$memcache->set('b'.$i,rand(1,99));
echo '<br>'.$i.'->'.$memcache->get('b'.$i

);
}

/*查看设置的值*/
$status = $memcache->getStats();
echo 'delete前内存使用情况'.$status['bytes'].'<br>';
echo '<br>开始delete';
for($i=0;$i<9;$i++) {
$memcache->delete('b'.$i);
echo '<br>'.$i.'->'.$memcache->get('b'.$i

);
}

/*查看flush使用的情况*/
$status = $memcache->getStats();
echo '使用flush前内存使用情况'.$status['bytes'].'<br>';
echo '使用flush情况:';
for($i=0;$i<9;$i++) {
$memcache->set('b'.$i,rand(1,99));
echo '<br>'.$i.'->'.$memcache->get('b'.$i);
}
$memcache->flush();
echo 'flush之后:';
for($i=0;$i<9;$i++) {
echo '<br>'.$i.'->'.$memcache->get('b'.$i);
}
$status = $memcache->getStats();
echo 'flush后内存使用情况'.$status['bytes'].'<br>';
?>

 

 

 

5。内存超量的测试(set)

 我们把内存设为2M

./memcached -d -m 2 -p 11211 -u root

 

<?php
$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

//600K左右
$test1str_repeat('jetlee',100000);
//600K左右
$test2str_repeat('jetlee',100000);
//600K左右
$test3str_repeat('李连杰',200000);
//600K左右
$test4str_repeat('连杰李',100000);
//200K
$test5file_get_contents('http://img.pconline.com.cn/images/photoblog/2988177/20068/4/1154688770042_mthumb.JPG');
$test6file_get_contents

('http://img.pconline.com.cn/images/photoblog/1767557/20069/28/1159417108902_mthumb.jpg');

for($i=1;$i<=6;$i++) {
$j='test'.$i;
if($memcache->set($j,$$j)) {
echo $j.'->设置成功<br>';
$status = $memcache->getStats();
echo '内存:'.$status['bytes'].'<br>';
}
else {
echo $j.'->设置失败<br>';
}
}
?>

 

执行结果:

test1->设置成功
内存:600042
test2->
设置成功

内存:1200084
test3->
设置失败

test4->
设置成功
内存:1200084
test5->
设置失败

test6->
设置失败

 

刚好印证我们的计算,不过20万的repeat为什么会失败,不是太了解,,,,,,

 

总结:

示例:

<?php
//
设置篇
if($data = $memcache->get('k',$v)) {
//显示我们的数据
    }
else {
$data = get_from_database; //得到数据源
    if(!$memcache->set('k',$data),MEMCACHE_COMPRESSED) //开始设置
    log();    //不成功,记录失败信息
}
?>

 

  -----------OVER-----------

相关教程:

Linux下Memcached的安装及配置:http://blog.haohtml.com/archives/364
基于 PHP5 & JQuery 的 Memcached 管理监控工具:http://www.junopen.com/memadmin/

memcached与memcache的区别

memcached 像是一个后台服务器(也有客户端的memcached),memcache是php的一个模块,需要编译,像是一个客户端,memcached 和 memcache 是紧密结合的两个东西。

另外memcached也是一个客户端的.这点可以参考php手册得知.两者的区别也可以参考:http://www.cnblogs.com/scotoma/archive/2011/02/15/1955573.html

有关linux下memcache和memcached的安装方法请参考:http://blog.haohtml.com/archives/9841

================================

说法一:

两个不同版本的php的memcached的客户端

new memcache是pecl扩展库版本
new memcached是libmemcached版本
功能差不多.

说法二:
Memcache是什么?

Memcache是一个自由和开放源代码、高性能、分配的内存对象缓存系统。用于加速动态web应用程序,减轻数据库负载。
它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,Memcached自管理这些HashTable。
Memcached是简单而强大的。它简单的设计促进迅速部署,易于发展所面临的问题,解决了很多大型数据缓存。它的API可供最流行的语言。
Memcache的知名用户有:LiveJournal、Wikipedia、Flickr、Bebo、Twitter、Typepad、Yellowbot、Youtube 等。
Memcache官方网站:http://memcached.org/

Memcached又是什么?
Memcache是该系统的项目名称,Memcached是该系统的主程序文件,以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,使用共享内存存取数据。

那PHP中的Memcache是什么?
php中的所讲的memcache是用于连接Memecached的客户端组件。

简单的说一句话:Memcached 是一个服务(运行在服务器上的程序,监听某个端口),Memcache 是 一套访问Memcached的api。

两者缺一不可,不然无法正常运行。Memcache能在多台服务器上发挥很好的作用,同台服务器上用APC或Xcache效率是很可观的。

同台服务器上APC的效率是Memcached的7倍,APC效率比Memcached高是肯定的

使用MySQL触发器自动更新memcache

    mysql 5.1支持触发器以及自定义函数接口(UDF)的特性,如果配合libmemcache以及Memcached Functions for MySQL,就能够实现memcache的自动更新。简单记录一下安装测试步骤。

安装步骤

安装memcached,这个步骤很简单,随处可见

安装mysql server 5.1RC,安装办法也很大众,不废话了

编译libmemcached,解压后安装即可./configure; make; make install

编译Memcached Functions for MySQL,在http://download.tangent.org/找一个最新的版本下载就是,./configure --with-mysql=/usr/local/mysql/bin/mysql_config --libdir=/usr/local/mysql/lib/mysql/

make

make install

接下来有两个办法让Memcached Functions for MySQL在mysql中生效

在mysql的shell中执行memcached_functions_mysql源码目录下的sql/install_functions.sql,这会把memcache function作为UDF加入mysql

运行memcached_functions_mysql源码目录下的utils/install.pl,这是一个perl脚本,作用同上一条

测试memcache function

以下测试脚本摘自memcached_functions_mysql的源码目录,有兴趣可以试试

PLAIN TEXTCODE: drop table if exists urls;

create table urls (

id int(3) not null,

url varchar(64) not null default '',

primary key (id)

);

select memc_servers_set('localhost:11211');

select memc_set('urls:sequence', 0);

DELIMITER |

DROP TRIGGER IF EXISTS url_mem_insert;

CREATE TRIGGER url_mem_insert

BEFORE INSERT ON urls

FOR EACH ROW BEGIN

SET NEW.id= memc_increment('urls:sequence');

SET @mm= memc_set(concat('urls:',NEW.id), NEW.url);

END |

DELIMITER ;

insert into urls (url) values ('http://google.com');

insert into urls (url) values ('http://www.ooso.net/index.php');

insert into urls (url) values ('http://www.ooso.net/');

insert into urls (url) values ('http://slashdot.org');

insert into urls (url) values ('http://mysql.com');

select * from urls;

select memc_get('urls:1');

select memc_get('urls:2');

select memc_get('urls:3');

select memc_get('urls:4');

select memc_get('urls:5');

让memcached和mysql更好的工作

  这次是Fotolog的经验,传说中比Flickr更大的网站,Fotolog在21台服务器上部署了51个memcached实例,总计有254G缓存空间可用,缓存了多达175G的内容,这个数量比很多网站的数据库都要大的多,原文是A Bunch of Great Strategies for Using Memcached and MySQL Better Together,我这里还是选择性的翻译以及按照我的理解补充,感谢Todd Hoff,总能给我们一些学习的案例,从这里也能看出国外技术的开放态度,不似我们,其实就那么点小九九还藏着掖着,好了,进入正题。

一、关于memcached

  还不知道这个?那你去面试的时候要吃亏了,赶紧去官方网站看一下http://www.danga.com/memcached/,另外google一下用法,硬盘总是太慢,把数据存在内存里面吧,如果你只有一台服务器,推荐用一下APC(Facebook在用)或者eaccelerator或者Xcache(国人开发的),这些产品单机效果更好,如果你需要分布式的缓存方案,那么用memcached吧。

二、memcached如何与mysql并肩作战?

  • 通过数据库分片来解决数据库写扩展的问题把数据库分片,部署到不同的服务器上,免得只有一个主服务器,写操作成为瓶颈以及可能有的“单点故障”,一般的数据库分片主要是按照业务来分,尽可能的拆分业务,不相干的都独立起来做成服务也好
  • 前端mysql和一堆memcached服务器来应付读的问题应用程序首先从memcached中获取数据,获取不到再从数据库中获得并保存在memcached中,以前看过一篇文章说好的应用95%的数据从memcache的中获得,3%的数据从mysql的query cache中获得,剩下2%才去查表,对比一下你的应用,差距有多远?
  • 通过mysql复制(master-slave)来解决读的问题
    首先mysql数据库通过master-slave读写分离,多个slave来应对应用程序读的操作。

三、为什么不用mysql的query cache?

  我们都知道mysql有个query cache,可以缓存上次查询的结果,可实际上帮不上太多的忙,下面是mysql quety cache的不足:

  • 只能有一个实例
    意味着你能存储内容的上限就是你服务器的可用内存,一台服务器能有多少内存?你又能存多少呢?
  • 只要有写操作,mysql的query cache就失效
    只要数据库内容稍有改变,那怕改变的是其他行,mysql的query cache也会失效
  • mysql的query cache只能缓存数据库数据行
    意味着其他内容都不行,比如数组,比如对象,而memcached理论上可以缓存任何内容,甚至文件^_^

四、Fotolog的缓存技术

  • 非确定性缓存你不确定你要的数据缓存中有没有,你也不知道是不是过期了,于是你就试探性的问memcached,我要的什么什么数据你那有吗?我可不要过期的数据啊,memcached告诉你说有并且给你,你就开心了,如果没有呢,你就要从数据库或者别的地方去获取了,这是memcached典型的应用。主要应用在:1.复杂的数据需要多次读取,你的数据库做了分片处理,从多个数据库中获取数据并组合起来是一个非常大的开销,你大可以把这些数据取出来之后存到memcached中

    2.mysql query cache的一个好的替代方案,这样数据库其他部门改变了,只要自己没改变就没问题(注意数据库更新的问题,后面会提到)

    3.把关系或者列表缓存起来,比如某个栏目下的多篇文章列表

    4.被多个页面调用并且获取起来很慢的数据,或者是更新很慢的数据,比如文章浏览排行榜

    5.如果cache的开销超过重新获取的开销,那么不要缓存它吧

    6.标签云和自动建议(类似google sugest)

    例如:当一个用户上传一个图片,这个用户的好友页面上都要列出这张图片来,那么把它缓存起来吧。

    潜在问题:

    memcached消耗的主要是服务器内存,对CPU消耗很小,所以Fotolog把memcached部署在他们的应用服务器上(貌似我们也是这样),他们遇到了CPU搞到90%的使用率(怎么会那么高?哪出问题了吧)、内存回收(这是个大问题)等等问题。

  • 状态缓存把应用服务的当前状态存在memcached中主要应用在:1.“昂贵”的操作,开销大的操作

    2.sessions会话,Flickr把session存在数据库中,个人感觉还是存memcached比较“便宜”些,如果memecached服务器down掉了,那么重新登录吧。

    3.记录用户在线信息(我们也是这样做的)

  • 确定性缓存对于某些特定数据库的全部内容,都缓存到memcached,有一个专门的应用服务来保障你要的数据都在memcached中,其他应用服务直接从memcached中获取数据而不去取数据库,因为数据库已经全部保存到memcached中并保持同步。主要应用在:1.读取伸展,所有的读取都从memcached中获得,数据库没有负载

    2.”永不过期“(相对的)的数据,比如行政规划数据,变动很小吧

    3.经常调用的内容

    4.用户的认证信息

    5.用户的概要信息

    6.用户的参数设置

    7.用户当前常用的媒体文件列表,比如用户的图片

    8.用户登录,不走数据库,只走memcached(个人觉得这个不太好,登录信息还是需要持久化的,用类似BDB这样效果也不错)

    使用方式:

    1.多个专门的缓存池而不是一个大的缓存服务器,多个缓存池保障了高可用性,一个缓存实例挂掉了走其他的缓存实例,所有的缓存实例挂掉了,走数据库(估计数据库抗不住^_^)

    2.所有的缓存池都用程序来维护,比如数据库有更新时,程序自动把更新后的内容同步到多个缓存实例中

    3.服务器重启之后,缓存要比网站先启动,这就意味着当网站已经启动了,所有的缓存都可用

    4.读取的请求可以负载均衡到多个缓存实例中去,高性能,高可靠性

    潜在的问题:

    1.你需要足够多的内存来存储那么多的数据

    2.数据以行记录数据,而memcached以对象来存储数据,你的逻辑要把行列的数据转换成缓存对象

    3.要维护多个缓存实例非常麻烦,Fotolog用Java/Hibernate,他们自己写了个客户端来轮询

    4.管理多个缓存实例会增加应用程序的许多开销,但这些开销相对于多个缓存得到的好处来说算不了什么

  • 主动缓存数据魔法般的出现在缓存中,当数据库中有更新的时候,缓存立马填充,更新的数据被调用的可能性更高(比如一篇新文章,看的的人当然多),是非确定性缓存的一种变形(原文是It’s non-deterministic caching with a twist.我觉得这样翻译怪怪的)。主要应用在:1.预填充缓存:让memcached尽可能的少调用mysql如果内容不展现的话。

    2.“预热”缓存:当你需要跨数据中心复制的时候

    使用步骤:

    1.解析数据库更新的二进制日志,发现数据库更新时对memcached也进行同样的更新

    2.执行用户自定义函数,设置触发器调用UDF更新,具体参考http://tangent.org/586/Memcached_Functions_for_MySQL.html

    3.使用BLACKHOLE策略,传说中Facebook也用mysql的Blackhole存储引擎来填充缓存,写到Blackhole的数据复制到缓存中,Facebook用这来设置数据作废以及跨国界的复制,好处是数据库的复制不走mysql,这就意味着没有二进制日志以及对CPU使用不那么多(啊?难道通过memcached存储二进制日志,然后复制到不同的数据库?有经验的同志在这个话题上可以补充。)

  • 文件系统缓存把文件直接缓存在memcached中,哇,够BT的,减轻NFS的负担,估计只缓存那些过于热门的图片吧。
  • 部分页面内容缓存如果页面的某些部分获取起来非常费劲,以其缓存页面的原始数据还不如把页面的部分内容直接缓存起来直接调用
  • 应用程序级别的复制通过API来更新缓存,API的执行细节如下:1.一个应用把数据写到某个缓存实例,这个缓存实例把内容复制到其他缓存实例(memcached同步)2.自动获得缓存池地址以及实例个数

    3.同时对多个缓存实例更新

    4.如果某个缓存实例down掉了,跳到下一个实例,直到更新成功

    整个过程非常高效以及低开销

  • 其他技巧1.多节点以应对”单点故障”2.使用热备技术,当某个节点down掉了,另外一台服务自动替换成它的IP,这样客户端不用更新memcached的IP地址3.memcached可以通过TCP/UDP访问,持续连接可以减轻负载,系统设计成可同时承受1000个连接

    4.不同的应用服务,不同的缓存服务器群

    5.检查一下你的数据大小是否匹配你分配的缓存,更多请参考http://download.tangent.org/talks/Memcached%20Study.pdf

    6.不要考虑数据行缓存,缓存复杂的对象

    7.不要在你的数据库服务器上跑memcached,两个都是吃内存的怪兽

    8.不要被TCP延迟困扰,本地的TCP/IP对内存复制是做了优化的

    9.尽可能的并行处理数据

    10.并不是所有的memcached的客户端都是一样的,仔细研究你用的语言所对应的(好像php和memcached配合的不错)

    11.尽可能的是数据过期而不是使数据无效,memcached可以设定过期时间

    12.选择一个好的缓存标识key,比如更新的时候加上版本号

    13.把版本号存储在memcached中

  作者最后的感言我就不翻译了,貌似mysql proxy正在做一个项目,自动同步mysql以及memcached,更多参考http://jan.kneschke.de/2008/5/18/mysql-proxy-replicating-into-memcache

来自:http://chaoqun.17348.com/2008/08/memcached_work_with_mysql/

多memcached 和 mysql 主从 环境下PHP开发: 代码详解(转)

多memcached 和 mysql 主从 环境下PHP开发: 代码详解

4点了.今天是最后一天在这间公司.心情不是很好.

所以写下东西发泄下.    
    一般的大站通常做法是    拿着内存当数据库来用(memcached).     和很好的读  写分离  备份机制 (mysql 的主从)

在这样的环境下我们怎么进行PHP开发呢.  本人不太会讲话.所以还是帖代码吧.  

刚在linux  的 VIM  里写的一个  demo    调试通过.  也同时希望大家拍砖 ,  使用PHP5  写的. PHP4写出来怕大家说我落后了

PHP代码:


<?php
$memcached 
= array(  //用memcached 的 多 进程模拟 多台memcached 服务器     cn     en   为  内存服务器名
     
'cn'=>array('192.168.254.144',11211),
     
'en'=>array('192.168.254.144',11212)
     );
$mysql    = array( // mysql 的主从 我的环境是 : xp 主    linux 从  mysql 5  php5
     
'master'=>array('192.168.254.213','root','1','mydz'),
     
'slave_1'=>array('192.168.254.144','root','1','mydz')  //可以灵活添加多台从服务器
     
);
?>

服务器配置文件: 十分方便的 切换主从.  当主换了  从可以迅速切换为主.  支持 多从服务器   .

复制PHP内容到剪贴板

PHP代码:


<?php
class Memcached
{
private 
$mem;
public 
$pflag=''// memcached pconnect tag
private function memConnect($serkey){
  require 
'config.php';
  
$server $memcached;
  
$this->mem = new Memcache;
  
$link = !$this->pflag 'connect' 'pconnect' ;
  
$this->mem->$link($server[$serkey][0],$server[$serkey][1]) or $this->errordie('memcached connect error');

}

public function set($ser_key,$values,$flag='',$expire=''){
  
$this->memConnect($this->tag($ser_key));
  if(
$this->mem->set($ser_key,$values,$flag,$expire)) return true;
  else return 
false;

public function get($ser_key){
  
$this->memConnect($this->tag($ser_key));
  if(
$var=$this->mem->get($ser_key)) return $var;
  else return 
false

private function 
tag($ser_key){
  
$tag=explode('_',$ser_key);
  return 
$tag[0];
}
private function 
errordie($errmsg){
  die(
$errmsg);
}
}
?>

简单的封装了 memcached  的操作. 详细的时间不多.我要离开公司了   

在memcached 的多服务器上.  我的实现思路是这样的:   在把信息添加到 内存服务器的时候.我选择了手工设置添加到那个服务器.而不用传统的根据ID自动分配.
这样可以更灵活点.  

以内存服务器名 为表示   比如 存  $arr 这个信息到  en 这台 内存服务器 我就这样写   $mem->set('en_'.$arr);    明白了吧

PHP代码:


<?php
class Mysql
{
private   
$mysqlmaster;
private   
$myssqlslave;
private static 
$auid=0;
public function 
__construct(){
  require 
'config.php';
  
$msg $mysql;
  
  
$this->mysqlmaster = new mysqli($msg['master'][0],$msg['master'][1],$msg['master'][2],$msg['master'][3]); //master mysql
   
$this->mysqlslave  $this->autotranscat($msg); // slave mysql

  if(mysqli_connect_errno()){
   
printf("Connect failed: %s\n",mysqli_connect_error());
   exit();
  }
  if(!
$this->mysqlmaster->set_charset("latin1") && !$this->mysqlslave->set_charset("latin1")){
   exit(
"set charset error");
  }
}

private function autotranscat($mysql){
  
session_start();
  
$_SESSION['SID']!=|| $_SESSION['SID']=0   ;
  if(
$_SESSION['SID'] >=count($mysql)-1$_SESSION['SID'] = 1;
  else 
$_SESSION['SID']++;
  
$key 'slave_'.$_SESSION['SID'];
  echo(
$_SESSION['SID']);
  return new 
mysqli($mysql[$key][0],$mysql[$key][1],$mysql[$key][2],$mysql[$key][3]);
}

public function mquery($sql){ //insert  update 
  
if(!$this->mysqlmaster->query($sql)){
   return 
false;
  }
}

public function squery($sql){
  if(
$result=$this->mysqlslave->query($sql)){
   return 
$result
  }else{
   return 
false;
  };
}
public function 
fetArray($sql){
  if(
$result=$this->squery($sql)){
   while(
$row=$result->fetch_array(MYSQLI_ASSOC)){
    
$resultraa[] = $row;
   };
   return 
$resultraa;
  }
}
}
?>

这个是 mysqli 的封装.  也就是   读  从  写 主  的操作的封装.

复制PHP内容到剪贴板

PHP代码:


<?php
require 'init.php';
$mem = new Memcached;
/* $mem->set('en_xx','bucuo');
echo($mem->get('en_xx'));
$mem->set('cn_jjyy','wokao');
echo($mem->get('cn_jjyy'));
*/ 
$sq = new Mysql;
$sql "insert into mybb(pid) values(200)";
$mdsql md5($sql);
if(!
$result=$mem->get('cn_'.$mdsql)){
  
$sq->mquery("insert into mybb(pid) values(200)"); //插入到主mysql
  
$result $sq->fetArray("select * from mybb"); //查询 是 从mysql
  
foreach($result as $var){
   echo 
$var['pid'];
  }
  
$mem->set('cn_'.$mdsql,$result); //添加到 名为 cn 的 memcached 服务器  
}else{
  foreach(
$result as $var){
   echo 
$var['pid'];
  }
}
?>

这个是使用程序.   看下就大概明白了.

memcached vs MySQL Memory engine table 速度比较

memcached 1.2.0
MySQL 5.0.26 with MEMORY (heap) engine

记录数:50万~100万条

单机,client 从另外一台机访问
数据:单条 0.1K左右

memcached set/get 15,000 / s
MySQL memory table: insert/select 5,000 / s

结论:
memcached 读写速度是 mysql memory table 3倍左右

优点:
MySQL: 适合对 cache 数据进行Select条件查询。
MemCached: 可以设置 exptime (超时时间),无需自己管理

memcachedb的性能测试

memcachedb故名思义就是 memcached + bdb,是基于memcached Socket层和berkeley-db存储层结构的实现, 是新浪互动社区技术团队2007年的一项重大的技术成果,现在应用于新浪互动社区多个产品线中,其中包括新浪博客等重头产品。能够实现任意memcache api的调用、数据实时落地以及主辅实时备份。

初步感觉用处不大,无非就是利用memcache协议的一个db,性能应该不会很高。如果有分布式需要用手工分数据库的方法也可以实现。但看了介绍http://blog.csdn.net/simonlsy/archive/2008/01/07/2027933.aspx说性能可以达到读写5000次/秒,觉得还是有它的价值。所以简单测试了一下

1. 环境
OS: Linux, Ubuntu 7.04 64-bit
Memory: 4G
CPU: Intel(R) Pentium(R) D CPU 2.66GHz
SCSI DISK, ext3 file system

libevent 1.3e
Memcached 1.2.4
Berkeley DB 4.6.21
Java 1.6.0
memcachedb 0.1.1 安装方法 http://blog.csdn.net/simonlsy/

2. 测试方法
client/server在同一机上,使用ethernet interface连接, 不是localhost
本Linux同时在作 ADSL route gateway,可能会对测试造成小量影响。

JAVA CLIENT, 使用3线程
Key: 数字,1~100万
数据:100字节字符串

3. 测试结果
Memcached 写速度
平均速度: 16222 次/秒
最大速度 18799 次/秒

Memcached 读速度
平均速度: 20971 次/秒
最大速度 22497 次/秒

Memcachedb 写速度
平均速度: 8958 次/秒
最大速度 10480 次/秒

Memcachedb 读速度
平均速度: 6871 次/秒
最大速度 12542 次/秒

由于硬件环境,网络环境,线程数,编程语言不同,可能测试结果差别也很大,本测试结果只起相对参考作用。即比较memcached/memcachedb在相同环境下的性能区别。

利用memcached构建高性能的Web应用程序

面临的问题

    对于高并发高访问的Web应用程序来说,数据库存取瓶颈一直是个令人头疼的问题。特别当你的程序架构还是建立在单数据库模式,而一个数据池连接数峰值已经达到500的时候,那你的程序运行离崩溃的边缘也不远了。很多小网站的开发人员一开始都将注意力放在了产品需求设计上,缺忽视了程序整体性能,可扩展性等方面的考虑,结果眼看着访问量一天天网上爬,可突然发现有一天网站因为访问量过大而崩溃了,到时候哭都来不及。所以我们一定要未雨绸缪,在数据库还没罢工前,想方设法给它减负,这也是这篇文章的主要议题。

    大家都知道,当有一个request过来后,web服务器交给app服务器,app处理并从db中存取相关数据,但db存取的花费是相当高昂的。特别是每次都取相同的数据,等于是让数据库每次都在做高耗费的无用功,数据库如果会说话,肯定会发牢骚,你都问了这么多遍了,难道还记不住吗?是啊,如果app拿到第一次数据并存到内存里,下次读取时直接从内存里读取,而不用麻烦数据库,这样不就给数据库减负了?而且从内存取数据必然要比从数据库媒介取快很多倍,反而提升了应用程序的性能。

    因此,我们可以在web/app层与db层之间加一层cache层,主要目的:1. 减少数据库读取负担;2. 提高数据读取速度。而且,cache存取的媒介是内存,而一台服务器的内存容量一般都是有限制的,不像硬盘容量可以做到TB级别。所以,可以考虑采用分布式的cache层,这样更易于破除内存容量的限制,同时又增加了灵活性。

Memcached 介绍

    Memcached是开源的分布式cache系统,现在很多的大型web应用程序包括facebook,youtube,wikipedia,yahoo等等都在使用memcached来支持他们每天数亿级的页面访问。通过把cache层与他们的web架构集成,他们的应用程序在提高了性能的同时,还大大降低了数据库的负载。
具体的memcached资料大家可以直接从它的官方网站[1]上得到。这里我就简单给大家介绍一下memcached的工作原理:

    Memcached处理的原子是每一个(key,value)对(以下简称kv对),key会通过一个hash算法转化成hash-key,便于查找、对比以及做到尽可能的散列。同时,memcached用的是一个二级散列,通过一张大hash表来维护。

    Memcached有两个核心组件组成:服务端(ms)和客户端(mc),在一个memcached的查询中,mc先通过计算key的hash值来确定kv对所处在的ms位置。当ms确定后,客户端就会发送一个查询请求给对应的ms,让它来查找确切的数据。因为这之间没有交互以及多播协议,所以memcached交互带给网络的影响是最小化的。

举例说明:考虑以下这个场景,有三个mc分别是X,Y,Z,还有三个ms分别是A,B,C:

设置kv对
X想设置key=”foo”,value=”seattle”
X拿到ms列表,并对key做hash转化,根据hash值确定kv对所存的ms位置
B被选中了
X连接上B,B收到请求,把(key=”foo”,value=”seattle”)存了起来

获取kv对
Z想得到key=”foo”的value
Z用相同的hash算法算出hash值,并确定key=”foo”的值存在B上
Z连接上B,并从B那边得到value=”seattle”
其他任何从X,Y,Z的想得到key=”foo”的值的请求都会发向B

Memcached服务器(ms)

内存分配

默认情况下,ms是用一个内置的叫“块分配器”的组件来分配内存的。舍弃c++标准的malloc/free的内存分配,而采用块分配器的主要目的是为了避免内存碎片,否则操作系统要花费更多时间来查找这些逻辑上连续的内存块(实际上是断开的)。用了块分配器,ms会轮流的对内存进行大块的分配,并不断重用。当然由于块的大小各不相同,当数据大小和块大小不太相符的情况下,还是有可能导致内存的浪费。

同时,ms对key和data都有相应的限制,key的长度不能超过250字节,data也不能超过块大小的限制 --- 1MB。
因为mc所使用的hash算法,并不会考虑到每个ms的内存大小。理论上mc会分配概率上等量的kv对给每个ms,这样如果每个ms的内存都不太一样,那可能会导致内存使用率的降低。所以一种替代的解决方案是,根据每个ms的内存大小,找出他们的最大公约数,然后在每个ms上开n个容量=最大公约数的instance,这样就等于拥有了多个容量大小一样的子ms,从而提供整体的内存使用率。

缓存策略

当ms的hash表满了之后,新的插入数据会替代老的数据,更新的策略是LRU(最近最少使用),以及每个kv对的有效时限。Kv对存储有效时限是在mc端由app设置并作为参数传给ms的。

同时ms采用是偷懒替代法,ms不会开额外的进程来实时监测过时的kv对并删除,而是当且仅当,新来一个插入的数据,而此时又没有多余的空间放了,才会进行清除动作。

缓存数据库查询
现在memcached最流行的一种使用方式是缓存数据库查询,下面举一个简单例子说明:

App需要得到userid=xxx的用户信息,对应的查询语句类似:

“SELECT * FROM users WHERE userid = xxx”

App先去问cache,有没有“user:userid”(key定义可预先定义约束好)的数据,如果有,返回数据;如果没有,App会从数据库中读取数据,并调用cache的add函数,把数据加入cache中。

当取的数据需要更新,app会调用cache的update函数,来保持数据库与cache的数据同步。

从上面的例子我们也可以发现,一旦数据库的数据发现变化,我们一定要及时更新cache中的数据,来保证app读到的是同步的正确数据。当然我们可以通过定时器方式记录下cache中数据的失效时间,时间一过就会激发事件对cache进行更新,但这之间总会有时间上的延迟,导致app可能从cache读到脏数据,这也被称为狗洞问题。(以后我会专门描述研究这个问题)

数据冗余与故障预防

从设计角度上,memcached是没有数据冗余环节的,它本身就是一个大规模的高性能cache层,加入数据冗余所能带来的只有设计的复杂性和提高系统的开支。

当一个ms上丢失了数据之后,app还是可以从数据库中取得数据。不过更谨慎的做法是在某些ms不能正常工作时,提供额外的ms来支持cache,这样就不会因为app从cache中取不到数据而一下子给数据库带来过大的负载。

同时为了减少某台ms故障所带来的影响,可以使用“热备份”方案,就是用一台新的ms来取代有问题的ms,当然新的ms还是要用原来ms的IP地址,大不了数据重新装载一遍。

另外一种方式,就是提高你ms的节点数,然后mc会实时侦查每个节点的状态,如果发现某个节点长时间没有响应,就会从mc的可用server列表里删除,并对server节点进行重新hash定位。当然这样也会造成的问题是,原本key存储在B上,变成存储在C上了。所以此方案本身也有其弱点,最好能和“热备份”方案结合使用,就可以使故障造成的影响最小化。

Memcached客户端(mc)

Memcached客户端有各种语言的版本供大家使用,包括java,c,php,.net等等,具体可参见memcached api page[2]。
大家可以根据自己项目的需要,选择合适的客户端来集成。

缓存式的Web应用程序架构
有了缓存的支持,我们可以在传统的app层和db层之间加入cache层,每个app服务器都可以绑定一个mc,每次数据的读取都可以从ms中取得,如果没有,再从db层读取。而当数据要进行更新时,除了要发送update的sql给db层,同时也要将更新的数据发给mc,让mc去更新ms中的数据。

假设今后我们的数据库可以和ms进行通讯了,那可以将更新的任务统一交给db层,每次数据库更新数据的同时会自动去更新ms中的数据,这样就可以进一步减少app层的逻辑复杂度。如下图:

不过每次我们如果没有从cache读到数据,都不得不麻烦数据库。为了最小化数据库的负载压力,我们可以部署数据库复写,用slave数据库来完成读取操作,而master数据库永远只负责三件事:1.更新数据;2.同步slave数据库;3.更新cache。如下图:

以上这些缓存式web架构在实际应用中被证明是能有效并能极大地降低数据库的负载同时又能提高web的运行性能。当然这些架构还可以根据具体的应用环境进行变种,以达到不同硬件条件下性能的最优化。

未来的憧憬
Memcached的出现可以说是革命性的,第一次让我们意识到可以用内存作为存储媒介来大规模的缓存数据以提高程序的性能。不过它毕竟还是比较新的东西,还需要很多有待优化和改进的地方,例如:
如何利用memcached实现cache数据库,让数据库跑在内存上。这方面,tangent software 开发的memcached_engine[3]已经做了不少工作,不过现在的版本还只是处于实验室阶段。
如何能方便有效的进行批量key清理。因为现在key是散列在不同的server上的,所以对某类key进行大批量清理是很麻烦的。因为memcached本身是一个大hash表,是不具备key的检索功能的。所以memcached是压根不知道某一类的key到底存了多少个,都存在哪些server上。而这类功能在实际应用中却是经常用到。

交流
作者也是刚接触memcached方面的内容,所以严格来说还只是个新手,班门弄斧地说了一大通,如果有不对的地方,还请各位大侠多多指正。当然,如果有什么和memcached方面有关的问题或建议,也欢迎和我联系。
联系Email: rongwei.yang@dianping.com

参考
[1]. Memcached website: http://danga.com/memcached/
[2]. Memcached API Page: http://danga.com/memcached/apis.bml
[3]. memcached_engine: http://tangent.org/506/memcache_engine.html

memcache简要安装步骤

1、  安装文件准备

1)、Memcache的服务器端程序:当前最新版本号为

  下载地址:http://www.danga.com/memcached/

2)、Memcache的安装先决条件:先安装libevent,当前最新版本号为

  Libevent介绍:libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名的用于apache的php缓存库memcached据说也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。

  下载地址:http://download.chinaunix.net/download/0006000/5804.shtml

 

2、  操作系统要求

鉴于我们线上环境和线下的要保持一致,我们都将采用linux。具体的版本号为:

Redhat advance server4 v4,可以使用更高版本(更高版本未经测试)

如果是redhat advance server4 v2 ,请保证gcc编译器可以使用,或者升级到v4然后安装gcc编译器。一般升级的方式都是从光盘启动升级过程,升级后安装gcc编译器。默认的v2版本没有安装gcc编译器。

3、  编译器要求

Memcache的安装文件是要求我们安装gcc编译器的。否则我们的libevent和memcache都无法安装。

检查是否有gcc编译器的命令:gcc –v

如果系统的gcc编译器可以用,将会有一段描述,否则提示找不到类库。

成功的例如:

Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.6/specs

Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux

Thread model: posix

gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

4、  安装

 先安装libevent,然后才能安装memcache

 1)、libevent安装

//先解压缩

[root@localhost]#tar -zxvf  libevent-1.4.8-stable.tar.gz

//切换到libevent的目录中

[root@localhost]#cd  libevent-1.4.8-stable

//指定安装路径到/usr/目录下
[root@localhost]#./configure --prefix=/usr/

//编译

[root@localhost]#make

//安装

[root@localhost]#.make install

 

 

 2)、memcache服务器安装

//先解压缩memcached-1.2.6.tar.gz

[root@localhost]#tar -zxvf  memcached-1.2.6.tar.gz

//切换到memcache的目录中

[root@localhost]#cd  memcached-1.2.6

//指定安装路径到/usr/local/server/memcache目录下,同时指定libevent的安装位置
[root@localhost]# ./configure --prefix=/usr/local/memcached --with-libevent=/usr/

//编译

[root@localhost]#make

//安装

[root@localhost]#.make install

 测试每步是否安装成功:

   测试libevent:

   [root@localhost]# ls /usr/lib |grep libevent

libevent-1.4.so.2

libevent-1.4.so.2.1.1

libevent.a

libevent.la

libevent.so

libevent_core-1.4.so.2

libevent_core-1.4.so.2.1.1

libevent_core.a

libevent_core.la

libevent_core.so

libevent_extra-1.4.so.2

libevent_extra-1.4.so.2.1.1

libevent_extra.a

libevent_extra.la

libevent_extra.so

  测试memcache:

[root@localhost]# ls -al /usr/local/memcached/bin

total 264

drwxr-xr-x  2 root root   4096 Sep 19 15:31 .

drwxr-xr-x  4 root root   4096 Sep 19 15:31 ..

-rwxr-xr-x  1 root root 120949 Sep 19 15:31 memcached

-rwxr-xr-x  1 root root 129947 Sep 19 15:31 memcached-debug

5、  启动memcache

1)、启动Memcache的服务器端:

[root@localhost]# /usr/local/bin/memcached -d -m 100 -u root -l 192.168.36.200 -p 11211 -c 256 -P /tmp/memcached.pid 

# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
    -d选项是启动一个守护进程,
    -m是分配给Memcache使用的内存数量,单位是MB,我这里是100MB,
    -u是运行Memcache的用户,我这里是root,
    -l是监听的服务器IP地址,如果有多个地址的话,我这里指定了服务器的IP地址192.168.36.200,
    -p是设置Memcache监听的端口,我这里设置了11211,最好是1024以上的端口,我们这里统一使用11211
    -c选项是最大运行的并发连接数,默认是1024,我这里设置了256,按照你服务器的负载量来设定。
    -P是设置保存Memcache的pid文件,我这里是保存在/tmp/memcached.pid,

2)、如果要结束Memcache进程,执行:

[root@localhost]# kill cat /tmp/memcached.pid

6、  监测是否启动成功方式

我们可以使用telnet来对我们的memcache服务器进行访问

例如:telnet 192.168.36.199 11211 (访问的是192.168.36.199这个ip的11211端口)

连接上后,直接敲击stats命令看当前缓存服务器状态

7、  设定memcache的telnet访问限制

请限定telnet的访问,使之只能在中转机上访问

8、  memcache的常见概念

memcached会预先分配内存,memcached分配内存方式称之为allocator,首先,这里有3个概念:
1 slab
2 page
3 chunk
解释一下,一般来说一个memcahced进程会预先将自己划分为若干个slab,每个slab下又有若干个page,每个page下又有多个chunk,如果我们把这3个咚咚看作是object得话,这是两个一对多得关系。再一般来说,slab得数量是有限得,几个,十几个,或者几十个,这个跟进程配置得内存有关。而每个slab下得page默认情况是1m,也就是说如果一个slab占用100m得内存得话,那么默认情况下这个slab所拥有得page得个数就是100,而chunk就是我们得数据存放得最终地方。

9、  Memcache的常用命令

 Memcache常见的命令都在协议文件上:安装文件的的doc目录下的protocol.txt文件中有详细说明

 1)、查询状态命令:stats:

    Name              Type     Meaning

----------------------------------

pid               32u      Process id of this server process

uptime            32u      Number of seconds this server has been running

time              32u      current UNIX time according to the server

version           string   Version string of this server

pointer_size      32       Default size of pointers on the host OS

                           (generally 32 or 64)

rusage_user       32u:32u  Accumulated user time for this process

                           (seconds:microseconds)

rusage_system     32u:32u  Accumulated system time for this process

                           (seconds:microseconds)

curr_items        32u      Current number of items stored by the server

total_items       32u      Total number of items stored by this server

                           ever since it started

bytes             64u      Current number of bytes used by this server

                           to store items

curr_connections  32u      Number of open connections

total_connections 32u      Total number of connections opened since

                           the server started running

connection_structures 32u  Number of connection structures allocated

                           by the server

cmd_get           64u      Cumulative number of retrieval requests

cmd_set           64u      Cumulative number of storage requests

get_hits          64u      Number of keys that have been requested and

                           found present

get_misses        64u      Number of items that have been requested

                           and not found

evictions         64u      Number of valid items removed from cache                                                                          

                           to free memory for new items                                                                                      

bytes_read        64u      Total number of bytes read by this server

                           from network

bytes_written     64u      Total number of bytes sent by this server to

                           network

limit_maxbytes    32u      Number of bytes this server is allowed to

                           use for storage.

threads           32u      Number of worker threads requested.

                           (see doc/threads.txt)

2)、查询版本号 version

3)、退出命令 quit

4)、显示各个slab的信息,包括chunk的大小、数目、使用情况等:stats slabs5)、显示各个slab中item的数目和最老item的年龄(最后一次访问距离现在的秒数):stats items
6)、显示内存分配:stats malloc

7)、清空缓存数据(其实是将所有缓存数据标记为过期):flush_all