首页 > 代码库 > CJCMS系列---说说项目中的缓存实现(1)

CJCMS系列---说说项目中的缓存实现(1)

缓存者,临时文件交换区也。主要就是方便查找,提高查找效率(效率在于读内存速度比读硬盘快)。

  

   大多数的项目的缓存都是通过设定过期时间来做的,可是我对于这样的替换策略不以为然,而且会导致混乱。

 

  有人说:最让人蛋疼的莫过于命名和缓存了。

 

  那么缓存蛋疼在哪里呢,那就是容易导致脏数据,缓存不应该成为脏数据,而大多数时间脏数据不可避免。

  

  举一个例子:淘宝商城,我店里有一个商品,当时缓存的库存100,但是赶上光棍节大酬宾,各种并发请求,也许你在买的时候缓存里面还有20,但是100个订单已经下过了,但是点击下单的时候蛋疼的事情来了(当然我觉得淘宝没有这样子的问题啦),你居然下单成功了。我操,我作为店主很郁闷啊,我他娘的到哪里多进口20架米格战斗机啊。

  

  上面的例子,你对缓存应该也有了一种深恶痛绝的感受吧。你这时候笑了,笑我写的程序差,笑我淘宝店的代码是垃圾,没错,这样的脏数据是能够避免的,可是有多少程序员能够注意到这一点呢,我觉得很少。

  

  直入主题上代码,这里先上一部分后面慢慢讲深入,慢慢改进,毕竟真的是在边写文章边写例子。

    

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace CJCMS.Framework.Cache{    public  class CacheTarget    {        /// <summary>        /// 缓存对象        /// </summary>        public object Target { get; set; }        /// <summary>        /// 缓存对象最后使用时间        /// </summary>        public DateTime LastRefresh { get; set; }    }}

 

  

  1 /******************************************************************  2 * 作者:                    不要理我 CJ  3 * 邮件:               869722304@qq.com(仅仅支持商业合作洽谈)  4 * 创建时间:                2012-8-14 19:43:41  5 * 最后修改时间:            2012-8-14 19:43:41  6 *   7 * 未经修改的文件版权属于原作者所有,但是你可以阅读,修改,调试。本项目不建议商用,不能确保稳定性。  8 * 同时由于项目bug引起的一切问题,原作者概不负责。  9 * 10 * 本项目所引用的所有类库,仍然遵循其原本的协议,不得侵害其版权。 11 * 12 * 您一旦下载就视为您已经阅读此声明。 13 * 14 * 您不可以移除项目中的任何声明。 15 *******************************************************************/ 16  17 using System; 18 using System.Collections.Generic; 19 using System.Linq; 20 using System.Text; 21  22 namespace CJCMS.Framework.Cache 23 { 24     public class CacheTargetManger //: ICacheTargetManger 25     { 26         private static Dictionary<string, CacheTarget> _entries = new Dictionary<string, CacheTarget>(); 27  28         /// <summary> 29         /// 检测是否缓存空间达到极限,需要使用策略替换 30         /// </summary> 31         /// <returns></returns> 32         public static void CheckIsExpired() 33         { 34             35             AppDomain.MonitoringIsEnabled = true; 36  37             AppDomain currAppDomain = System.Threading.Thread.GetDomain(); 38             while (true) 39             { 40                 GC.Collect(); 41                 if (currAppDomain.MonitoringSurvivedMemorySize > 50 * 1000 * 1000) 42                 { 43                     //最近最少使用策略实现 44                     DoStrategy(); 45                 } 46                 else 47                 { 48                     break; 49                 } 50             } 51         } 52         /// <summary> 53         /// 使用了最近最少使用策略 54         /// </summary> 55         public static void DoStrategy() 56         { 57             try 58             { 59                 Remove(_entries.OrderBy(a => a.Value.LastRefresh).First().Key); 60             } 61             catch 62             { 63                 64             } 65         } 66         /// <summary> 67         /// 添加新的内容 68         /// </summary> 69         /// <param name="key"></param> 70         /// <param name="cache"></param> 71         public static void Add(string key, object cache) 72         { 73             CacheTarget c = new CacheTarget(); 74             c.Target = cache; 75             c.LastRefresh = DateTime.Now; 76             CheckIsExpired(); 77             lock (_entries) 78             { 79                 _entries.Add(key, c); 80             } 81  82         } 83  84         public static void Update(string key, object cache) 85         { 86             CacheTarget c = new CacheTarget(); 87             c.Target = cache; 88             c.LastRefresh = DateTime.Now; 89  90             lock (_entries) 91             { 92                 _entries.Remove(key); 93                 _entries.Add(key, c); 94             } 95  96         } 97  98         public static void Save(string key, object cache) 99         {100             if (_entries.ContainsKey(key))101             {102                 Update(key, cache);103             }104             else105             {106                 Add(key, cache);107             }108         }109 110         public static void Remove(string key)111         {112             lock (_entries)113             {114                 _entries.Remove(key);115             }116         }117 118         public static void FuzzyRemove(string fuzzykey)119         {120             foreach (KeyValuePair<string, CacheTarget> k in _entries.Where(a => a.Key.Contains(fuzzykey)).ToList())121             {122                 Remove(k.Key);123             }124         }125 126         public static void Get(string key, out object result)127         {128             try129             {130                 CacheTarget c = new CacheTarget();131                 _entries.TryGetValue(key, out c);132                 result = c.Target;133                 Update(key, result);134             }135             catch136             {137                 result = null;138             }139         }140     }141 }

 

大家先看起来代码,具体还没有讲完,我后面再讲。

 

 宝宝跨年乐 刷票 qq 869722304

CJCMS系列---说说项目中的缓存实现(1)