浅谈网站架构中缓存的应用

27
——浅浅浅浅浅浅浅浅浅浅浅浅 5173.com 浅浅 2010 浅 6 浅 浅浅浅浅 浅浅浅浅

Upload: powerzhuye

Post on 28-Jun-2015

2.790 views

Category:

Technology


0 download

DESCRIPTION

2010/7/17 博客园活动演讲

TRANSCRIPT

Page 1: 浅谈网站架构中缓存的应用

——浅谈网站架构中缓存的应用

5173.com

朱晔2010 年 6 月

缓存恢恢,疏而不漏

Page 2: 浅谈网站架构中缓存的应用

内容概要 缓存的基本知识 网站架构中缓存的分类 影响缓存命中率的因素 缓存常见的模式和实现 缓存的更新过期和清除策略 包裹着缓存纱布的数据库 缓存存储方式的选择 缓存的同步问题 缓存的颠簸问题 分布式缓存系统的需求 Memcache 的基本介绍 Memcache 的使用误区和实践 Windows Server AppFabric Caching

Page 3: 浅谈网站架构中缓存的应用

缓存的基本知识 缓存的由来

两种介质的速度不匹配(差距较大)的问题导致?高速方在和低速方交互的时候因等待速度趋近于低速方,并且闲置得不到有效利用。

存在第三种介质,速度介于两者之间, 价格介于两者之间。通过引入这种介质,把低速方部分内容保存在这个介质中,高速方大多情况下无须和低速方直接交互来提高整体性能。

典型的例子: CPU 缓存(高速方 CPU 低速方内存),内存(高速方 CPU 低速方磁盘)。

缓存的分类 硬件领域中缓存(某种介质),软件领域中的缓存(不

限于某种介质,只是一种手段),我们之后谈的缓存都是软件缓存。

读取缓存(解决读取速度慢),写入缓存(解决写入速度慢),读写缓存。

狭义上解决介质读写速度不匹配问题,广义上包括任何利用中间媒介提高速度的方法,包括空间换时间,动态操作变为静态操作。

1E+001E+011E+021E+031E+041E+051E+061E+071E+081E+09

315

200

10000000

1000000000

访问需要的时钟周期

Page 4: 浅谈网站架构中缓存的应用

缓存的基本知识 缓存( CACHE )和缓冲( BUFFER )

缓存:可以共享,多种数据,大小不固定,可以重复使用,已知数据,用于提高 IO效率。

缓冲:不可以共享,单一数据,大小固定,读取后失效,命中 100% ,未知数据,用于减少 IO 次数。

缓存的属性 命中率:从缓存中返回正确数据的次数 / 总请求次数。 容量:超过这个值启用一定的策略:转移到磁盘;转移到远端;清空部分。 存储介质:内存、磁盘。 成本:开发成本、部署成本、硬件成本。 效率: SET 效率、 GET 效率、序列化、哈希算法、分布式算法。

缓存的限制 由于价格的因素,缓存实现依赖的存储往往有大小限制——保存什么,舍弃什么,

命中率。 缓存往往是从无到有的——在最初阶段不能发挥作用,在不命中的时候性能颠簸。

Page 5: 浅谈网站架构中缓存的应用

网站架构中缓存的分类 按照存储介质来分

内存(网站进程内、同服务器独立进程、独立服务器、分布式服务器组)。 磁盘(本地文件和数据库,独立服务器、分布式服务器组)。 缓存可以使用磁盘而不仅仅是内存。

按照存储的数据来分 直接用于输出的整页( HTML 、脚本样式、图片)。 片段页(可供多个客户端使用的 HTML 、脚本样式等)。 索引和聚合数据(空间换时间)。 耗时查询的结果数据。 和业务相关的大块数据(列表数据,引用数据)。 和业务相关的小级数据(行级数据,资源数据)。 和上下文(用户)相关的数据(活动数据)。

按照实现方式来分 框架或引擎内置的缓存(比如 ORM 缓存和 SQL SERVER 缓存)。 安装特定的组件根据规则自动实现缓存(比如反向代理和输出缓存)。 需要由开发以编程方式实现的缓存(比如业务数据缓存)。

