zoukankan      html  css  js  c++  java
  • 中小型网站的缓存策略

    在上一篇文章《大型网站系统架构分析》中,介绍了大型网站的系统架构,其中缓存环境非常重要,大型网站往往使用Squid前端缓存服务器群,memcache分布式缓存,负载均衡,CDN等来提升性能。但中小型网站使用这些大家伙就有杀鸡用牛刀的感觉,但毋庸置疑,缓存是需要的,开发者开发程序的时候若没有并发思维,一味注重业务逻辑,往往导致并发用户可能在差不多相同的时间请求相同的数据,网站再请求数据库,如果使用缓存,对这种相同的请求,或者不变的数据,可以缓存起来,直接从内存读取,可以大大提升并发访问的性能,减少数据库访问次数。因为数据库往往是最容易出现瓶颈的地方,而通过使用恰当的缓存技术可以非常有效地减轻数据库的负载。

    根据我的经验,中小型网站可以采用这样的缓存策略 :

    • 如果是单台服务器可以直接缓存在内存,怕内存不够就合理利用ASP.NET所提供的缓存机制,有现成的干嘛不用呢?缓存存在XML文件中也是一种备选方案,但首先速度没有内存的来的快,其次是写入并发写入XML的时候会锁住文件。可以选用现成的微软Cache application block来实现。
    • 有多台的服务器的话可以考虑memcached,或者其他类似的东西,或者另加一个数据库作为缓存库也行啊。当然有钱的可以用内存数据库。

    但不是所有数据都可以缓存的:

    • 对于恒定不变的数据,系统启动后放入缓存就不过期不更新了。
    • 对于偶尔改变的数据,缓存过期时间可以稍微长一些,比如15分钟。
    • 对于经常改变的数据,但访问量极大的热点数据,可以缓存很短的时间,例如30秒,或60秒。(微软有一种数据库数据改变自动同步缓存的SqlDependency功能,有兴趣的读者可以关注)   

    如此,便可最大程度的利用缓存,从而可以有效提高系统性能,并明显减轻数据库和网络负载。

    你也可以统计并发访问最高的页面和DB访问的频率,把网页静态化,或缓存该些热点,淘汰不热的(缓存替换算法),即使缓存30秒,或60秒也是很大的性能提升,因为他们的并发访问量很大,导致数据库的压力也很大。

    代码参考:使用策略模式和单例模式的单机内存缓存:(可以扩展到其他的缓存策略,例如memcache等)

    ClassDiagram

    ICacheStrategy.cs

     1: using System;
     2: using System.Text;
     3:  
     4: namespace Sample.Caching
     5: {
     6: /// <summary>
     7: /// 缓存策略接口
     8: /// </summary>
     9: public interface ICacheStrategy
     10: {
     11: void AddObject(string objId, object o);
     12: 
     13: void AddObjectWithTimeout(string objId, object o, int timeoutSec);
     14: 
     15: void AddObjectWithFileChange(string objId, object o, string[] files);
     16: 
     17: void AddObjectWithDepend(string objId, object o, string[] dependKey);
     18:  
     19: void RemoveObject(string objId);
     20:  
     21: object RetrieveObject(string objId);
     22:  
     23: int TimeOut { set;get;}
     24: }
     25: }

    DefaultCacheStrategy.cs

     1: using System;
     2: using System.Web;
     3: using System.Collections;
     4: using System.Web.Caching;
     5:  
     6: namespace Sample.Caching
     7: {
     8: /// <summary>
     9: /// 默认的缓存策略,实现了缓存策略接口
     10: /// </summary>
     11: public class DefaultCacheStrategy : ICacheStrategy
     12: {
     13: private static readonly DefaultCacheStrategy instance = new DefaultCacheStrategy();
     14:  
     15: protected static volatile System.Web.Caching.Cache webCache = System.Web.HttpRuntime.Cache;
     16:  
     17: protected int _timeOut = 1; //默认缓存一分钟,也可以单独设置对象的超时时间
     18:  
     19: private static object syncObj = new object();
     20:  
     21: /// <summary>
     22: /// Initializes the <see cref="DefaultCacheStrategy"/> class.
     23: /// </summary>
     24: static DefaultCacheStrategy()
     25: {
     26: //lock (syncObj)
     27: //{
     28: // //System.Web.HttpContext context = System.Web.HttpContext.Current;
     29: // //if(context != null)
     30: // // webCache = context.Cache;
     31: // //else
     32: // webCache = System.Web.HttpRuntime.Cache;
     33: //} 
     34: }
     35:  
     36:  
     37: public int TimeOut
     38: {
     39: set { _timeOut = value > 0 ? value : 6000; }
     40: get { return _timeOut > 0 ? _timeOut : 6000; }
     41: }
     42:  
     43: 
     44: public static System.Web.Caching.Cache GetWebCacheObj
     45: {
     46: get { return webCache; }
     47: }
     48:  
     49: public void AddObject(string objId, object o)
     50: {
     51:  
     52: if (objId == null || objId.Length == 0 || o == null)
     53: {
     54: return;
     55: }
     56:  
     57: CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
     58:  
     59: if (TimeOut == 6000)
     60: {
     61: webCache.Insert(objId, o, null, DateTime.MaxValue, TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, callBack);
     62: }
     63: else
     64: {
     65: webCache.Insert(objId, o, null, DateTime.Now.AddMinutes(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
     66: }
     67: }
     68:  
     69: public void AddObjectWith(string objId, object o)
     70: {
     71: if (objId == null || objId.Length == 0 || o == null)
     72: {
     73: return;
     74: }
     75:  
     76: CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
     77:  
     78: webCache.Insert(objId, o, null, System.DateTime.Now.AddHours(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
     79: }
     80:  
     81: 
     82: public void AddObjectWithTimeout(string objId, object o, int timeoutSec)
     83: {
     84: if (objId == null || objId.Length == 0 || o == null || timeoutSec <= 0)
     85: {
     86: return;
     87: }
     88:  
     89: CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
     90:  
     91: webCache.Insert(objId, o, null, System.DateTime.Now.AddSeconds(timeoutSec), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
     92: }
     93:  
     94: public void AddObjectWithFileChange(string objId, object o, string[] files)
     95: {
     96: if (objId == null || objId.Length == 0 || o == null)
     97: {
     98: return;
     99: }
     100:  
     101: CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
     102:  
     103: CacheDependency dep = new CacheDependency(files, DateTime.Now);
     104:  
     105: webCache.Insert(objId, o, dep, System.DateTime.Now.AddHours(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
     106: }
     107:  
     108: 
     109: public void AddObjectWithDepend(string objId, object o, string[] dependKey)
     110: {
     111: if (objId == null || objId.Length == 0 || o == null)
     112: {
     113: return;
     114: }
     115:  
     116: CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(onRemove);
     117:  
     118: CacheDependency dep = new CacheDependency(null, dependKey, DateTime.Now);
     119:  
     120: webCache.Insert(objId, o, dep, System.DateTime.Now.AddMinutes(TimeOut), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.High, callBack);
     121: }
     122:  
     123: public void onRemove(string key, object val, CacheItemRemovedReason reason)
     124: {
     125: switch (reason)
     126: {
     127: case CacheItemRemovedReason.DependencyChanged:
     128: break;
     129: case CacheItemRemovedReason.Expired:
     130: {
     131: //CacheItemRemovedCallback callBack = new CacheItemRemovedCallback(this.onRemove);
     132:  
     133: //webCache.Insert(key, val, null, System.DateTime.Now.AddMinutes(TimeOut),
     134: // System.Web.Caching.Cache.NoSlidingExpiration,
     135: // System.Web.Caching.CacheItemPriority.High,
     136: // callBack);
     137: break;
     138: }
     139: case CacheItemRemovedReason.Removed:
     140: {
     141: break;
     142: }
     143: case CacheItemRemovedReason.Underused:
     144: {
     145: break;
     146: }
     147: default: break;
     148: }
     149:  
     150: //TODO: write log here
     151: }
     152:  
     153: 
     154: public void RemoveObject(string objId)
     155: {
     156: //objectTable.Remove(objId);
     157: if (objId == null || objId.Length == 0)
     158: {
     159: return;
     160: }
     161: webCache.Remove(objId);
     162: }
     163:  
     164:  
     165: public object RetrieveObject(string objId)
     166: {
     167: //return objectTable[objId];
     168:  
     169: if (objId == null || objId.Length == 0)
     170: {
     171: return null;
     172: }
     173:  
     174: return webCache.Get(objId);
     175: }
     176:  
     177: }
     178: }

    CachingManager.cs

     1: using System;
     2: using System.Collections.Generic;
     3: using System.Text;
     4:  
     5: namespace Sample.Caching
     6: {
     7: /// <summary>
     8: /// The caching manager
     9: /// </summary>
     10: public class CachingManager
     11: {
     12: private static ICacheStrategy cs;
     13: private static volatile CachingManager instance = null;
     14: private static object lockHelper = new object();
     15: 
     16: //private static System.Timers.Timer cacheConfigTimer = new System.Timers.Timer(15000);//Interval in ms
     17:  
     18: 
     19: private CachingManager()
     20: {
     21: cs = new DefaultCacheStrategy();
     22:  
     23: ////Set timer
     24: //cacheConfigTimer.AutoReset = true;
     25: //cacheConfigTimer.Enabled = true;
     26: //cacheConfigTimer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
     27: //cacheConfigTimer.Start();
     28: }
     29:  
     30: 
     31: private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
     32: {
     33: //TODO:
     34: }
     35:  
     36: 
     37: public static CachingManager GetCachingService()
     38: {
     39: if (instance == null)
     40: {
     41: lock (lockHelper)
     42: {
     43: if (instance == null)
     44: {
     45: instance = new CachingManager();
     46: }
     47: }
     48: }
     49:  
     50: return instance;
     51: }
     52:  
     53: 
     54: public virtual void AddObject(string key, object o)
     55: {
     56: if (String.IsNullOrEmpty(key) || o == null) return;
     57:  
     58: lock (lockHelper)
     59: {
     60: if (cs.TimeOut <= 0) return;
     61:  
     62: cs.AddObject(key, o);
     63: }
     64: }
     65:  
     66: 
     67: public virtual void AddObject(string key, object o, int timeout)
     68: {
     69: if (String.IsNullOrEmpty(key) || o == null) return;
     70:  
     71: lock (lockHelper)
     72: {
     73: if (cs.TimeOut <= 0) return;
     74:  
     75: cs.AddObjectWithTimeout(key, o, timeout);
     76: }
     77: }
     78:  
     79: 
     80: public virtual object RetrieveObject(string objectId)
     81: {
     82: return cs.RetrieveObject(objectId);
     83: }
     84:  
     85: 
     86: public virtual void RemoveObject(string key)
     87: {
     88: lock (lockHelper)
     89: {
     90: cs.RemoveObject(key);
     91: }
     92: }
     93:  
     94: 
     95: public void LoadCacheStrategy(ICacheStrategy ics)
     96: {
     97: lock (lockHelper)
     98: {
     99: cs = ics;
     100: }
     101: }
     102:  
     103: 
     104: public void LoadDefaultCacheStrategy()
     105: {
     106: lock (lockHelper)
     107: {
     108: cs = new DefaultCacheStrategy();
     109: }
     110: }
     111: }
     112: }

    调用:

     1: CachingManager cm = CachingManager.GetCachingService();
     2: cm.LoadDefaultCacheStrategy();
     3: //从缓存获取
     4: IList list = cm.RetrieveObject("mykey") as IList;
     5: if (list == null)
     6: {
     7: list = DAL.GetData(); //从数据库查询
     8: cm.AddObject("mykey", list, 2 * 60); //缓存2分钟
     9: }
     10: return list;

    调用时序图:

    SequenceDiagram1

  • 相关阅读:
    ibatis报错
    struts配置时遇到的几个问题
    快乐工作,快乐生活
    浅谈协方差矩阵理解篇
    类成员变量初始化
    类对象所占内存空间总结
    const 成员函数
    Qt对话框QDialog
    const引用返回值
    Qt 对象间的父子关系
  • 原文地址:https://www.cnblogs.com/Mainz/p/1449858.html
Copyright © 2011-2022 走看看