01 没缓存的日子
文章插图
对于web来说,是用户量和访问量支持项目技术的更迭和前进 。随着服务用户提升 。可能会出现一下的一些状况:
页面并发量和访问量并不多,MySQL足以支撑自己逻辑业务的发展 。那么其实可以不加缓存 。最多对静态页面进行缓存即可 。
页面的并发量显著增多,数据库有些压力,并且有些数据更新频率较低反复被查询或者查询速度较慢 。那么就可以考虑使用缓存技术优化 。对高命中的对象存到key-value形式的redis中,那么,如果数据被命中,那么可以省经效率很低的db 。从高效的redis中查找到数据 。
当然,可能还会遇到其他问题,你可以需要静态页面本地缓存,cdn加速,甚至负载均衡这些方法提高系统并发量 。这里就不做介绍 。
02 缓存思想无处不在
我们从一个算法问题开始了解缓存的意义 。
问题1:输入一个数n(n<20),求n!;
分析1:单单考虑算法,不考虑数值越界问题 。当然我们知道n!=n * (n-1) * (n-2) * ... * 1= n * (n-1)!;那么我们可以用一个递归函数解决问题 。
文章插图
这样每输入求一次需要执行n次 。
问题2:输入t组数据(可能成百上千),每组一个x(n<20),求x!;
分析2:
文章插图
文章插图
时间复杂度才O(n) 。这里的思想就和缓存思想差不多 。先将数据在jiecheng[21]数组中储存 。执行一次计算 。当后面继续访问的时候就相当于当问静态数组值 。为O(1) 。就能大大的减少查询、执行成本啦!
03 缓存的应用场景
文章插图
缓存适用于高并发的场景,提升服务容量 。主要是将从经常被访问的数据或者查询成本较高从慢的介质中存到比较快的介质中,比如从硬盘—>内存 。我们知道大多数关系数据库是基于硬盘读写的,其效率和资源有限,而redis等非关系型就是基于内存存储 。其效率差别很大 。当然,缓存也分为本地缓存和服务端缓存,这里只讲redis的服务端缓存 。
举个例子 。例如如果一个接口sql查询需要2s 。你每次查询都会2s并且加载的时候都会等在,这个长期等待给用户的体验是非常糟糕的 。而用户能够接受的往往是第一次的等待 。如果你用了缓存技术 。你第一次查询放到redis里面 。然后数据再从redis返回给你 。后面当你继续访问这个数据的时候 。查询到redis中有备份,那么不需要通过db直接能从redis中获取数据 。那么,你想想,从一个key value的Nosql中取一个value能要多久呢!
所以对于像样的,有点规模的网站,缓存isnecessary的.redis也是必不可少的 。并且服务端的缓存设计也是要根据业务有所区别的 。也要防止占用内存过大,redis雪崩等问题 。
04 需要注意的问题
缓存使用不当会带来很多问题 。所以需要对一些细节进行认真考量和设计 。笔者对于分布式的经验并不是很丰富,就相对于笔者的眼中谈谈缓存设计不好会带来那些问题 。
(1)是否用缓存
现在不少项目,为了缓存而缓存,然而缓存并不是适合所有场景,比如如果对数据一致性要求极高,又或者数据频繁更改而查询并不多 。有的可以不需要缓存 。因为如果使用redis缓存多多少少可能会遇到数据一致性问题 。那你可以考虑使用redis做成分布式锁去锁sql的数据 。同样如果频繁更新数据,那么redis能起到的作用就仅仅是多了一层中转站 。反而浪费资源 。使得传输过程臃肿 。
(2)过期策略选择
大部分场景不适合缓存一致存在,首先,你的sql数据库的内容可能很多就不说了,另外,返回给你的对象如果是完整的pojo对象还好,但是如果是使用不同参数各种关联查询出来的结果那么redis中会储存太多冷数据 。占用资源而得不到销毁 。我们学过操作系统也知道在计算机的缓存实现中有)先进先出的算法(FIFO);最近最少使用算法(LRU);最佳淘汰算法(OPT);最少访问页面算法(LFR)等磁盘调度算法 。对于web开发也可以借鉴 。根据时间来的FIFO是最好实现的 。因为redis在全局key支持过期策略 。
而开发中可能还会遇到其他问题 。比如过期时间的选择上,如果过久会导致数据聚集 。而过少可能导致频繁查询数据库甚至可能会导致缓存雪崩等问题 。
推荐阅读
- 八宅风水图解具体解析
- 详细解析茶叶冲泡十三道
- Python 解析 XML 数据的正确姿势
- 如何用Redis实现购物车的增删改和清空
- Redis数据淘汰算法
- 浅析浏览器缓存
- MIUI团队:MIUI支持清理微信缓存
- 高考材料作文新题解析及范文 高考材料作文
- 使用redis作为消息队列的用法
- Redis批量删除key的小技巧,你知道吗?