返回目录

本篇文章可以说是第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存(可控更新,WEB端数据缓存)的续篇,事实上,有EnterpriseLibrary.Caching也只是实现缓存持久化的一种方式,而Redis做为成熟的分布式存储中间件来说,实现这个数据集缓存功能显得更加得心应手,也更加满足大型网站的设计规则。(在多web服务器时(web端实现负载均衡,反向代理),EnterpriseLibrary.Caching显得没什么作为,而这时,分布式缓存就可以一显身手了,它可以很轻松的将缓存服务器部署到第三方服务器上,解决了上面的问题)

一个标准,多种实现,面向对象的真谛:多态性,如果你问我接口有什么用,那么本篇文章可以告诉你答案:根据不同的场合,使用不同的持久化方式去存储数据。

下面是缓存标准接口ICacheProvider

  1. /// <summary>
  2. /// 表示实现该接口的类型是能够为应用程序提供缓存机制的类型。
  3. /// 这可以有多种实现机制
  4. /// </summary>
  5. public interface ICacheProvider
  6. {
  7. #region Methods
  8. /// <summary>
  9. /// 向缓存中添加一个对象。
  10. /// </summary>
  11. /// <param name="key">缓存的键值,该值通常是使用缓存机制的方法的名称。</param>
  12. /// <param name="valKey">缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。</param>
  13. /// <param name="value">需要缓存的对象。</param>
  14. void Add(string key, string valKey, object value);
  15. /// <summary>
  16. /// 向缓存中更新一个对象。
  17. /// </summary>
  18. /// <param name="key">缓存的键值,该值通常是使用缓存机制的方法的名称。</param>
  19. /// <param name="valKey">缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。</param>
  20. /// <param name="value">需要缓存的对象。</param>
  21. void Put(string key, string valKey, object value);
  22. /// <summary>
  23. /// 从缓存中读取对象。
  24. /// </summary>
  25. /// <param name="key">缓存的键值,该值通常是使用缓存机制的方法的名称。</param>
  26. /// <param name="valKey">缓存值的键值,该值通常是由使用缓存机制的方法的参数值所产生。</param>
  27. /// <returns>被缓存的对象。</returns>
  28. object Get(string key, string valKey);
  29. /// <summary>
  30. /// 从缓存中移除对象。
  31. /// </summary>
  32. /// <param name="key">缓存的键值,该值通常是使用缓存机制的方法的名称。</param>
  33. void Remove(string key);
  34. /// <summary>
  35. /// 获取一个<see cref="Boolean"/>值,该值表示拥有指定键值的缓存是否存在。
  36. /// </summary>
  37. /// <param name="key">指定的键值。</param>
  38. /// <returns>如果缓存存在,则返回true,否则返回false。</returns>
  39. bool Exists(string key);
  40. /// <summary>
  41. /// 获取一个<see cref="Boolean"/>值,该值表示拥有指定键值和缓存值键的缓存是否存在。
  42. /// </summary>
  43. /// <param name="key">指定的键值。</param>
  44. /// <param name="valKey">缓存值键。</param>
  45. /// <returns>如果缓存存在,则返回true,否则返回false。</returns>
  46. bool Exists(string key, string valKey);
  47. #endregion
  48. }

而这次我们使用Redis来作为实现持久化的方式,看一个RedisCacheProvider代码,它为了兼容性,将Dictionary<string, object>类型改为了Dictionary<string, byte[]>类型,这种设计避免了很多错误,因为我们知道,数据在发送时,它会被序列化,而兼容性,

