缓存技术是用来提升程序运行性能的常见手段,如你所见, 阿里巴巴、新浪微博、美团网等互联网龙头企业都是用缓存技术来提升自己家网站的性能。然而,任何事物都有两面性, 缓存技术使用得当带来的好处自然不言而喻, 但是如果使用不当, 产生的副作用也够让人喝一壶的。
我们写服务器程序时,使用缓存的目的无非就是减少数据库访问次数降低数据库的压力和提升程序的响应时间, 然而根据具体的使用场景又可以派生出无数种情况, 比如说
程序频繁读取数据库, 但是查询获得的结果却总是相同的,这部分相同的结果是不是可以放入缓存 ?
获得查询结果要进行复杂的运算,非常消耗时间, 运算结果是不是可以放入缓存 ?
有一些在网站每个页面都需要使用的数据, 比如说用户数据, 是不是可以放入缓存 ?
还有另外不胜枚举等等各种情况,概括起来就是那些变化不那么频繁, 从源头读取又显得耗费资源和性能的数据, 是不是都应该放入缓存 ?
既然身为行业技术风向标的淘宝、美团、新浪里面的技术大牛们都在使用缓存技术, 那么咱们自然也得跟上他们的脚步。 然而不知道大家有没有听到有这样一种流传甚广说法:“在选择一样东西前,请先问一下自己,我喜欢吗? 我适合吗?我需要吗?”, 具体到我们在工作中选择使用某种技术,喜欢其实不应该是左右我们选择某项技术的关键, 而合适和需要才是我们应该详细考虑的。 这个道理自然也适合于是否使用缓存技术上面。
通常来讲,狭义上的缓存仅指一些缓存软件, 如memcached或redis; 而广义上缓存不仅包括缓存软件, 程序的内存空间、static变量、磁盘文件、甚至数据库自身, 只要能用来放置临时数据提升程序性能的都可以称之为缓存。
我们在使用缓存技术提高程序性能时应该不仅仅把缓存的范围局限于狭义的缓存技术, 而应该从广义的缓存技术集合中, 结合自身程序的特点选择一种合适的缓存模式。 比如说用户信息数据,就算全都放session之中也未尝不可, 难不成用户数据会有几十上百兆不成;比如说复杂的查询结果临时放置的位置,新建一个表存放或存储在磁盘文件中亦可;比如说需要频繁读取的结果 , 如果是使用Java之类的语言, 那么放在一个static变量中也可以解决问题;以上这些都是缓存技术的应用实践。
有的同学可能会提出质疑,为什么我们非要搞这么多的花样?直接使用缓存软件不是都能解决上面这些问题吗? 然而并不是, 因为我们在享受缓存软件带来的好处的同时,却往往忽略它带来的副作用,而这些副作用在程序的开发的初期阶段往往是不会显现出来的, 到了开发后期或者部署上线至生产环境时,问题才有可能暴露出来。 举一个例子来侧面说明下
假如我们开发一个非常简单的网站应用程序,只有少量的简单数据需要存储,那么应该选择什么作为我们存储数据的介质? 关系数据库或者xml文件? 答案很显然, xml文件存储方案显然要优于关系数据库。 我们使用数据库存储数据, 那么势必需要在服务器安装数据库软件, 新建访问用户, 而且同样的事情在开发环境和生产环境都需要做一遍, 跟环境相关的东西如数据库地址、用户名、密码之类都还都需要存储在某个配置文件中, 一来二去问题就变得相对复杂了。 而存储在xml中就简单的多了, 直接在项目中建个目录存储文件就行了, 至于xml的编程接口那是任何一种技术的标准配置,根本不用自己去实现。 这样把程序部署至线上环境会方便的多, 不用考虑各种环境依赖问题。 而使用关系数据库, 对于这类简单的项目就是拿着牛刀去杀鸡,真正的威力发挥不出来, 还把问题搞的复杂 。
在某些情况下, 缓存软件和上面例子中的关系数据库其实扮演的是同一个角色 ,缓存软件真正的威力没有发挥出来, 却把程序搞的相对复杂,这不是得不偿失的做法吗?
因此, 在决定使用缓存软件前, 一定先确定上面所提的广义的缓存都没有办法满足需求了,届时再使用缓存软件才能将它能发挥的价值最大化,或可抵消使用它带来的副作用。