系统缓存设计

写的很全面,也很深入。看完一遍不够,所以转载一下

 

1. 前言

在高访问量的web系统中,缓存几乎是离不开的;但是一个适当、高效的缓存方案设计却并不容易;所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些东西,包括缓存的选型、常见缓存系统的特点和数据指标、缓存对象结构设计和失效策略以及缓存对象的压缩等等,以期让有需求的同学尤其是初学者能够快速、系统的了解相关知识。

 

2. 数据库的瓶颈

2.1 数据量

关系型数据库的数据量是比较小的,以我们常用的MySQL为例,单表数据条数一般应该控制在2000w以内,如果业务很复杂的话,可能还要低一些。即便是对于Oracle这些大型商业数据库来讲,其能存储的数据量也很难满足一个拥有几千万甚至数亿用户的大型互联网系统。

 

2.2 TPS

在实际开发中我们经常会发现,关系型数据库在TPS上的瓶颈往往会比其他瓶颈更容易暴露出来,尤其对于大型web系统,由于每天大量的并发访问,对数据库的读写性能要求非常高;而传统的关系型数据库的处理能力确实捉襟见肘;以我们常用的MySQL数据库为例,常规情况下的TPS大概只有1500左右(各种极端场景下另当别论);下图是MySQL官方所给出的一份测试数据:

而对于一个日均PV千万的大型网站来讲,每个PV所产生的数据库读写量可能要超出几倍,这种情况下,每天所有的数据读写请求量可能远超出关系型数据的处理能力,更别说在流量峰值的情况下了;所以我们必须要有高效的缓存手段来抵挡住大部分的数据请求!

 

2.3 响应时间

正常情况下,关系型数据的响应时间是相当不错的,一般在10ms以内甚至更短,尤其是在配置得当的情况下。但是就如前面所言,我们的需求是不一般的:当拥有几亿条数据,1wTPS的时候,响应时间也要在10ms以内,这几乎是任何一款关系型数据都无法做到的。

那么这个问题如何解决呢?最简单有效的办法当然是缓存!

3. 缓存系统选型

3.1 缓存的类型

3.1.1 本地缓存

本地缓存可能是大家用的最多的一种缓存方式了,不管是本地内存还是磁盘,其速度快,成本低,在有些场合非常有效;

但是对于web系统的集群负载均衡结构来说,本地缓存使用起来就比较受限制,因为当数据库数据发生变化时,你没有一个简单有效的方法去更新本地缓存;然而,你如果在不同的服务器之间去同步本地缓存信息,由于缓存的低时效性和高访问量的影响,其成本和性能恐怕都是难以接受的。

3.1.2 分布式缓存

前面提到过,本地缓存的使用很容易让你的应用服务器带上“状态”,这种情况下,数据同步的开销会比较大;尤其是在集群环境中更是如此!

分布式缓存这种东西存在的目的就是为了提供比RDB更高的TPS和扩展性,同时有帮你承担了数据同步的痛苦;优秀的分布式缓存系统有大家所熟知的Memcached、Redis(当然也许你把它看成是NoSQL,但是我个人更愿意把分布式缓存也看成是NoSQL),还有国内阿里自主开发的Tair等;

对比关系型数据库和缓存存储,其在读和写性能上的差距可谓天壤之别;memcached单节点已经可以做到15w以上的tps、Redis、google的levelDB也有不菲的性能,而实现大规模集群后,性能可能会更高!

所以,在技术和业务都可以接受的情况下,我们可以尽量把读写压力从数据库转移到缓存上,以保护看似强大,其实却很脆弱的关系型数据库。

 

3.1.3 客户端缓存

这块很容易被人忽略,客户端缓存主要是指基于客户端浏览器的缓存方式;由于浏览器本身的安全限制,web系统能在客户端所做的缓存方式非常有限,主要由以下几种:

a、 浏览器cookie这是使用最多的在客户端保存数据的方法,大家也都比较熟悉;

 

b、 浏览器本地缓存;很多浏览器都提供了本地缓存的接口,但是由于各个浏览器的实现有差异,所以这种方式很少被使用;此类方案有chrome的Google Gear,IE的userData、火狐的sessionStorage和globalStorage等;

 

c、 flash本地存储;这个也是平时比较常用的缓存方式;相较于cookie,flash缓存基本没有数量和体积的限制,而且由于基于flash插件,所以也不存在兼容性问题;不过在没有安装flash插件的浏览器上则无法使用;

 

d、 html5的本地存储;鉴于html5越来越普及,再加上其本地存储功能比较强大,所以在将来的使用场景应该会越来越多。

 

由于大部分的web应用都会尽量做到无状态,以方便线性扩容,所以我们能使用的除了后端存储(DB、NoSQL、分布式文件系统、CDN等)外,就只剩前端的客户端缓存了。

对客户端存储的合理使用,原本每天几千万甚至上亿的接口调用,一下就可能降到了每天几百万甚至更少,而且即便是用户更换浏览器,或者缓存丢失需要重新访问服务器,由于随机性比较强,请求分散,给服务器的压力也很小!在此基础上,再加上合理的缓存过期时间,就可以在数据准确和性能上做一个很好的折衷。

3.1.4 数据库缓存

这里主要是指数据库的查询缓存,大部分数据库都是会提供,每种数据库的具体实现细节也会有所差异,不过基本的原理就是用查询语句的hash值做key,对结果集进行缓存;如果利用的好,可以很大的提高数据库的查询效率!数据库的其他一些缓存将在后边介绍。

 

3.2 选型指标

现在可供我们选择使用的(伪)分布式缓存系统不要太多,比如使用广泛的Memcached、最近炒得火热的Redis等;这里前面加个伪字,意思是想说,有些所谓的分布式缓存其实仍是以单机的思维去做的,不能算是真正的分布式缓存(你觉得只实现个主从复制能算分布式么?)。

既然有这么多的系统可用,那么我们在选择的时候,就要有一定的标准和方法。只有有了标准,才能衡量一个系统时好时坏,或者适不适合,选择就基本有了方向。

下边几点是我个人觉的应该考虑的几个点(其实大部分系统选型都是这么考虑的,并非只有缓存系统):

 

3.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值