中小型网站的缓存策略

news/2024/5/11 19:12:11/文章来源:https://blog.csdn.net/he90227/article/details/45078825

在上一篇文章《大型网站系统架构分析》中,介绍了大型网站的系统架构,其中缓存环境非常重要,大型网站往往使用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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_809047.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

瞬时响应:网站的高性能架构

什么叫高性能的网站&#xff1f; 两个网站性能架构设计方案&#xff1a;A方案和B方案&#xff0c;A方案在小于100个并发用户访问时&#xff0c;每个请求的响应时间是1秒&#xff0c;当并发请求达到200的时候&#xff0c;请求的响应时间将骤增到10秒。B方案不管是100个并发用户访…

Mysql在大型网站的应用架构演变

本文主要描述在网站的不同的并发访问量级下&#xff0c;Mysql架构的演变,下面分别从不同的角度思考mysql的演变过程.可扩展性架构的可扩展性往往和并发是息息相关&#xff0c;没有并发的增长&#xff0c;也就没有必要做高可扩展性的架构&#xff0c;这里对可扩展性进行简单介绍…

大型网站架构与分布式架构

大型互联网架构 解决问题的通用思路是将分而治之&#xff08;divide-and-conquer&#xff09;&#xff0c;将大问题分为若干个小问题&#xff0c;各个击破。在大型互联网的架构实践中&#xff0c;无一不体现这种思想。 架构目标 低成本:任何公司存在的价值都是为了获取商业利益…

网站分布式架构的演进

来源&#xff1a;知乎 http://www.zhihu.com/question/22764869/answer/31277656首先推荐4本书 大型分布式网站架构设计与实践 http://item.jd.com/11529266.html 大型网站技术架构&#xff1a;核心原理与案例分析 http://item.jd.com/11322972.html 大型网站系统与Java中间件实…

浅谈Web网站架构演变过程及各阶段所用的技术和架构设计

前言 我们以javaweb为例&#xff0c;来搭建一个简单的电商系统&#xff0c;看看这个系统可以如何一步步演变。该系统具备的功能&#xff1a;用户模块&#xff1a;用户注册和管理商品模块&#xff1a;商品展示和管理交易模块&#xff1a;创建交易和管理 阶段一、单机构建网站 网…

大型网站电商网站架构案例和技术架构的示例

大型网站架构是一个系列文档&#xff0c;欢迎大家关注。本次分享主题&#xff1a;电商网站架构案例。从电商网站的需求&#xff0c;到单机架构&#xff0c;逐步演变为常用的&#xff0c;可供参考的分布式架构的原型。除具备功能需求外&#xff0c;还具备一定的高性能&#xff0…

个人网站被攻击,并受到勒索信息,怎么应对?

个人网站被攻击,并受到勒索信息,这已经是第二次了 To recover your lost databases and avoid leaking it: visit http://dbrestore.to and enter your unique token 18dc****52424 and pay the required amount of Bitcoin to get it back. Databases that we have:** Your d…

Web网站通知系统设计

写在前面&#xff1a; 通知系统是网站信息传播机制的重要的一部分&#xff0c;足够写一大章来说明。本文只梳理设计原则&#xff0c;后续相关内容会持续更新。 这里的通知包括但不限于公告、提醒或消息&#xff08;不同使用场景下的功能定义不同&#xff09;。 关于各客户端平台…

主流网站服务器配置组成 主流网站服务器报价

主流网站服务器配置组成 主流网站服务器报价 当今互联网已经是由数量巨大的服务器担当各种服务角色&#xff0c;构成丰富多彩&#xff0c;信息巨大的网络世界&#xff0c;最新英特尔Xeon处理器采用45纳米制程技术&#xff0c;提供第二代四核动力&#xff0c;主频高达 3.2GHz&am…

如何替换页面url_网站改版需要注意什么?如何把SEO影响降到最低?

网站的重新改版意味着网站的主题、页面设计或网站架构没有变化&#xff0c;以便做出相对较大的改变。如果网站主题的内容发生很大变化&#xff0c;域名从一个行业变成另一个行业的内容&#xff0c;从SEO的角度来看&#xff0c;这不是网站的改版&#xff0c;而是网站的自杀。首先…

seo查询工具源码_分享3款实用的SEO推广工具,值得收藏!

