今天翻译一篇关于缓存策略的文章,原文标题是Cacheing Strategies and How to Choose the Right One,朋友推荐看的,以为总结的不错,鉴于不少朋友都懒得看英文的,因此皮皮就用蹩脚的水平试着翻译一波,如何以为还凑合,能够帮忙转发一下让更多的人看到。数据库
缓存是提升系统性能的最简单方法之一。相对而言,数据库(or NoSQL数据库)的速度比较慢,而速度却每每又是制胜的关键。缓存
若是使用得当,缓存能够减小相应时间、减小数据库负载以及节省成本。本文罗列了几种缓存策略,选择正确的一种会有很大的不一样。缓存策略取决于数据和数据访问模式。换句话说,数据是如何写和读的。例如:服务器
系统是写多读少的吗?(例如基于时间的日志)ide
数据是不是只写入一次并被读取屡次?(例如用户配置文件)性能
返回的数据老是唯一的吗?(例如搜索查询)翻译
选择正确的缓存策略是提升性能的关键。让咱们快速了解一下各类缓存策略。日志
这多是最经常使用的缓存方法。缓存位于一边,应用程序直接与缓存和数据库对话。cdn
简要解释一下:blog
应用程序首先检查缓存。内存
若是在缓存中找到,表示已经命中缓存。数据被读取并返回给应用程序。
若是在缓存中没有找到,则未命中缓存。应用程序必须作一些额外的工做,它须要查询数据库来读取数据,将数据返回给客户端,而后还要将数据存储在缓存中,这样对相同数据的后续读取能够命中缓存。
Cache-aside策略特别适合读多的应用场景。使用Cache-aside的系统对缓存失效具备必定的弹性。若是缓存集群宕机,系统仍然能够经过直接访问数据库进行操做。(不过,若是缓存在峰值负载期间降低,这也没有多大帮助。响应时间可能会变得很糟糕,最糟糕的状况是,数据库可能会中止工做。)
另外一个优势在于缓存中的数据模型能够与数据库中的数据模型不一样。例如,多个查询产生的响应能够存储在某个请求id上。
当使用cache-aside时,最多见的写策略是直接将数据写到数据库中。当这种状况发生时,缓存可能与数据库不一致。为了解决这个问题,开发人员一般会引入TTL,并继续提供陈旧的数据,直到TTL过时。若是必须保证数据的新鲜度,开发人员要么使缓存条目无效,要么使用适当的写策略,咱们将在后面讨论。
Read-though策略下的缓存与数据库保持一致。当缓存丢失时,它从数据库加载相应的数据,填充缓存并将其返回给应用程序(参考下图)。
cache-aside和read-through策略都是延迟加载数据的,也就是说,只在第一次读取数据时才加载数据。
虽然read-through和cache-aside很是类似,但至少有两个关键区别:
在cache-aside中,应用程序负责从数据库中获取数据并填充缓存。在read-through中,此逻辑一般由库或独立缓存提供程序支持。
与cache-aside不一样,read-through cache中的数据模型不能与数据库中的数据模型不一样。
当屡次请求相同的数据时,read-through缓存最适合于读量较大的工做负载。例如,一个新闻故事。缺点是,当第一次请求数据时,它老是致使缓存丢失,并致使额外的数据加载到缓存的代价。开发人员经过手动发出查询来“预热”或“预热”缓存来处理这个问题。就像cache-aside同样,数据也可能在缓存和数据库之间变得不一致,而解决方案就在写策略中,咱们将在接下来看到这一点。
在这种写策略中,首先将数据写入缓存,而后写入数据库。缓存与数据库保持一致,写操做老是经过缓存到达主数据库。
在这种写策略中,首先将数据写入缓存,而后写入数据库。缓存与数据库保持一致,写操做老是经过缓存到达主数据库。
就其自己而言,write-through缓存彷佛没有多大做用,实际上,它们引入了额外的写延迟,由于数据先写到缓存,而后写到主数据库。可是,当与read-through结合使用时,咱们得到了read-through的全部好处,还得到了数据一致性保证,使咱们没必要使用缓存失效技术。
DynamoDB Accelerator (DAX)是write-through / read-through cache的一个很好的例子。它与DynamoDB和应用程序内联。对DynamoDB的读写能够经过DAX完成。(附注:若是您计划使用DAX,请确保熟悉它的数据一致性模型以及它如何与DynamoDB交互。)
这种策略下,数据直接写入数据库,只有读取的数据才能进入缓存。Write-around能够与read-through结合使用,并在数据只写一次、读取次数较少或从不读的状况下提供良好的性能。例如,实时日志或聊天室消息。一样,这个模式也能够与cache-aside组合使用。
这种策略下,应用程序将数据写入缓存,缓存会当即确认,并在延迟一段时间后将数据写入数据库。有时这种策略也被称为write-behind。
Write-back缓存提升了写性能,对于写工做量大的工做负载很是有用。当与read-through相结合的时候,它对于混合工做负载很是有效,最近更新和访问的数据老是在缓存中可用。它对数据库故障具备很大程度上的弹性,能够容忍一些数据库的宕机。若是支持批处理或合并,则能够减小对数据库的整体写操做,这将减小负载并下降成本。
一些开发人员使用Redis时,同时采用了cache-aside和write-back两种策略,以便更好地吸取峰值负载期间的峰值。主要缺点是,若是缓存失效,数据可能会永久丢失。大多数关系数据库存储引擎(例如InnoDB)的内部都默认启用了回写缓存。查询首先写入内存,最后刷新到磁盘。
在本文中,咱们探讨了不一样的缓存策略及其优缺点。在实践中,请仔细评估您的目标,理解数据访问(读/写)模式,并选择最佳策略或组合策略。
若是你选错了怎么办?一个与你的目标或访问模式不匹配的?您可能会引入额外的延迟,或者至少没有看到所有的好处。例如,若是在实际应该使用write-around/read-through时选择write-through/read-through(访问写入数据的频率较低),那么缓存中就会有无用的垃圾。能够说,若是缓存足够大,它可能没问题。但在许多实际的高吞吐量系统中,当内存永远不够大而且须要考虑服务器成本时,正确的策略很重要。