按照作用来分 用于数据的读取(之后介绍的大部分内容都是基于此类缓存) 用于(允许丢失)数据的写入——写到缓存的队列中,再由工作线程提交处理(写入存储)

Page 6: 浅谈网站架构中缓存的应用

影响缓存命中率的因素

500毫秒 1000毫秒 2000毫秒0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

100%

1000 次访问 2000 次访问 5000 次访问

假设数据库的访问操作需要 5毫秒。第一个测试固定 Key 的范围,第二个测试固定缓存时间。 对于相同的请求数,随着缓存时间的上升(实时性下降),缓存命中率明显上升。 对于相同的缓存时间,随着请求数的上升(时间的推移),缓存命中率保持稳定。 在相同的缓存时间下( 2秒),缓存 Key 的跨度越大命中率越低,往往 Key 的范围很大预示着缓存的粒度太粗, Key所容纳的条件太多。

100 个 Key 1000 个 Key 2000 个 Key0%

10%

20%

30%

40%

50%

60%

70%

80%

90%

100%

1000 次访问 2000 次访问 5000 次访问

Page 7: 浅谈网站架构中缓存的应用

影响缓存命中率的因素 影响命中率的因素

业务需求决定的时效性(体现在缓存的过期时间)。 硬件基础结构决定的容量(即使未过期都可能会删除 LRU )。 软件架构设计决定的缓存的粒度

Key = 帖子 ID; Value = 所有跟贴数据。 Key = 帖子 ID; Value = 一条帖子的数据 以及 Key = 帖子 ID; Value = 跟贴 ID 列表。

缓存的设计(包括替换策略等)

提高缓存命中率的方法 权衡业务、基础结构和架构设计。 预热、增加过期时间、增加存储容量、调整缓存项的键值算法、对热点问题的捕捉。

对于时效性很高(或缓存空间有限),内容跨度很大(或访问很随机),并且访问量不高的应用来说缓存命中率可能长期接近于 0 ,预热后的缓存还没来得及为后人服务就已经冷却。

Page 8: 浅谈网站架构中缓存的应用

缓存常见的模式和实现延迟加载的缓存 主要用于缓存计算后的小块数据

依靠用户的请求加载数据 一开始命中率低(可以通

过预热提高命中率) 随着用户访问的增多命中

率逐渐提高 随着缓存的过期命中率保持稳定

“冷门”的数据可能始终从数据库获取

适合分布式缓存

预加载的缓存 主要用于缓存计算前的原始大块数据

一般缓存的(元)数据不太需要更新

大多采用主动更新 一般信任缓存的数据 考虑初始化的时候多台服务器对数据库的冲击

不适合分布式缓存

Page 9: 浅谈网站架构中缓存的应用

缓存常见的模式和实现操作缓存(异步队列) 优点是把瞬时的流量冲击“磨平”,可以控制一定的“带宽”对数据库操作,

而不是“压垮”,以及不阻塞调用方线程。 缺点是不能保证返回结果的时间。 注意要平衡写入速度和处理速度,要确保缓存的容量足够大,能应付 peak

time 。饭店生意兴旺没有座位的时候可以选择不接受新客人或是让客人排队等候,如果来的客人永远比走的客人多,那么只能考虑再开一个饭店了。

Page 10: 浅谈网站架构中缓存的应用

缓存的更新、过期和清除策略 缓存的更新策略

A 由获取数据请求触发的被动更新 B 由更新数据请求触发的主动更新(双写) C 使用独立线程主动定时更新缓存 D 回调方式更新(过期或依赖) E 永远不更新?

缓存的过期(失效)策略 F 绝对的过期时间 G 平滑过期(有人使用就不会过期) H 依赖方式(依赖数据库、依赖文件) I 永远不过期?

缓存的清除(替换)策略: RAND 删除随机数据,不能反映局部性。 SIZE 删除最大的数据。 FIFO , First In First Out 删除最先进入缓存的数据,不能反映局部性。 LFU , Least Frequently Used 删除一直以来最少被使用的数据。 LRU , Least Recently Used 删除最近最少使用的数据。

常见模式 延迟加载方式: A+F 预加载方式: B/C/E+I

Page 11: 浅谈网站架构中缓存的应用