在竞争激烈的市场环境中&#xff0c;如何降低网站的维护成本&#xff0c;如何获得较多的人流量&#xff0c;如何提高网站排名等诸多问题&#xff0c;都是企业在营销过程中不可忽视的问题。然而&#xff0c;在大多数推广方式之中&#xff0c;SEO优化方法被很多企业优先考虑的。因…

jstl处理栏目与子栏目_SEO:栏目页优化对于关键词排名的重要性

我们在做网站优化排名的时候发现&#xff0c;网站关键词排名一直上不来&#xff0c;而且关键词库是很少的&#xff0c;除了我们设置好的首页TDK以外&#xff0c;其它栏目页就没有好好的运用&#xff0c;我们可以看看大部分的企业网站&#xff0c;他们的栏目页大部分就是一些留言…

2021江西高考成绩查询微信可以吗,2021年江西高考成绩查询网站查分网址:http://www.jxeea.cn/...

【导语】高考结束后大家最为关心的问题就是在哪里查分&#xff0c;如何查分&#xff0c;无忧考网高考频道特别整理2021年江西高考成绩查询查分网址&#xff0c;成绩公布时考生可直接点击网址进行查分&#xff0c;预祝大家都能顺利的考上理想的大学&#xff01;由于&#xff0c;…

PHP:【商城后台管理系统】部署友情链接,网站基础设置

PHP:【商城后台管理系统】部署友情链接&#xff0c;网站基础设置 一.友情链接 ①友情链接页面 ②友情链接编辑 ③友情链接添加 二.网站基础设置 ①后台网站基础设置页面 ②网站基础设置效果 三.部署流程 部署流程 后端采用thinkphp6.0&#xff0c;首先是网站基础设置&…

Python建站-阿里云-Ubuntu-Django

以前写的更像是备忘&#xff0c;这次希望写出一个完整教程&#xff0c;方便大家&#xff0c;也加深一下自己的印象。 服务器 用的是阿里云的轻量应用服务器&#xff0c;就是学生申请的那个&#xff0c;其他的应该都差不多。相信大家都已经申请好了&#xff0c;如果有小白的话…

avenir字体可以商用吗_一字赔万金,4个网站拯救字体版权问题

歪脑设计的第7个WHY大家好&#xff0c;我是小喳子夸下海口日更的我来了昨天&#xff0c;根正苗红的木木突然热泪盈眶要庆祝阿中麻麻的生日求程序猿小哥哥撸了个小红旗头像的小程序我和柚柚却给小哥哥捶背到无法自拔就在把小哥哥捶到四肢僵硬时&#xff0c;咋一看手机&#xff0…

404 not found nginx是什么意思_404到底是什么意思,网站设置有啥好处,怎么设置?...

在我们打开网站的时候&#xff0c;有时候会存在打不开的现象&#xff0c;而每一种打不开现象背后都有一个逻辑&#xff0c;例如数据库错误&#xff0c;例如页面不存在等现象&#xff0c;而404就是页面不存在返回到的一种页面&#xff0c;有些404页面会进行设置了自动跳转到首页…

伪静态隐藏域名后缀_如何区分网站URL是动态还是静态?

我们在对网站优化的过程中&#xff0c;常常会遇到各种各样的网站内页URL链接类型&#xff0c;但是&#xff0c;你知道吗&#xff1f;如何通过网站URL去分别该页面是动态还是静态呢&#xff1f;网站URL的层级不要超过5层&#xff0c;最好的状态是三层&#xff0c;网站的域名属于…

御用导航官方网站提醒提示页_高德地图上线手机AR驾车导航 已支持部分安卓手机...

高德地图App近日发布了v10.60新版本&#xff0c;上线了手机端的AR驾车导航功能&#xff0c;可为用户带来更加直观的路线、方向和车道级实景导航体验。该功能目前已经支持部分安卓手机&#xff0c;iPhone版本也将于近期上线。据悉高德AR导航借助智能的图像识别技术以及专业的交通…

aix如何查看日志策略_企业网站排名,SEO诊断,网站日志分析为什么不能忽略?...

在做SEO的过程中&#xff0c;我们总是会遇到各种莫名其妙的问题&#xff0c;比如&#xff1a;某一天你的网站突然出现收录缓慢的问题&#xff0c;而平时都是秒收录。 最开始我们在做审查的时候&#xff0c;总是在思考&#xff1a; ①是否搜索引擎算法在调整。 ②是否自己的内容…