一般来说,网站随着访问量以及数据库的增大,访问速度将会越来越慢,如何优化这个响应速度,增大用户支持容量是网站从小到中,到大的必经之路。

你也可能听说过对于大型web站点一般严重依赖于cache来弹性放大其基础设施的能力。虽然已知大型网站都使用了cache,但是很少有比较严谨的探讨性文章来说说他们是如何来做这个cache的。其中的原因可能有几个,一方面很多cache的策略都是特定于特定网站的,很难泛化成理论。另一方面可能过于复杂,并无放之四海而皆准的策略存在,特别是cache的过时更新问题到现在为止应该还没有一个非常好的解决方案。

本文介绍几种应用广泛的缓存策略,如果使用得当,应该可以保证永远不会有过期数据访问的问题存在。其中第一个策略叫做:write-through策略,第二种叫做:generational caching.

writethrough是最简单有效的策略。当你向db写的时候,你就顺便向cache更新相应key的数据。这样的好处是,任何随后的请求总是会击中cache,而不用再打到db上返回数据。只有一种情况会打到db: cache内存已经占满,而你访问的key的value已经被清场。该策略也有一些需要注意的地方:

一般人们都会使用object id作为cache的key,但是不同的表,其id可能相同,因此在构造cache key时需要注意这一点,严格定义并且遵循一个统一的key定义规范就很重要了,比如User/17

另外,任何put/delete操作时,首先得确认该操作是否成功执行了,只有确认成功执行了,你才能去更新cache,

否额,可能就会出现db并未更新,但是cache却被更改的情况,从而db和cache就不再一致!

虽然这个策略对单个的object做cache非常有效,但是大部分应用会从db中拉取多个对象,比如(返回所有属于张三的书籍).对于操作包含多个对象的数据,我们来谈谈另一种策略"generational caching"

设想你在设计一个blog app,可能需要一个简单的posts表格包含每一个Post的信息,比如title, createdat等。一般博客类型网站需要有两种页面,一个是单博客页面,一个是博客聚类页面。比如posts/3和posts/两个页面。问题就来了,我们如何有效地对posts/这个页面的数据做好cache呢?

对单博客页面的caching前面介绍的策略非常适合:write through即可,每一个post都将映射为一个cache key(一般都是基于object type和object id,比如Post/3),而每次对一个post的更新都将write-through回cache中,保持数据的一致性。

更困难的问题是:我们如何处理博客聚类列表页面,比如home page或者category page的数据缓存?为了保证db和cache的一致性,非常重要的一点是:任何时候一个Post被update,那么所有包含该Post引用的keys都必须expired掉。而这是并不容易的事情,因为一个post可能在多个cache key中被引用,比如: latest ten posts, posts in php category, posts favorited by user 15等。虽然理论上你可以通过写代码来找到包含已更新post的所有cache key,并且手工去expire掉他,但是必须指出这个过程是非常费事费力也非常容易错误的!我们推荐另外一种思路,这个思路就是genrational caching.

这种generational caching对每种类型的object去维护一个"generation" value。每次一个object被更新,则该generation value就会被增加。依然使用post作为例子,任何时候有人更新了一个post object,我们就增加the post generation object as well. 然后,任何时候我们从cache中读或者写一组boject时,我们就包含这个generation key.

通过包含这个generation value在cache key中,任何时候一个Post被更新,那么接下来的访问就不会击中cache,因此强制回源db获取数据。这种策略的一个结果是:任何时候一个post object被更新或者删除,所有包含多个posts的keys都会隐含expired掉。之所以说是隐含,因为我们永远不会主动去删除这些objects,仅仅通过增加这个generation value,我们就能保证所有old keys永远不会被访问,下面的事情就留给cache系统本身的垃圾回收机制去处理。

在多个实际application中应用该策略后,对于cache的性能提高有以下几点认识:总的来说该策略可以大大提高应用的性能减少数据库的负载。可以节约大量的表格扫描等高密度计算能力要求。同时由于减少了对数据库的请求,其他必须访问数据库的请求也能大大加快性能。

为了保持cache的一致,这个策略相对有些保守,也就是说有可能部分不该过期的cache entry也被强制过期了。比如,如果你更新了一个特定类目下的一个Post,本策略会将所有类目的key都过期。而这看起来会有些低效率和过优化嫌疑。而我也发现大多数应用是read-heavy(重读请写)的因此这种过优化的缓存策略本身不会带来大的问题。相反,如果不适用这种略显“过优化”的简易策略,那么我们的代码实现完全是和应用,model绑定在一起的,是非常难以维护的。