包裹着缓存纱布的数据库 静态资源被浏览器、反向代理挡掉,很少

能击中 Web服务器 实时性不高的动态页,可以整页缓存在反向代理端

实时性高,参数复杂的动态页,分为 10个页面片段

其中 4 个页面片段,呈现层直接在分布式缓存中找到

剩余 6 个页面片段 Web服务器无法直接获取。但所需的数据,其中 4 个可以由应用服务器结合自己的缓存和分布式缓存计算得到, 1 个由应用服务器基于内存的业务数据得到

最终只有 1 个查询落到数据库端(还不一定需要访问磁盘)

需要考虑的问题? 如果数据有重叠,需要刷新缓存怎

么办? 开发人员各自实现自己的缓存,造

成浪费,增加 debug难度。

Page 12: 浅谈网站架构中缓存的应用

缓存存储方式的选择优点 缺点 典型数据

客户端内存(浏览器进程内)

很多时候无须考虑资源释放 刷新页面失效,数据安全性得不到保证、不能跨页面

Ajax页面面向输出的数据

客户端磁盘(浏览器临时文件)

无须访问 Web服务器获取数据

数据安全性得不到保证 高频度访问的很少改动的非敏感数据,载体 js文件

Web服务进程内 速度快,没有(反)序列化开销,引用类型地址(易于维护对象关系)

空间有限,和 Web服务进程互相干扰,同步问题

网站程序相关的数据

Web服务器上的非Web服务进程

速度快,和 Web服务进程互不影响

空间有限,同步问题 高频度访问的需要较少更新的业务数据

应用服务器上的内存 可以存储大块数据,灵活性高,引用类型地址

空间有限,对外(反)序列化开销,同步问题,网络通讯开销

中频度访问的难以拆散的整块业务数据(实体数据)

Web服务器上的磁盘 空间较大,没有网络开销 速度较慢 临时性的用于输出或用于中转的数据

应用服务器上的磁盘 空间较大 速度较慢,网络通讯开销, 聚合数据,索引数据

分布式内存缓存 空间较大可以扩展,单点无须考虑同步问题

对存储数据大小往往有限制,分布过散性能问题

面向输出的片段数据或运算之后的小块业务数据

分布式磁盘缓存 空间非常大也可以扩展 性能较差,网络开销 聚合数据,索引数据

Page 13: 浅谈网站架构中缓存的应用

缓存存储方式的选择

平衡

网络开销

序列化开销

同步开销

空间开销

背景: 单台服务器 2G 内存, 200G 磁

盘 内网千兆带宽

缓存 5KB省市联动数据 缓存 10KB 请求中产生的数据 缓存 100KB 网站配置文件 缓存 10MB敏感过滤词列表 缓存 100MB游戏列表数据 缓存 500M CMS页面数据 缓存 1GB辞典原始数据 缓存 1GB行级发布单数据 缓存 1GB查询结果数据 缓存 100GB 的报表聚合数据 缓存 1TB 的搜索索引数据

特殊情况下可否考虑多种存储联合使用?二级缓存

Page 14: 浅谈网站架构中缓存的应用

缓存的同步问题 什么时候需要同步缓存?

多份相同的数据保存在多个点,比如负载均衡的应用服务器中的大块业务数据。 对数据实时性要求高,或是不允许数据出现不一致的现象,各自过期不能满足

要求。

缓存同步的方式? 被动同步:让缓存依赖到一个点(文件、数据库等)多份缓存同时过期,不适合永不过期的大块数据,不适合主动更新的缓存,存在一定的延时。

主动同步:把最新的 KeyValue传给各个节点,或是把需要的 Key传给各个节点,由每一个节点从一个点(比如数据库或memcache )去更新最新的值(后者也可以通过独立的同步服务进行)。

缓存同步的问题? 消耗太多的资源:一份数据因为同步在网络上传多份,同步时的锁,在端点很

多的时候创建过多的连接。 需要这么做的时候考虑一下,需要同步的数据是否适合缓存,如果是的话,是否能在单点缓存?

Page 15: 浅谈网站架构中缓存的应用

缓存的颠簸问题 什么是缓存的颠簸问题?

