完成本系列的第2部分后,您现在有了一个可伸缩的数据库解决方案。你再也不用担心存储太字节了,世界看起来很美好。当从数据库中获取大量数据时,您的用户仍然不得不忍受缓慢的页面请求。解决方案是实现缓存。
对于“缓存”,我总是指内存缓存,比如Memcached或Redis。请永远不要使用基于文件的缓存,它会让克隆和自动伸缩服务器变得很痛苦。
但是回到内存缓存。缓存是一种简单的键值存储,它应该作为应用程序和数据存储之间的缓冲层存在。当您的应用程序必须读取数据时,它应该首先尝试从缓存中检索数据。只有当数据不在缓存中时,它才应该尝试从主数据源获取数据。你为什么要这么做?因为缓存是闪电般快速的。它在RAM中保存每一个数据集,并且在技术上尽可能快地处理请求。例如,当Redis托管在一个标准服务器上时,它可以每秒执行几十万次读操作。而且写入,尤其是增量,非常非常快。
有两种缓存数据的模式。一个旧的,一个新的
1 -缓存数据库查询
这仍然是最常用的缓存模式。每当对数据库进行查询时,都会将结果数据集存储在缓存中。您的查询的哈希版本是缓存键。下次运行查询时,首先检查它是否已经在缓存中。下次运行查询时,首先检查缓存是否已经有结果。这种模式有几个问题。主要问题是到期。当您缓存一个复杂的查询时,很难删除缓存的结果。当一个数据发生变化时(例如一个表格单元格),您需要删除所有缓存的查询,这些查询可能包括这个表格单元格。
2 -缓存对象
这是我强烈的建议,我一直更喜欢这种模式。通常,将数据视为一个对象,就像你在代码中已经做的那样(类、实例等)。让类从数据库中组装一个数据集,然后将该类的完整实例或组装的数据集存储在缓存中。我知道这听起来很理论化,但看看你通常是怎么编码的。例如,你有一个叫做“Product”的类,它有一个叫做“data”的属性。它是一个包含产品价格、文本、图片和客户评论的数组。属性“data”由类中的几个方法填充,这些方法执行几个数据库请求,由于许多事情相互关联,所以很难缓存。现在,做以下事情:当你的类完成了数据数组的“组装”后,直接将数据数组存储在缓存中,或者更好的是将类的完整实例存储在缓存中!这使您可以在任何更改发生时轻松地摆脱对象,并使代码的整体操作更快、更符合逻辑。
最好的部分是:它使异步处理成为可能!想象一下,有一群工作人员在为你组装物品!应用程序只使用最新的缓存对象,几乎不再接触数据库!
缓存对象的一些想法:
- 用户会话(从不使用数据库!)
- 完全渲染的博客文章
- 活动流
- 用户< - >的朋友关系
您可能已经意识到,我非常喜欢缓存。它很容易理解,执行起来也很简单,结果总是惊人的。总的来说,我更喜欢Redis而不是Memcached,因为我喜欢Redis额外的数据库特性,比如持久性和内置的数据结构,比如列表和集合。有了Redis和一个聪明的键,你甚至有可能完全摆脱数据库。但如果您只需要缓存,那么使用Memcached,因为它的伸缩性很好。
引用:
https://www.lecloud.net/post/9246290032/scalability-for-dummies-part-3-cache