随着网络的发展,数据越来越多,从而导致运算压力越来越大,为了解决这个问题,就需要合理的分级计算机资源,充分利用已有资源。缓存的工作实际上就是资源的合理分配。
一个网站或者应用的一般形式是:浏览器发应用请求,应用服务器做一堆计算和逻辑判断后再向数据存储层发出请求,数据存储层收到请求后再通过计算把数据返回给应用服务器,应应用服务器再次计算后把数据返回给浏览器。这是标准流程。
一、为什么使用缓存
随着web业务的复杂和并发的增加,应用服务器和数据库服务器所做的计算越来越多。怎样利用有限的资源提供尽可能大的吞吐量,这是我们需要解决的问题。
一个办法:减少计算量,缩短请求流程,这里缓存就可以大显身手了。缓存的基本原理就是打破标准流程,在标准流程中任何环节都可以被切断。请求可以从缓存中取得数据直接返回。这样能够节省时间、提高相应速度、节省硬件资源,可以让有限的硬件资源服务更多用户。
二、缓存层次
在web中,理论上每一层都可以被缓存,这些缓存进行一些层次划分,如下:
①底层有CPU缓存、磁盘文件系统缓存;
②应用层有Zend虚拟机的变量缓存、有memcached这样的key-value内存缓存,有APC、eAccelerator这类基于opcode字节码的缓存;
③数据库有Table Cache、Thread cache、query cache;
④Servlet容器有Apache的缓存;
⑤servlet再上去一点,有一个web cache层(如squid、Varnish等),然后应用程序代码级别的smarty实现的文件缓存。
此外,NoSQL缓存(NoSQL不是not sql,而是Not only SQL),包括Memcached、Cassandra、MongoDB、Redis、Tokyo Tyrant等产品。NoSQL同样是一种存储数据的数据库,主要基于内存和key-value模式。
缓存存放在内存和硬盘。文件缓存存放在硬盘上,而一些需要高速存取的变量则缓存在内存中。通常来说,缓存组件都是同时结合内存和硬盘的,当内存满后,把大部分数据持久化存储到硬盘,或者定期dump把内存的数据写入硬盘,防止数据丢失。
缓存有三要素:命中率、缓存更新策略、缓存最大数据量。
三、命中率
通过命中率衡量缓存机制的好坏和效率。命中率指请求缓存次数和缓存返回正确结果次数的比例。比例越高,证明缓存的使用率越高。需要注意的是,如果数据频繁更新,就需要考虑缓存的合理性。因为缓存更新会使命中率大大降低,当命中率比较低,缓存不仅不能提高效率,反而可能会造成负面影响。
四、缓存更新策略
缓存的容器都有大小限制,我们在对数据进行缓存的过程中,最后达到缓存可以容纳的极限;或者我们对原有的数据进行了操作,操作包括新增、修改、删除等;这个时候就必须考虑缓存内容更新问题。缓存更新策略归纳为以下几种:
①FIFO:first in first out。最先进入缓存的数据在缓存空间不够情况下会被首先清空出去;
②LFU:less Frequently Used。最少使用的元素会被清理丢。这要求缓存的元素有hit属性,在缓存空间不够的情况下,hit值最小的将会被清除缓存;
③FRU:least Recently Used。最近最少使用的元素被清理。缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出缓存的地方,现有的缓存元素中时间戳离当前时间最远的元素将被清空出缓存。
五、缓存的最大数据量
缓存最大数据量是在缓存中能处理元素的最大个数或所能使用的最大存储空间。通常各种缓存机制都会对缓存最大数据量进行限制,可以是固定大小的存储空间、集合个数,或者由操作系统所能分配和处理的存储空间决定。
例如mysql的Query cache缓存最大数据量由query_cache_size参数决定,可以修改;而基于内存的key-value实施方案Memcached,其缓存最大数据量可使用内存由操作系统决定,默认为64MB,每次最大可申请内存为2M.
超过缓存机制所允许的最大数据量系统会进行相应处理,一般有四种处理方式:
①停止缓存服务,所有缓存数据被清空;
②拒绝写入,不再对缓存数据进行更新;
③根据缓存更新策略清空旧数据;
④在方式3基础上,将淘汰的数据备份,腾出新的空间。
在实际的应用中,通常以方式3和4最为常见。