Más contenido relacionado La actualidad más candente (20) Web开发中的缓存2. 赵劼,网名老赵,洋名Jeffrey Zhao
博客:http://www.cnblogs.com/JeffreyZhao/
推特:@jeffz_cn
InfoQ中文站编辑
某创业小公司架构师 + 程序员
希望可以给给初学者以合适引导。坚定的北大青鸟
反对者,强烈愤慨恶劣的培训机构对于处于懵懂期
的初学者以误导,强烈抵制各种虚假广告给业界带
来的不良影响,强烈建议有理想有抱负的从业青年
放弃北大青鸟,不要做冤大头。
3. 性能 能耗 冰川
降低 增加 融化
资源 温室 地球
浪费 效应 毁灭
5. CPU
磁盘
浏览器
DNS
网页快照
……
6. 客户端缓存
表现层缓存
业务逻辑层缓存
数据访问层缓存
数据库缓存
……
7. HTTP/1.1
◦ Expires, Max-Age, ETag...
Request Header
◦ If-Modified-Since
◦ If-None-Match
Response Header
◦ Expires
◦ Cache-Control
◦ Last-Modified
◦ ETag
8. 利用HTTP/1.1的标准(同上)
使用JavaScript编程时缓存数据:
window.workWithCache = function(id) {
var data = window._cache["id_" + id];
if (data != undefined) work(data);
makeAjaxRequest(id, window.ajaxCallback);
}
window.ajaxCallback = function(id, data) {
window._cache["id_" + id] = data;
work(data);
}
10. 检查缓存No.1~30
请求前 请求后
◦ 缓存为空
发出请求
◦ 请求图片No.1~30
收到回复
◦ 缓存图片No.1~30
显示图片
◦ 显示图片No.1~30
11. 检查缓存No.41~70
请求前 请求后
◦ 缓存为空
发出请求
◦ 请求图片No.41~70
收到回复
◦ 缓存图片No.41~70
显示图片
◦ 显示图片No.41~70
12. 检查缓存No.21~50
请求前 请求后
◦ 发现缓存No.21~30
◦ 发现缓存No.41~50
发出请求
◦ 请求图片No.31~40
收到回复
◦ 缓存图片No.31~40
显示图片
◦ 显示图片No.21~50
13. 便利:
◦ 单线程环境,避免许多麻烦
◦ 对于生命周期短的页面,无须资源释放
限制
◦ 无法跨页面缓存
◦ 刷新后缓存即清空
◦ 对于生命周期长的页面,需要制定资源释放策略
何时释放数据?
释放哪些数据?
14. 静态页
◦ 粒度过大
◦ 几乎无法用于一般Web 2.0系统
整页动态缓存
◦ 灵活性较静态页略高
◦ 粒度仍然过大
页面片断缓存(fragment caching)
15. class BlogController < ApplicationController
def list
unless read_fragment(:action => 'list' )
@articles = Article.find_recent
end
end
end
<% cache do %> <!- Here's the content we cache ->
<ul>
<% for article in @articles -%>
<li><p><%= h(article.body) %></p></li>
<% end -%>
</ul>
<% end %>
16. 某些时候因为@articles没有初始化而出错
详见Robin Lu于RubyConf China 2009中的演讲
“Ruby on Rails Pitfalls”,Page 10
17. public class BlogController : Controller {
public ActionResult List() {
var model = LazyBuilder.Create<Model>()
.Setup(m => m.Articles, () => Article.FindRecent())
.Instance;
return View(model);
}
}
<% Html.Cache("recent-articles", () => { %>
<ul>
<% foreach (var article in Model.Articles) { %>
<li><p><%= article.Body %></p></li>
<% } %>
</ul>
<% } %>
18. 使用相对方便,性能优势明显
粒度较大,适用面相对较窄
◦ “即时性”往往不够
19. 与业务密切相关的缓存
◦ 推荐好友
◦ 最新文章
◦ ……
一般用于缓存实体对象
控制灵活
◦ 相对容易设计“即时”的缓存
复用概率大
◦ 命中率
22. 站内短消息列表
◦ 帖子列表
◦ 回复列表
◦ 好友列表
分页显示
即时更新
23. 缓存每页数据时,附带获取数据时的时间戳
◦ data + read_timestamp
在发生更新时,刷新时间戳
◦ last_updated_timestamp
读取缓存时,比较数据获取时间与最后更新时间
◦ 如read_timestamp > last_updated_timestamp,则
cache hit
◦ 如read_timestamp < last_updated_timestamp,则
cache miss
24. Comment[] GetComments(int articleId, int page) {
DateTime lastUpdated;
var cached = GetFromCache(articleId, page, out lastUpdated);
if (cached == null || cached.TimeStamp < lastUpdated) {
var data = GetFromDatabase(articleId, page);
cached = new CacheEntry(data, DateTime.Now);
SetToCache(articleId, page, cached);
}
return cached;
}
void AddComment(Comment comment) {
... // write to database
SetLastUpdatedToCache(comment.ArticleID, DateTime.Now);
}
25. 共享引用问题
并发环境下的缓存操作
◦ 博客园评论列表
缓存数据大小
是否每个数据都要缓存?
◦ 爬虫访问?
◦ N年前的数据?
是否每种数据的缓存策略都相同?
◦ 存储方式?
◦ 过期策略?
27. 手机之家数据访问组件(引用自许超前的博文)
28. 是否透明?
◦ 多种数据库
◦ 多存储方式(RDBMS,K/V存储)
即时性如何?
◦ 数据复制
◦ CAP
是否能够应对所有形式的查询?
◦ 功能 vs. 复杂度
是否一定需要缓存?
◦ 复杂查询
◦ 并发操作
30. 数据库缓存优化:拆表
避免缓存滥用
◦ 缓存不是万能的
◦ 缓存带来复杂度
业务为技术让步
◦ e.g. 难道“即时”就那么重要吗?
Consistent Hash