缓存失效后到缓存重建之间的时间内,由于用户都会访问数据库导致性能急剧下降。 应用服务启动的时候初始大量的数据,大量的应用服务器同时启动给数据库造成巨大压力。

缓存可以改善性能,但是缓存也可能会在瞬时给系统造成巨大的压力,并且,由于缓存的存在,我们很难预测数据库真正需要面对的压力,一旦缓存基础服务瘫痪,整个系统可能就瘫痪了。

有什么应对方法?

考虑让缓存永不失效,主动更新缓存,采用替换引用方式更新(主 / 次缓存),而不是先删除。

对于大块缓存的初始化考虑按需加载(延迟加载),或是尽量避免同时重启初始化服务。

压力测试考虑无缓存服务的情况。 还要注意尽量让外界无法干扰KEY 的生成,否则可能会带来过多无效数据穿透缓存

(比如直接根据 querystring 作为 key 来查询缓存不是好办法,不信任或不直接使用任何来自客户端的东西)。

Page 16: 浅谈网站架构中缓存的应用

分布式缓存系统的需求 为什么选择分布式架构?太多的理由!

单台服务器的资源(内存)不足以支撑我们的应用。 负载均衡的服务器缓存了大量相同的拷贝。 负载均衡的服务器缓存需要同步,或者多点更新。 负载均衡的服务器在缓存丢失的时候对数据库同时发起“攻击”。 我们有很多服务器 CPU资源紧张而内存资源充足,得不到有效利用。

为什么存储方式选择内存?内存真不贵! 主要用于解决磁盘速度太慢。 使用 CPU 缓存不太现实,即使可以速度也和网络不匹配 。

为什么存储结构选择哈希表( Key-Value)? 快速——时间复杂度 O(1)。 稳定——一直是 O(1)。 简单—— GET/SET/DEL。 天生就适合分布式——不需要考虑如何拆分, Key-Value的粒度足够小。 不过——我们要针对 Key和 Value的设计做很多工作,这又关于缓存的贡献度。

于是乎,我们想到了Memcache

Page 17: 浅谈网站架构中缓存的应用

Memcache 的基本介绍 分布式内存对象缓存系统;表现为分布式内存哈希表 DHT ; C/S 架构;客户端决定分布;服务端之间互不通信;多平台;见缝插针; 不是数据库;不提供故障转移;不提供容灾;不提供验证; 多客户端访问相同数据?序列化方式;压缩方式;哈希方式; 基本命令: get/set/del/add/replace/incr/decr/stats/flush/gets/cas Key 250字符(超过截断); Value 1MB 限制(超过失败) ; 只是字符串(有些不能序列化的数据不适合);和进程中缓存相比没有缓存指针的优势; 始终是缓存而不是数据库;过期时间(最长 30天)和 LRU (可以禁用);懒过期; 所有单条命令原子; 1.2.5+ GETS 和 CAS(key, value, cas) ;

Page 18: 浅谈网站架构中缓存的应用

Memcache 的基本介绍 内存存储结构 Slab Allocator

malloc/free 慢、内存碎片 ( 也可使用 USE_SYSTEM_MALLOC 编译开关启用) 以 Slab ( Page ) 1MB (其实会是小于 1M Chunk Size 的倍数)为单位申请内

存 将 Slab 分割为固定尺寸的 Chunk ( -f 开关设置增长因子,默认 1.25 ) 把相同尺寸的 Chunk 分成组也就是 Slab Class ( bucket ) 选择最合适的 Chunk 保存,会造成浪费,以空间作为性能的 tradeoff 如果全部空间都是 10K 的 Chunk ,之后进来的数据都是 20K怎么办?重启动

Page 19: 浅谈网站架构中缓存的应用

Memcache 的基本介绍 单调性和平衡性 传统方式:取模,一旦节点有改变,映射全部改变 一致性哈希:解决单调性,平衡性通过引入虚拟节点来解决

Page 20: 浅谈网站架构中缓存的应用

Memcache 的基本介绍

Page 21: 浅谈网站架构中缓存的应用

Memcache 的使用误区和实践使用误区

不能假设可靠性也就是 100%获取到数据(比如当作 static 变量,或用于session )。

需要考虑网络开销或序列化反序列化开销(一个页面数十个请求,拆分存储大对象)。