我前面提过在这个策略中任何model都不会被显式地从cache中删除。这也隐含着和caching tool以及库满驱赶策略有关。一般这个cache策略会使用LRU(least recent used) eviction policy来配合使用。一个LRU策略会对那些老的keys优先从内存中移除。

web应用服务端cache策略初探的更多相关文章

  1. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  2. 如何提高Web服务端并发效率的异步编程技术

    作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升 ...

  3. 【转载】Web移动端Fixed布局的解决方案

    特别声明:本文转载于EFE的<Web移动端Fixed布局的解决方案>.如需转载,烦请注明原文出处:http://efe.baidu.com/blog/mobile-fixed-layout ...

  4. winform客户端利用webClient实现与Web服务端的数据传输

    由于项目需要,最近研究了下WebClient的数据传输.关于WebClient介绍网上有很多详细介绍,大概就是利用WebClient可以实现对Internet资源的访问.无外乎客户端发送请求,服务端处 ...

  5. Openstack的web管理端相关

    openstack的web管理端技术方面要关注的问题. 同步?异步 先说浏览器的同步和异步,我们知道的浏览器可以使用ajax实现异步请求,就是浏览器在请求数据的时候,我们管理员还能对浏览器就行其他操作 ...

  6. android中图片的三级缓存cache策略(内存/文件/网络)

    实现图片缓存也不难,需要有相应的cache策略.这里我采用 内存-文件-网络 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且 ...

  7. 从web移动端布局到react native布局

    在web移动端通常会有这样的需求,实现上中下三栏布局(上下导航栏位置固定,中间部分内容超出可滚动),如下图所示: 实现方法如下: HTML结构: <div class='container'&g ...

  8. 教你如何实现微信小程序与.net core应用服务端的无状态身份验证

    随着.net core2的发布,越来越多人使用.net core2开发各种应用服务端,下面我就结合自己最近开发的一款小程序,给大家分享下,怎么使用小程序登录后,小程序与服务端交互的权限控制. .net ...

  9. web移动端常见问题解决方案 (转)

    总结:本文总结了web移动端的常见问题并附上解决方案,包括:Meta标签.获取滚动条的值.禁止选择文本.屏蔽阴影.css之border-box.css3多文本换行.Retina屏幕高清图片.html5 ...

随机推荐

  1. Spring Boot的listener简单使用

    监听器(Listener)的注册方法和 Servlet 一样,有两种方式:代码注册或者注解注册 1.代码注册方式 通过代码方式注入过滤器 @Bean     public ServletListene ...

  2. RSNAKE 的 Slowloris DOS攻击工具初试

    Slowloris 号称低带宽对服务器进行DDOS攻击 原理就是对WEB服务器发送 不完整的包并且以 单一  \r\n结尾,并不是 完整的HTTP包.造成WEB服务器堵塞达到最大连接数. 官网给出介绍 ...

  3. Flow中的Switch分析

    A switch statement can complete normally iff at least one of the following is true: (1)The switch bl ...

  4. 《Mysql技术内幕,Innodb存储引擎》——文件、表

    文件 日志 错误日志 对Mysql启动.运行和关闭过程进行记录,通过SHOW VARIABLES LIKE 'log_error'查看日志文件位置. 慢查询日志 Mysql启动时设置一个阈值,运行时间 ...

  5. C/C++程序调试和内存检测

    程序出现错误很正常,一个优秀的程序员必须学会调试,发现错误并改正.减少程序错误最有效的方法是:在敲代码之前,多花点时间思考,如何构造程序,数据结构和算法,尽量把细节提前写下来,可以尝试着在纸上写出核心 ...

  6. 用PDMReader工具生成数据库设计文档(转载)

    来源:http://blog.csdn.net/xinglun88/article/details/19987719 第一步:下载并安装PDMReader,资源网站: http://www.pdmre ...

  7. 结合after使用content

    结合after或before伪类,在元素的开头或结尾附加上一定的内容,content:""的引号中即是添加的内容,比如说我们这么写: <div>学而时习之不亦说乎< ...

  8. 边框圆角Css

    .box{ background:grey; //灰色背景 height:50px; //高500像素 width:200px; //宽200像素 border-top-left-radius:15p ...

  9. [日常] crontab的秒执行和串行化和多进程实现

    1. crontab的最低运行频率是,按照每分钟执行一次,通过在脚本中简单实现按秒级别运行 比如这条cron规则 , 每分钟执行一次脚本 * * * * * php /var/www/html/tes ...

  10. 设置navigationbar透明度时的坑

    1.需要设置导航条透明度时     UIImage *image = [UIImage imageNamed:@"bg_clear.png"]; //设置背景颜色 [nav2.na ...