关于Memcache mutex设计模式的.net实现

关于Memcache mutex设计模式的.net实现 收藏

此文于2011-02-22被推荐到CSDN首页
如何被推荐?

     之前在网上看过memcache-mutex的场景分析和实现代码,这里将.net方式加以实现,当然这里主要是依据原文的伪代码照猫画虎,以此做为总结 及记录。如果您对相应实现感兴趣可以尝试使用本文提供的代码进行测试,如果有问题请及时与我联系。   

     原文链接:http://timyang.net/programming/memcache-mutex/

     本地链接:http://www.cnblogs.com/daizhj/articles/1959704.html

     为了实现原文中的对象到期时间属性,定义了一个基类,其信息如下:

[Serializable]
public   class  CacheObj
{
        
///   <summary>
        
///  数据绝 对到期时间,默认为当前时间开始三分钟后失效
        
///   </summary>
         public  DateTime ExpireTime  =  DateTime.Now.AddMinutes( 3 );      

        
///   <summary>
        
///  数据相 对有效时间,单位:秒。默认为30秒有效期
        
///   </summary>
         public   int  TimeOut  =   30 ;
}

     这样所有要放到memcached的对象只要继承该对象就OK了,比如下面的用户信息类:


///   <summary>
///  用户信息
///   </summary>
[Serializable]
public   class  UserInfo : CacheObj
{
        
public   string  UserName;
        
public   int  Age;
        
public   string  Email;

        
public   override   string  ToString()
        {
            
return   " UserName: "   +  UserName  +   "   Age: "   +  Age  +   "   Email: "   +  Email;
        }
}
     下面是原文中方式一的实现代码:
MemcachedClient mc  =  MemCachedManager.CacheClient;
// 方一
public  UserInfo GetCacheData1( string  key)
{
    UserInfo value 
=  mc.Get(key)  as  UserInfo;
    
if  (value  ==   null )
    {
        
//  3 分钟到期.在delete操作执行之前,当前key_mutex add只能被 添加一次并返回true
         if  (mc.Add(key  +   " _mutex " , key  +   " _mutex " , DateTime.Now.AddMinutes( 3 ))  ==   true )
        {
            value 
=   new  UserInfo() { UserName  =   " daizhj " , Email  =   " daizhj617595@126.com "  }; //  db.get(key); // 从加载数据
            mc.Set(key, value);
            mc.Delete(key 
+   " _mutex " );                    
        }
        
else
        {
            System.Threading.Thread.Sleep(
500 ); // 如果设置过短,可能上面set语法还未生效
            value  =  mc.Get(key)  as  UserInfo; // sleep之后重试读取cache数据
        }
    }
    
return  value;
}

    下面是方式2的代码:

// 方法二
public  UserInfo GetCacheData2( string  key)
{
    UserInfo value 
=  mc.Get(key)  as  UserInfo;
    
if  (value  ==   null )
    {
        
//  3 分钟到期,在delete之前,当前key_mutex add只能被添加一次 并返回true
         if  (mc.Add(key  +   " _mutex " " add_mutex " , DateTime.Now.AddMinutes( 3 ))  ==   true )
        {
            value 
=   new  UserInfo() { UserName  =   " daizhj " , Email  =   " daizhj617595@126.com "  }; //  db.get(key); // 从加载数据
            mc.Set(key, value);
            mc.Delete(key 
+   " _mutex " );
        }
        
else
        {
            System.Threading.Thread.Sleep(
500 ); // 如果设置过短,可能上面set语法还未生效
            value  =  mc.Get(key)  as  UserInfo; // sleep之后重试读取cache数据
        }
    }
    
else
    {
        
if  (value.ExpireTime  <=  DateTime.Now)
        {
            
// 有值但已过期 
             if  (mc.Add(key  +   " _mutex " " add_mutex " , DateTime.Now.AddMinutes( 3 ))  ==   true )
            {
                value.ExpireTime 
=  DateTime.Now.AddSeconds(value.TimeOut);
                
// 这只是为了让它先暂时有效(后面即将更新该过期数据),这样做主要防止避免cache失效时刻大量请求获取不到mutex并进行sleep, 注意这里设置成有效会导致其它线程会暂时读到脏数据
                mc.Set(key, value, DateTime.Now.AddSeconds(value.TimeOut  *   2 )); // 这里*2是为了让memcached缓存数据更长时间,因为真正校验到期时间用 ExpireTime来判断

                
// 从数据源加载最新数据
                value  =   new  UserInfo() { UserName  =   " daizhenjun " , Email  =   " 617595@163.com "  }; //  db.get(key);
                value.ExpireTime  =  DateTime.Now.AddSeconds(value.TimeOut);
                mc.Set(key, value, DateTime.Now.AddSeconds(value.TimeOut 
*   2 ));
                mc.Delete(key 
+   " _mutex " );
            }
            
else
            {
                System.Threading.Thread.Sleep(
500 ); // 如果设置过短,可能上面set语法还未生效
                value  =  mc.Get(key)  as  UserInfo; // sleep之后重试读取cache数据
            }
        }
    }
    
return  value;
}
      无论使用那种方式,都会带来代码复杂性增大(尤其第二种),另外还有就是与memcached额外的连接及存储开销(key _mutex本身存储也要消耗资源 )。因为除非是高并发场景下同时更新 memcached,否则这两种方式需要斟酌使用。

      源码下载地址:/Files/daizhj/MemcachedApp.rar  

      【示例位于MemcachedApp/sample/MutexSample.aspx】

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值