关于Memcache mutex设计模式的.net实现
原文链接:http://timyang.net/programming/memcache-mutex/
为了实现原文中的对象到期时间属性,定义了一个基类,其信息如下:
[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实现的更多相关文章
- Memcache mutex设计模式
Memcache mutex设计模式 转自:https://timyang.net/programming/memcache-mutex/ 场景 Mutex主要用于有大量并发访问并存在cache过期的 ...
- Memcache的mutex设计模式 -- 高并发解决方案
场景 Mutex主要用于有大量并发访问并存在cache过期的场合,如 首页top 10, 由数据库加载到memcache缓存n分钟: 微博中名人的content cache, 一旦不存在会大量请求不能 ...
- Web开发基本准则-55实录-缓存策略
续上篇<Web开发基本准则-55实录-Web访问安全>. Web开发基本准则-55实录-缓存策略 郑昀 创建于2013年2月 郑昀 最后更新于2013年10月26日 提纲: Web访问安全 ...
- 设计模式之PHP项目应用——单例模式设计Memcache和Redis操作类
1 单例模式简单介绍 单例模式是一种经常使用的软件设计模式. 在它的核心结构中仅仅包括一个被称为单例类的特殊类. 通过单例模式能够保证系统中一个类仅仅有一个实例并且该实例易于外界訪问.从而方便对实例个 ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- php 设计模式
一.工厂模式 1.创建接口类,规范方法,要实现这个接口的类必须实现这个接口的所有方法,接口的方法默认是抽象的,所以不再方法前面加 abstract interface people{ public f ...
- C#设计模式-单例模式
单例模式三种写法: 第一种最简单,但没有考虑线程安全,在多线程时可能会出问题…… public class Singleton { private static Singleton _instance ...
- go sync.Mutex 设计思想与演化过程 (一)
go语言在云计算时代将会如日中天,还抱着.NET不放的人将会被淘汰.学习go语言和.NET完全不一样,它有非常简单的runtime 和 类库.最好的办法就是将整个源代码读一遍,这是我见过最简洁的系统类 ...
- memcache 缓存失效问题(转)
在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险. 解决方法 方法一 在load db之前先add一个mutex ...
随机推荐
- Oracle分析函数 — rank, dense_rank, row_number用法
本文通过例子演示了Oracle分析函数 —— rank, dense_rank, row_number的用法. //首先建score表 create table score( course nva ...
- C#网络编程简单实现通信小例子-2
1.主界面 2.源代码 Client public partial class For ...
- JS禁用浏览器退格键
我们在真实的项目开发中经常会使用JS 对键盘上的一些按键进行禁用,常见的比如说退格键(backspace/ 后退键),我在一个项目中就遇到过在页面编辑的时候禁用掉退格键,因为退格键会发生页面后退,代码 ...
- iOS开发学习路线图
很多初学iOS开发的人会经常问:“我想学iOS应该从何入手呢?”.作为一个做了2年多各种iOS开发的程序员,只想写写自己的一些心得体会,好和体验与不好的体验.写的不好,请多包涵.希望能起到抛砖引玉的作 ...
- easyui 多行文本框 Multiline TextBox
<input class="easyui-textbox" data-options="multiline:true" value="This ...
- 去除C/C++程序代码中的注释
最近搞软件著作权,去除代码空行和注释比较麻烦,想写个程序自动去除,去网上搜了下,发现有类似的程序,不过只有去除注释.鉴于word中可以去除空行(用^p^p替换^p),先用网上的代码,以后有时间写个完整 ...
- iOS sqlite 增删改查 简单封装(基于 FMDB)
/** * 对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * * 基于 FMDB * * 操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整 ...
- 【莫比乌斯反演】关于Mobius反演与gcd的一些关系与问题简化(bzoj 2301 Problem b&&bzoj 2820 YY的GCD&&BZOJ 3529 数表)
首先我们来看一道题 BZOJ 2301 Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd( ...
- 团体程序设计天梯赛-练习集L1-002. 打印沙漏
L1-002. 打印沙漏 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给 ...
- unity3d与eclipse协同工作环境
原地址:http://bbs.9ria.com/thread-212576-1-1.html 这个过程非常复杂.步骤一定要谨记 1,建立一个unity3d工程,然后自己丢点模型进去吧.然后设置导出时候 ...