安全性,性能等最佳的方式就是二进制的方式,所以,我们使用它来对数据进行存储。

  1. /// <summary>
  2. ///使用redis方式进行缓存持久化
  3. /// </summary>
  4. internal class RedisCacheProvider : ICacheProvider, IDisposable
  5. {
  6. private readonly IRedisClient _cacheManager = Redis.Client.RedisManager.GetClient();
  7. static byte[] Serialize(object data)
  8. {
  9. BinaryFormatter formatter = new BinaryFormatter();
  10. MemoryStream rems = new MemoryStream();
  11. formatter.Serialize(rems, data);
  12. return rems.GetBuffer();
  13. }
  14. static object Deserialize(byte[] data)
  15. {
  16. BinaryFormatter formatter = new BinaryFormatter();
  17. MemoryStream rems = new MemoryStream(data);
  18. data = null;
  19. return formatter.Deserialize(rems);
  20. }
  21. public void Add(string key, string valKey, object value)
  22. {
  23. byte[] byteValue = Serialize(value);
  24. using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
  25. {
  26. Dictionary<string, byte[]> dict = null;
  27. if (tbl.ContainsKey(key))
  28. {
  29. dict = (Dictionary<string, byte[]>)tbl.Lists[key][];
  30. dict[valKey] = byteValue;
  31.  
  32. }
  33. else
  34. {
  35. dict = new Dictionary<string, byte[]>();
  36. dict.Add(valKey, byteValue);
  37. }
  38. Remove(key);
  39. tbl.Lists[key].Add(dict);
  40. }
  41.  
  42. }
  43.  
  44. public void Put(string key, string valKey, object value)
  45. {
  46. Add(key, valKey, value);
  47. }
  48.  
  49. public object Get(string key, string valKey)
  50. {
  51. using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
  52. {
  53. if (tbl.ContainsKey(key))
  54. {
  55. Dictionary<string, byte[]> dict = (Dictionary<string, byte[]>)tbl.Lists[key][];
  56. if (dict != null && dict.ContainsKey(valKey))
  57. return Deserialize(dict[valKey]);
  58. else
  59. return null;
  60. }
  61. }
  62. return null;
  63.  
  64. }
  65.  
  66. public void Remove(string key)
  67. {
  68. using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
  69. {
  70. tbl.Lists[key].RemoveAll();
  71. }
  72. }
  73.  
  74. public bool Exists(string key)
  75. {
  76. using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
  77. {
  78. return tbl.ContainsKey(key);
  79. }
  80. }
  81.  
  82. public bool Exists(string key, string valKey)
  83. {
  84. using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
  85. {
  86. return tbl.ContainsKey(key) &&
  87. ((System.Collections.Generic.Dictionary<string, byte[]>)tbl.Lists[key][]).ContainsKey(valKey);
  88. }
  89. }
  90.  
  91. public void Dispose()
  92. {
  93. _cacheManager.Dispose();
  94. }
  95. }

事实上,写到这里,我们的redis方法签名存储就完成了,配合上一篇文章,你可以设计出自己的缓存系统了,在这里再多说一句,本缓存系统用到的设计模式类似于策略模式,它对于一个完善功能,可以多种实现的策略,而对外只公开一个标准的对象,其它具体

的,完整功能的实现都使用了internal作为修饰符,来对外界隐藏。

返回目录

