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%           
        );
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值