Key-Value 的存储决定了在设计阶段需要考虑如何使用缓存而不是在发布前去用。

使用实践

不要和需要内存的服务一起部署,可以和需要 CPU 的服务一起部署,不要开启SWAP 。

定义具有意义的 Key ,命名空间 _业务相关主键 ID ,而不是一段 hash 值:批量删除、批量获取、避免冲突,还可以在 Key 中包含版本号,老的数据”自然死亡“。

对于 Value 到底是保存序列化后的立体对象还是字符分隔的平面对象?比如: { { 标题 : 标题 1, ID:1 } , { 标题 : 标题 2, ID:2 } } 还是 “标题 _ID1_标题2_ID2” 。

Page 22: 浅谈网站架构中缓存的应用

Memcache 的使用误区和实践 对于列表数据,可以采用两种数据结构两段式存取( IDs 和行数据 ID-Value ),排序、查找基于 IDs (可以根据条件定义多个 IDs ,比如news_from_0_to_100 、 news_category_1_top_20 )而更新只需更新行数据。

如果没有维护 IDs结构可以直接根据 Key查找列表数据,比如news_2010_6_1_12_00 ,我们就可以实现分页列表但不能提供总页数功能。

善于利用 append 和 prepend (留言添加应用,甚至可以采用命令叠加Ids:1,2,3,2d,4 )。

善于使用批量获取来减少网络调用,必要情况下把相关的 Key指定服务器保存。 改变思路,使用分布式缓存需要在设计阶段花一些时间,把缓存的时间和业务紧密连接并根据 KeyValue 的特性(不利于范围查询、搜索等)来舍弃一些不那么必要的业务功能。

对于需要枚举 Key 的应用最好具有单独的 memcached集群。 可以基于 memcache做一些扩展,比如分布式锁等等。

Page 23: 浅谈网站架构中缓存的应用

Windows Server AppFabric Caching 什么是 Windows Server AppFabric ?

包含 Caching 和 Hosting 两部分。 增强有关 Caching 和 Hosting 的基础结构。

Windows Server AppFabric 解决的问题? 分布式缓存 持久化的工作流 监控WCF/WF 应用程序 基于 IIS 和 POWERSHELL 的管理工具

Windows Server AppFabric 的优缺点 生产环境操作系统受限于 Windows Server 2008 SP2 和 Windows Server

2008 R2 ,基本都需要依赖 .NET框架 4.0 。 功能非常完善,能做到都做了,并且可以和很多微软产品很好结合。 大多数组件和工具基于 .NET/C#/WCF 实现,不要对性能期望过多。 要 GET START非常简单,要进行一些细节项配置比较难(界面提供的配置项过于简单),好在“开源”。

Page 24: 浅谈网站架构中缓存的应用

Windows Server AppFabric Caching

• Client• Cluster• Host• Admin tool• Config Storage

Page 25: 浅谈网站架构中缓存的应用

Windows Server AppFabric Caching

编程模型 本地缓存 并发模型 高可用性 过期和清空 缓存通知

Page 26: 浅谈网站架构中缓存的应用

Windows Server AppFabric Caching

演示项目 http://velocityshop.codeplex.com/

常见模式和应用 产品分类信息 New-Cache -CacheName productCategory -Eviction None –

Expirable false 产品信息 New-Cache -CacheName product -Eviction LRU –TimeToLive 5 会话信息 New-Cache -CacheName session –TimeToLive 1440 –

Seondaries 1 基于 regoin 的存储:优势批量加载,劣势负载不够均衡 基于 listid 的存储:优势负载更均衡,劣势编程难度增加

常见使用技巧 善于使用 tag ,为缓存项关联多个 Tag ,可以查找都满足所有 Tag 的或满足任意

Tag 的项 结合 IIS 7.5 的自启动功能初始化大量起始数据 结合 .NET 4.0 并行库并行存取缓存 ASP.NET 的会话和输出缓存可以使用 AppFabric Nhibernate 和 EF 可以使用 AppFabric 作为二级缓存

Page 27: 浅谈网站架构中缓存的应用

Q&A 谢谢

http://lovecherry.cnblogs.com http://lovecindywang.cnblogs.com [email protected]