缓存篇~第七回 Redis实现基于方法签名的数据集缓存(可控更新,分布式数据缓存)的更多相关文章

  1. 缓存篇~第八回 Redis实现基于方法签名的数据集缓存~续(优化缓存中的key)

    返回目录 上一讲主要是说如何将数据集存储到redis服务器里,而今天主要说的是缓存里的键名,我们习惯叫它key. redis或者其它缓存组件实现的存储机制里,它将很多方法对应的数据集存储在一个公共的空 ...

  2. 缓存篇~第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存

    返回目录 这一讲中主要是说EnterpriseLibrary企业级架构里的caching组件,它主要实现了项目缓存功能,它支持四种持久化方式,内存,文件,数据库和自定义,对于持久化不是今天讨论的重要, ...

  3. 高性能网站架构设计之缓存篇(1)- Redis C#客户端

    一.什么 RedisREmote DIctionary Server,简称 Redis,是一个类似于Memcached的Key-Value存储系统.相比Memcached,它支持更丰富的数据结构,包括 ...

  4. 缓存篇(Cache)~第一回 使用static静态成员实现服务器端缓存(导航面包屑)

    返回目录 今天写缓存篇的第一篇文章,在写完目录后,得到了一些朋友的关注,这给我之后的写作带来了无穷的力量,在这里,感谢那几位伙伴,哈哈! 书归正传,今天我带来一个Static静态成员的缓存,其实它也不 ...

  5. Redis缓存篇(一)Redis是如何工作的

    Redis提供了高性能的数据存取功能,所以广泛应用在缓存场景中,既能有效地提升业务应用的响应速度,还可以避免把高并发压力发送到数据库层. 因为Redis用作缓存的普遍性以及它在业务应用中的重要作用,所 ...

  6. 高性能网站架构设计之缓存篇(6)- Redis 集群(中)

    昨天晚上钓鱼回来,大发神经,写了篇概括程序员生活现状的文章,没想到招来众多人的口诛笔伐,大有上升到政治层面的趋势. 我也许不会再发表任何冲击心灵的文章,我希望给大家带来更多的正能量,所以那篇文章已被我 ...

  7. 高性能网站架构设计之缓存篇(2)- Redis C#客户端

    在上一篇中我简单的介绍了如何利用redis自带的客户端连接server并执行命令来操作它,但是如何在我们做的项目或产品中操作这个强大的内存数据库呢?首先我们来了解一下redis的原理吧. 官方文档上是 ...

  8. 高性能网站架构设计之缓存篇(5)- Redis 集群(上)

    集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规则放入多个不同的服务器节 ...

  9. 高性能网站架构设计之缓存篇(4)- Redis 主从复制

    Redis 的主从复制配置非常容易,但我们先来了解一下它的一些特性. redis 使用异步复制.从 redis 2.8 开始,slave 也会周期性的告诉 master 现在的数据量.可能只是个机制, ...

随机推荐

  1. Windows下 maven3.3.1的安装步骤+maven配置本地仓库

    简单讲下maven的安装步骤: 1.在安装maven之前,先确保已经安装JDK1.6及以上版本,并且配置好环境变量. 2.下载maven3,最新版本是Maven3.3.1 ,下载地址:http://m ...

  2. JAVA SSH 框架介绍

    SSH 为 struts+spring+hibernate 的一个集成框架,是目前较流行的一种JAVA Web应用程序开源框架. Struts Struts是一个基于Sun J2EE平台的MVC框架, ...

  3. android.util.TypedValue.applyDimension

    先看一个例子: int size = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, context.getResourc ...

  4. 关于display: box 和 box-flex

    这两天做手机项目,使用到这个css3新属性.现在还不为所有浏览器支持,所以使用的时候要加上前缀.使用方法见下面: html代码: <div class="s-indLine" ...

  5. Python 学习---------Day1

    第一章 问答环节一.人们为何使用Python 软件质量 开发者的效率 程序的可移植性 标准库的支持 组件集成 享受乐趣二.Python的缺点 Python唯一的缺点就是:与C/C++这类编译语言相比, ...

  6. BZOJ1188 [HNOI2007]分裂游戏(SG函数)

    传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...

  7. Android中<original-package>标签含义

    在AndroidManifest.xml中,<original-package>与<manifest package=...>中的区别:<original-package ...

  8. jdk1.6 webService 客户端代码生成和测试

    参数:测试webService的地址:http://10.113.11.1:9090/enocpService/buildingEngService?wsdl 1,eclipse中新建一个项目, 2, ...

  9. Android 环境搭建

    一.Android 环境搭建 开发工具: Android Studio(开发工具,前提是先装 java JDK) 下载地址:http://www.androiddevtools.cn/   Oracl ...

  10. [laravel] Laravel - composer install

    #composer installLoading composer repositories with package informationUpdating dependencies (includ ...