• 对memcache分布式的一点理解


    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   //查看服务器当前状态

    结果如下图所示:
     

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


    根据上面的测试情况,发现
    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,页面输出如下内容:

     在命令行 telnet 127.0.0.1 11211 再stats,得到如下结果:

     

    通过上面的结果我们得出结论, 当一个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,内容输出如下:

      我们发现php程序尝试去连接127.0.0.1:11212发现其不在线后又去127.0.0.1:11211找到了对应的缓存项,这和设置缓存时分布式缓存分配算法的表现是一致的
      奇怪的是接着打开127.0.0.1:11212这个memcache服务器后再访问localhost/get.php,输出内容如下:

    为什么明明缓存在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%          
            );

  • 相关阅读:
    XML验证框架在项目中的应用
    Container.DataItem几种方式.
    XMLSpy 的使用
    介绍一个工具给大家,做网站时,经常要上传文件到外网服务器,但是上传时往往需要很长时间,如果有一个文件对比工具……
    Xcopy 帮助.net 2005组件化开发
    不影响原有的onload方法的前提下,在页面中增加onload的执行方法
    如何将XSD文件以及引入import的文件生成相应的C#类。
    封装my97时间控件成asp.net 时间控件,支持多语言,皮肤,时间大小限制,时间格式验证功能,非常强大。
    参数化使用ADO.NET的OleDb方法时注意不能使用@参数
    提供一个通用的Javascript验证页面输入的脚本给大家,并希望大家提意见呀
  • 原文地址:https://www.cnblogs.com/mxw09/p/2141457.html
Copyright © 2020-2023  润新知