之前在网上看过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】

关于Memcache mutex设计模式的.net实现的更多相关文章

  1. Memcache mutex设计模式

    Memcache mutex设计模式 转自:https://timyang.net/programming/memcache-mutex/ 场景 Mutex主要用于有大量并发访问并存在cache过期的 ...

  2. Memcache的mutex设计模式 -- 高并发解决方案

    场景 Mutex主要用于有大量并发访问并存在cache过期的场合,如 首页top 10, 由数据库加载到memcache缓存n分钟: 微博中名人的content cache, 一旦不存在会大量请求不能 ...

  3. Web开发基本准则-55实录-缓存策略

    续上篇<Web开发基本准则-55实录-Web访问安全>. Web开发基本准则-55实录-缓存策略 郑昀 创建于2013年2月 郑昀 最后更新于2013年10月26日 提纲: Web访问安全 ...

  4. 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类

    1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...

  5. [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)

    如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html   谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...

  6. php 设计模式

    一.工厂模式 1.创建接口类,规范方法,要实现这个接口的类必须实现这个接口的所有方法,接口的方法默认是抽象的,所以不再方法前面加 abstract interface people{ public f ...

  7. C#设计模式-单例模式

    单例模式三种写法: 第一种最简单,但没有考虑线程安全,在多线程时可能会出问题…… public class Singleton { private static Singleton _instance ...

  8. go sync.Mutex 设计思想与演化过程 (一)

    go语言在云计算时代将会如日中天,还抱着.NET不放的人将会被淘汰.学习go语言和.NET完全不一样,它有非常简单的runtime 和 类库.最好的办法就是将整个源代码读一遍,这是我见过最简洁的系统类 ...

  9. memcache 缓存失效问题(转)

    在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险. 解决方法 方法一 在load db之前先add一个mutex ...

随机推荐

  1. java实现.net中的枚举

    Java 和 .net中的枚举不一样,在.net中,枚举是属于值类型的,而在java中确实引用类型的(其实就是一个特殊的类,enum默认集成java.lang.Enum类),所以在java中操作枚举类 ...

  2. 泛形集合List<T>

    public class Person { /// <summary> /// 姓名 /// </summary> private string name; public st ...

  3. NSInvocation的使用(转)

    转载自:http://www.cnblogs.com/pengyingh/articles/2359199.html http://blog.iosxcode4.com/?p=125 在 iOS中可以 ...

  4. 硬盘4k对齐教程总结

    4k对齐概念: 4K对齐相关联的是一个叫做“高级格式化”的分区技术.首先先来了解一下什么是叫做“4K 对齐”.其实“4K对齐”相关联的是一个叫做“高级格式化”的分区技术.“高级格式化”是国际硬盘设备与 ...

  5. 【BZOJ 1821】 [JSOI2010]Group 部落划分 Group

    Description 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗.只是,这一切都成 ...

  6. Android导入Cocos2D的Sample项目

    导入Cocos2D项目到Android的Eclipse时注意以下几点 1. Set up Variables: Eclipse->Windows->Preferences->Gene ...

  7. js解决checkbox全选和反选的问题

    function SelectAll() { var checkboxs=document.getElementsByName("chk_list"); for (var i=0; ...

  8. PAT-乙级-1045. 快速排序(25)

    1045. 快速排序(25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CAO, Peng 著名的快速排序算法里有一个经典的划分 ...

  9. POJ2526+简单几何

    题意:给定的这些点是否有一个对称中心. PS:我写得有点啰嗦.. 就是把小的x和大的x进行匹配. #include<stdio.h> #include<algorithm> # ...

  10. SaaS系列介绍之十: SaaS的商业模式

    1 引言 赚钱之道很多,但是找不到赚钱的种子,便成不了事业家.作为职业软件人,我们都寻求使用一种有效而经济的过程来建造一个能够工作的,有用的产品.                            ...