设为首页 收藏本站
查看: 677|回复: 0

[经验分享] 缓存篇~第七回 Redis实现基于方法签名的数据集缓存(可控更新,分布式数据缓存)

[复制链接]

尚未签到

发表于 2015-7-21 12:10:05 | 显示全部楼层 |阅读模式
  返回目录
  本篇文章可以说是第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存(可控更新,WEB端数据缓存)的续篇,事实上,有EnterpriseLibrary.Caching也只是实现缓存持久化的一种方式,而Redis做为成熟的分布式存储中间件来说,实现这个数据集缓存功能显得更加得心应手,也更加满足大型网站的设计规则。(在多web服务器时(web端实现负载均衡,反向代理),EnterpriseLibrary.Caching显得没什么作为,而这时,分布式缓存就可以一显身手了,它可以很轻松的将缓存服务器部署到第三方服务器上,解决了上面的问题)
  一个标准,多种实现,面向对象的真谛:多态性,如果你问我接口有什么用,那么本篇文章可以告诉你答案:根据不同的场合,使用不同的持久化方式去存储数据。
  下面是缓存标准接口ICacheProvider



///
/// 表示实现该接口的类型是能够为应用程序提供缓存机制的类型。
/// 这可以有多种实现机制
///
public interface ICacheProvider
{
#region Methods
///
/// 向缓存中添加一个对象。
///
/// 缓存的键值,该值通常是使用缓存机制的方法的名称。
/// 缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。
/// 需要缓存的对象。
void Add(string key, string valKey, object value);
///
/// 向缓存中更新一个对象。
///
/// 缓存的键值,该值通常是使用缓存机制的方法的名称。
/// 缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。
/// 需要缓存的对象。
void Put(string key, string valKey, object value);
///
/// 从缓存中读取对象。
///
/// 缓存的键值,该值通常是使用缓存机制的方法的名称。
/// 缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。
/// 被缓存的对象。
object Get(string key, string valKey);
///
/// 从缓存中移除对象。
///
/// 缓存的键值,该值通常是使用缓存机制的方法的名称。
void Remove(string key);
///
/// 获取一个值,该值表示拥有指定键值的缓存是否存在。
///
/// 指定的键值。
/// 如果缓存存在,则返回true,否则返回false。
bool Exists(string key);
///
/// 获取一个值,该值表示拥有指定键值和缓存值键的缓存是否存在。
///
/// 指定的键值。
/// 缓存值键。
/// 如果缓存存在,则返回true,否则返回false。
bool Exists(string key, string valKey);
#endregion
}
  而这次我们使用Redis来作为实现持久化的方式,看一个RedisCacheProvider代码,它为了兼容性,将Dictionary类型改为了Dictionary类型,这种设计避免了很多错误,因为我们知道,数据在发送时,它会被序列化,而兼容性,
  安全性,性能等最佳的方式就是二进制的方式,所以,我们使用它来对数据进行存储。



    ///
///使用redis方式进行缓存持久化
///
internal class RedisCacheProvider : ICacheProvider, IDisposable
{
private readonly IRedisClient _cacheManager = Redis.Client.RedisManager.GetClient();
static byte[] Serialize(object data)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream rems = new MemoryStream();
formatter.Serialize(rems, data);
return rems.GetBuffer();
}
static object Deserialize(byte[] data)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream rems = new MemoryStream(data);
data = null;
return formatter.Deserialize(rems);
}
public void Add(string key, string valKey, object value)
{
byte[] byteValue = Serialize(value);
using (var tbl = _cacheManager.GetTypedClient())
{
Dictionary dict = null;
if (tbl.ContainsKey(key))
{
dict = (Dictionary)tbl.Lists[key][0];
dict[valKey] = byteValue;
}
else
{
dict = new Dictionary();
dict.Add(valKey, byteValue);
}
Remove(key);
tbl.Lists[key].Add(dict);
}
}
public void Put(string key, string valKey, object value)
{
Add(key, valKey, value);
}
public object Get(string key, string valKey)
{
using (var tbl = _cacheManager.GetTypedClient())
{
if (tbl.ContainsKey(key))
{
Dictionary dict = (Dictionary)tbl.Lists[key][0];
if (dict != null && dict.ContainsKey(valKey))
return Deserialize(dict[valKey]);
else
return null;
}
}
return null;
}
public void Remove(string key)
{
using (var tbl = _cacheManager.GetTypedClient())
{
tbl.Lists[key].RemoveAll();
}
}
public bool Exists(string key)
{
using (var tbl = _cacheManager.GetTypedClient())
{
return tbl.ContainsKey(key);
}
}
public bool Exists(string key, string valKey)
{
using (var tbl = _cacheManager.GetTypedClient())
{
return tbl.ContainsKey(key) &&
((System.Collections.Generic.Dictionary)tbl.Lists[key][0]).ContainsKey(valKey);
}
}
public void Dispose()
{
_cacheManager.Dispose();
}
}
  事实上,写到这里,我们的redis方法签名存储就完成了,配合上一篇文章,你可以设计出自己的缓存系统了,在这里再多说一句,本缓存系统用到的设计模式类似于策略模式,它对于一个完善功能,可以多种实现的策略,而对外只公开一个标准的对象,其它具体
  的,完整功能的实现都使用了internal作为修饰符,来对外界隐藏。
  返回目录

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-89062-1-1.html 上篇帖子: redis ltrim命令 下篇帖子: Redis学习笔记~实现消息队列比MSMQ更方便
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表