看了老赵写的相关缓存的话题,说实话,缓存的概念实在是很大,不过其一点不变,就是尽可能的简化处理机制,尽量的减少应用程序间的交互(不知道这样表达对不对,其实也说大不清,呵呵见谅),为此我也把我作的缓存拿出来谈一下,希望有好的地方能一起分享,不好的地方及结构,也请各位指出,让我也能进行完善。
可能会分3次讲完
第一步:先讲一下我目前的缓存结构(不好的话大家不要拍砖啊 呵呵)
第二步:讲解一下怎样实现缓存的操作,以及中间的一些问题点
第三步:缓存怎样自动更新和手动更新
目前该缓存方案运用于某网站,独立ip的日访问量大概在10-15万左右(应该不算多也不算少报,呵呵),至少目前而言没有任何问题.
特别先说明一下,以下谈的缓存只针对数据缓存而言(虽然是可以支持object类型的缓存,但是为了方便说明,还是只以数据缓存为例)
首先我们利用hash来构建立一个K/V结构缓存大容器,我在这个时候key表示的数据缓存(例如DBCache),而value则针对该库的缓存。(我们称这个K/V 叫CacheContainer)
CacheContainer 是可以包含数据缓存也可以包含图片等object缓存
我目前是有2种缓存一种是object类型,一种的数据类型,那么也就是说这个容器有2个value。
此时,我们还是建立K/V结构,来作为CacheContainer的value,这时我们的key可以是DataBaseName的名(或者其他,如果你的缓存量非常大,可能需要分割多个hash块,以便提高性能)。而value则是我们针对这个database 的缓存。(我们称这个叫CacheDBContainer)
我们最后一个K/V结构,则是真正的数据存放块
key可以是有CacheContainerKey+CacheDBContainerKey+SqlQuery来构造,而value则是dt来组成
自此我们大概容器类的缓存结构都建立完成了。我都使用Hashtable.Synchronized(new Hashtable())来解决他们直接互斥并发等问题。
接下来我把CacheDBContainer 提炼出来,组建了一个CacheModel。看事例代码。
public CacheEnum CacheType { get; set; }
public string CacheKey { get; set; }
public Hashtable CacheObj { get; set; }
其中枚举代表着那种类型的缓存,即CacheContainer的key
CacheKey代表着CacheDBContainer的key
CacheObj 当然代表了我CacheDBContainer对应key的缓存列表
这个Model提供了如下方法
SetCache,RemoveCache,RefreshCache等针对CacheObj的操作
我还创建了一个CacheModelList 来缓存了CacheModel对象,以便于不需要每次使用时都需要new 一个这样的CacheModel.
接下来我们先谈一下
怎么进行缓存操作。
我们设计一个ICache的接口,这个接口很简单,只要实现SQL的Query方法就可以了。
例如ICache.Query(sql)。
重点是这个接口有2个比较重要的属性,
CacheKey: 是你需要指定该接口属于那个CacheDBContainer中的那个CacheKey,
ISqlHelper:
你需要把数据库操作类传进来,以便你没有命中缓存时,直接数据库查询。
我们可以创建一个CacheDbFactory来创建ICache,当然这个ICache接口也可以缓存起来,放到一个List<ICache>里面,以便不需要每次都new一个对象出来。
接下来我们大致的操作代码流程就是
ICacheDb iCache=CacheDbFactory.GetCls(iSqlHelper,strCacheKey);
iCache.Query(strSql)
那么我们的Query是怎样实现缓存的命中呢,我们在第二篇讲