设为首页 收藏本站
查看: 1515|回复: 0

[经验分享] 对memcache分布式的一点理解

[复制链接]

尚未签到

发表于 2015-8-31 07:58:02 | 显示全部楼层 |阅读模式
  pecl的memcache扩展(注意,不是memcache的扩展,两者不同)中连接memcache服务器有两种方式:
  1.短连接(Memcache::connect)
  使用方法 Memcache::connect()打开的连接在脚本执行结束后会自动关闭。当然,你也可以使用方法  Memcache::close()来主动关闭
  2.长连接(Memcache::connect)
  这个连接不会在脚本执行结束后或者Memcache::close()被调用后关闭,持久化连接仅仅会在web服务器关机/重启时关闭 。
  

  memcache的分布式是通过 Memcache::addServer这个方法实现的,下面在windows下测试memcache的分布式实现
  1.在命令行启动两个memcache服务器,分别监听11211和11212端口:


memcached.exe -p 11211 start
  memcached.exe -p 11212 start
  

  2.将以下php代码保存到localhost/index.php,用浏览器浏览一次index.php
  <?php


    function createCache()
    {
        $arr=array(  
            array("host"=>"127.0.0.1","port"=>11211,"weight"=>20), //
127.0.0.1:11211的权重是20%
            array("host"=>"127.0.0.1","port"=>11212,"weight"=>80),
//
127.0.0.1:11212的权重是80%
        );
        $cache=new memcache;
        foreach ($arr as $ele )
        {
    //使用长连接,并且设置不同memcache服务器的权重,将memcache服务器添加到连接池
            $cache->addServer($ele["host"],$ele["port"],true,$ele["weight"]);            
        }
        return $cache;
    }
    $cache = createCache ();
    for($i=0;$i<10;$i++)
    {
//由于使用了分布式,所以这里不需要使用connect或者pconnect打开链接,set方法会调用memcache的分布式缓存分配算法,按照权重将缓存项缓存到连接池的某个服务器
        if($cache->set($i,$i,0,3600))
        {
            echo "缓存成功,key:$i,value:$i";
        }else
        {
            echo "缓存失败";
        }
        echo "<br/>";
    }
?>  
  3.再开启两个cmd窗口,分别输入如下内容:


//第一个窗口
telnet 127.0.0.1 11211   //先登入memcache服务器
stats  //查看服务器当前状态
  结果如下图所示:
DSC0000.jpg
  
  //第二个窗口
telnet 127.0.0.1 11212   //先登入memcache服务器
stats  //查看服务器当前状态
结果如下图所示:
DSC0001.jpg

  
根据上面的测试情况,发现
1.两个memcache服务器当前连接数(curr_connections)都是2,这是因为


$cache->addServer($ele["host"],$ele["port"],true,$ele["weight"])  第三个参数指定使用长连接,所以每个memcache服务器保存了两个连接:一个是php里的长连接,一个是telnet登陆的连接(如果不信,我们多刷新几次
index.php这个页面,再调用stats命令,发现两台memcache服务器的
curr_connections还是2)
  2.127.0.0.1:11211的current_items为4,

127.0.0.1:11212的current_items为6,这说明十个缓存项有4个存到了第一台服务器,有6个存到了第二胎服务器,虽然与20%和80%的权重不符,但是相信缓存项越多,越趋近这个权重。  
  
  
  在多做几次实验还会发现:
  (1).将127.0.0.1:11211和

127.0.0.1:11212两台memcache服务器都关掉,再打开
127.0.0.1:11211,然后访问index.php,页面输出如下内容:
DSC0002.jpg
  
  在命令行 telnet 127.0.0.1 11211 再stats,得到如下结果:
DSC0003.jpg
  通过上面的结果我们得出结论, 当一个memcache连接池的某个服务器down掉以后,通过memcache分布式缓存分配算法分配到down掉的服务器的缓存不会被丢弃,而是会存储到另外的服务器上。
  再编写一个存储到localhost/get.php的get.php ,内容如下:
  <?php


function createCache() {
    $arr = array (array ("host" => "127.0.0.1", "port" => 11211, "weight" => 20 ), array ("host" => "127.0.0.1", "port" => 11212, "weight" => 80 ) );
    $cache = new memcache ();
    foreach ( $arr as $ele ) {
        $cache->addServer ( $ele ["host"], $ele ["port"], true, $ele ["weight"], 1 );
    }
    return $cache;
}
$cache = createCache ();
$val;
for($i = 0; $i < 10; $i ++) {
    $val = $cache->get ( $i );
    if (false === $val) {
        echo "缓存获取失败";
    } else {
        echo "缓存获取成功:,key:$val,value:$val";
    }
    echo "<br/>";
}
$cache->close ();
?>  访问localhost/get.php,内容输出如下:
DSC0004.jpg

  我们发现php程序尝试去连接127.0.0.1:11212发现其不在线后又去127.0.0.1:11211找到了对应的缓存项,这和设置缓存时分布式缓存分配算法的表现是一致的
  奇怪的是接着打开127.0.0.1:11212这个memcache服务器后再访问localhost/get.php,输出内容如下:
DSC0005.jpg
为什么明明缓存在127.0.0.1:11211都存在,却有6个缓存项显示找不到缓存呢?我觉得是这样的:当通过$cache->get获取缓存的时候,分布式缓存分配算法推算出6个缓存项是存储在127.0.0.1:11212这个memcache服务器上的,接着发现127.0.0.1:11212这个memcache服务器是在线的,所以即使没有找到对应的缓存也不会像上一步一样去127.0.0.1:11211寻找缓存
(2)假设127.0.0.1:11211和127.0.0.1:11212都已经开启 当我们将  $cache->addServer($ele["host"],$ele["port"],true,$ele["weight"]);   
  改为   


$cache->addServer($ele["host"],$ele["port"],false,$ele["weight"]);  后
  发现无论刷新多少次localhost/index.php和localhost/get.php,stats 127.0.0.1:11211和127.0.0.1:11212会看到curr_connections总为1,这是因为使用短连接后每一次页面脚本执行完毕都会关掉连接,所以两个memcache服务器都只有telnet一个连接在线。

  

  (3) 加入set和get的memcache服务器连接池的连接一样但是顺序不一样,会发现get缓存的时候明明set的所有缓存项都存入了对应的memcache服务器但是很多缓存项就是取不到,既set的时候使用如下连接池:


$arr=array(  
            array("host"=>"127.0.0.1","port"=>11211,"weight"=>20), //127.0.0.1:11211的权重是20%
            array("host"=>"127.0.0.1","port"=>11212,"weight"=>80), //127.0.0.1:11212的权重是80%
        );get的时候使用如下连接池:

$arr=array(              
           array("host"=>"127.0.0.1","port"=>11212,"weight"=>80), //127.0.0.1:11212的权重是80%     
           array("host"=>"127.0.0.1","port"=>11211,"weight"=>20)//127.0.0.1:11211的权重是20%                   );
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106515-1-1.html 上篇帖子: memcache源码分析之命名空间stats 下篇帖子: CentOS6.2+Nginx1.1.12+PHP5.3.10+Redis2.4.5+Memcache及相关扩展安装脚本
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表