为什么我们需要缓存?
很久很久以前,在还没有缓存的时候……用户经常是去请求一个对象,而这个对象是从数据库去取,然后,这个对象变得越来越大,这个用户每次的请求时间也越来越长了,这也把数据库弄得很痛苦,他无时不刻不在工作。所以,这个事情就把用户和数据库弄得很生气,接着就有可能发生下面两件事情:
- 用户很烦,在抱怨,甚至不去用这个应用了(这是大多数情况下都会发生的)
- 数据库为打包回家,离开这个应用,然后,就出现了大麻烦(没地方去存储数据了)(发生在极少数情况下)
上帝派来了缓存
在几年之后,IBM(60年代)的研究人员引进了一个新概念,它叫“缓存”。
什么是缓存?
正如 part 1 的开头,缓存是“存贮数据(使用频繁的数据)的临时地方,因为取原始数据的代价太大了,所以我可以取得快一些。”
缓存可以认为是数据的池,这些数据是从数据库里的真实数据复制出来的,并且为了能别取回,被标上了标签(键ID)。
太棒了!programmer one已经知道这点了,但是他还不知道下面的缓存术语。
命中:
当客户发起一个请求(我们说他想要查看一个产品信息),我们的应用接受这个请求,并且如果是在第一次检查缓存的时候,需要去数据库读取产品信息。
如果在缓存中,一个条目通过一个标记被找到了,这个条目就会被使用,我们就叫它缓存命中。所以,命中率也就不难理解了。
Cache Miss:
(这个Cahe Miss不知道用什么词翻译合适,但是大家都知道的)。但是这里需要注意两点:
- 如果还有缓存的空间,那么,没有命中的对象会被存储到缓存中来。
- 如果缓存慢了,而又没有命中缓存,那么就会按照某一种策略,把缓存中的旧对象踢出,而把新的对象加入缓存池。而这些策略统称为替代策略(缓存算法),这些策略会决定到底应该提出哪些对象。
存储成本:
当没有命中时,我们会从数据库取出数据,然后放入缓存。而把这个数据放入缓存所需要的时间和空间,就是存储成本。
索引成本:
和存储成本想法。
失效:
当存在缓存中的数据需要更新时,就意味着缓存中的这个数据失效了。
替代策略:
当缓存没有命中时,并且缓存容量已经满了,就需要在缓存中踢出一个老的条目,加入一条新的条目,而到底应该踢出什么条目,就由替代策略决定。
最有替代策略:
最优的替代策略就是想把缓存中最没用的条目给踢出去,但是未来是不能够被预知的,所以这种策略是不可能实现的。但是有很多策略,都是朝着这个目前去努力。
Java街恶梦:
当programmer one在读这篇文章的时候,他睡着了,并且做了个恶梦(每个人都有做恶梦的时候)。
programmer one:nihahha,我要把你弄失效!(疯狂的状态)
缓存对象:别别,让我活着,他们还需要我,我还有孩子。
programmer one:每个缓存对象在失效之前都会那样说。你从什么时候开始有孩子的?不用担心,现在就永远消失吧!
哈哈哈哈哈……programmer one恐怖的笑着,但是警笛打破了沉静,警察把programmer one抓了起来,并且控告他杀死了(失效)一个仍需被使用的缓存对象,他被押到了监狱。
programmer one突然醒了,他被吓到了,浑身是汗,他开始环顾四周,发现这确实是个梦,然后赶紧继续阅读这篇文章,努力的消除自己的恐慌。