码迷,mamicode.com
首页 > 其他好文 > 详细

memcached的剖析

时间:2014-08-09 18:29:48      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   color   使用   os   io   

如何安装memcache就让给度娘了,我们先看看memcached的一些基本工作机制。

应用背景:

Web应用将数据保存到关系型数据库中,应用服务器从数据库中检索记录后返回浏览器。一旦数据太多,就会出现数据库服务器负载过大,最终当机。
当其中有些数据满足一下条件:
  • 被客户端访问频率非常高
  • 更新频率一般
则可以利用高性能的分布式内存缓存服务器memcached,通过缓存数据库查询结果(原子操作),减少数据库访问次数,以提高动态Web应用的速度。
工作流程如下(网上找来的图):
bubuko.com,布布扣
通讯方法及操作说明:
 
通过telnet可以连接到memcached服务器,
$ telnet localhost 11211

通过set,get方法就可以进行最基本的键值对操作了:

set foo 0 0 3
bar
STORED
get foo
VALUE foo 0 3
bar
END

存储数据的命令格式:

command <key> <flags> <expiration time> <bytes>
<value>

参数用法
key key 用于查找缓存值,本文中使用foo
flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远),本文使用0,希望一直保存,直到手动将其删除。
bytes 在缓存中存储的字节点
value 存储的值(始终位于第二行),本文中设置为bar

如果使用 set 命令正确设定了键值对,服务器将使用单词 STORED 进行响应。

其他的一些命令雷同:

  • add: 仅当缓存中不存在键时,add 命令才会向缓存中添加一个键值对。如果缓存中已经存在键,则之前的值将仍然保持相同,并且您将获得响应NOT_STORED
  • replace: 仅当键已经存在时,replace 命令才会替换缓存中的键。如果缓存中不存在键,那么您将从 memcached 服务器接受到一条 NOT_STORED 响应。
  • get: 用于检索与之前添加的键值对相关的值。您将使用 get 执行大多数检索操作。
  • delete: 用于删除 memcached 中的任何现有值。您将使用一个键调用delete,如果该键存在于缓存中,则删除该值。如果不存在,则返回一条NOT_FOUND 消息。
  • gets: 功能类似于基本的 get 命令。两个命令之间的差异在于,gets 返回的信息稍微多一些:64 位的整型值非常像名称/值对的 “版本” 标识符。
  • cas: (check 和 set)是一个非常便捷的 memcached 命令,用于设置名称/值对的值(如果该名称/值对在您上次执行 gets 后没有更新过)。它使用与 set命令相类似的语法,但包括一个额外的值:gets 返回的额外值。

 BTW,cas的功能就好比CVS文件版本控制中不能跳版更新文件一样,必须在得到最新更新情况后,即得知最新的flag,再更新进去,非常好用。

两个 memcached 命令用于监控和清理 memcached 实例。它们是 stats 和 flush_all 命令。

stats就是列出服务器的存储状态,flush_all就是清除所有键值对。

以上就是基本操作,接下来说说PHP上如何使用memcached。

有两种方法可以使 PHP 作为 memcached 客户端,调用 memcached 的服务进行对象存取操作。

第一种,PHP 有一个叫做memcached扩展,Linux 下编译时需要带上 –enable-memcache[=DIR] 选项,Window 下则在 php.ini 中去掉 php_memcache.dll 前边的注释符,使其可用。

除此之外,还有一种方法,可以避开扩展、重新编译所带来的麻烦,那就是直接使用php-memcached-client

本文选用第二种方式,虽然效率会比扩展库稍差一些,但问题不大。

<?php
    header("content-type:text/html; charset=utf-8");
    require_once("memcached-client.php");
    $options = array(
        ‘servers‘ => array(‘127.0.0.1:11211‘), //memcached 服务的地址、端口,可用多个数组元素表示多个 memcached 服务 
        ‘debug‘ => false, //是否打开 debug 来打印出调试字符串
        ‘compress_threshold‘ => 10240, //超过多少字节进行压缩
        ‘persistant‘ => false    //是否使用持久连接 
        );
    $mc = new memcached($options);
    $key = ‘a‘;

    flush_all($options);

    $mc->add($key, ‘kJohn‘);
    //$mc->replace($key,"Mike");
    $val = $mc->get($key);
    echo $val;

function flush_all($options){
    list($host,$port) = explode(":",$options["servers"][0]);
    $cmd = "flush_all\n";
    $timeout = 0.25;
    $socket = @fsockopen($host, $port, $errno, $errstr, $timeout);
          // Do not buffer writes
    stream_set_write_buffer($socket, 0);
    fwrite($socket, $cmd, strlen($cmd));
    //$res = trim(fgets($socket));
    //echo "$res!";
}
?

关于memcached-client.php用法,网上有很多,也非常简单,这里就不多作介绍了。

因为在memcached-client里找不到清空命令,网上也有说用其自带的run_command($sock,$cmd)方法,仔细分析过php-memcached-client的源代码后发现,

在memcache上执行flush_all,是可以用fsockopen的方法自定义了一个socket来写入"flush_all\n",达到清空键值对的目的。

如果是一些有数据返回的操作,则可以用fgets($socket)来获得返回信息。

BTW,有兴趣的同学可以把这个function扩充到php-memcached-client源代码里去。

在实际应用中,通常会把数据库查询的结果集保存到 memcached 中,下次访问时直接从 memcached 中获取,而不再做数据库查询操作,这样可以在很大程度上减轻数据库的负担。通常会将 SQL 语句 md5() 之后的值作为唯一标识符 key。

<?php 
$sql = ‘SELECT * FROM users‘; 
$key = md5($sql); //memcached 对象标识符 
if ( !($datas = $mc->get($key)) ) { 
  // 在 memcached 中未获取到缓存数据,则使用数据库查询获取记录集。 
  echo "n".str_pad(‘Read datas from MySQL.‘, 60, ‘_‘)."n"; 
  $conn = mysql_connect(‘localhost‘, ‘test‘, ‘test‘); 
  mysql_select_db(‘test‘); 
  $result = mysql_query($sql); 
  while ($row = mysql_fetch_object($result)){ 
    $datas[] = $row; 
    // 将数据库中获取到的结果集数据保存到 memcached 中,以供下次访问时使用。 
    $mc->add($key, $datas);
  } }
else {   echo "n".str_pad(‘Read datas from memcached.‘, 60, ‘_‘)."n"; } var_dump($datas); ?>

 

memcached的剖析,布布扣,bubuko.com

memcached的剖析

标签:des   style   blog   http   color   使用   os   io   

原文地址:http://www.cnblogs.com/angular/p/3900787.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!