云计算设计模式翻译:Cache-Aside Pattern

这个手册其实老早就搞到了,只是最近实在太懒了一直没动- - ,希望能坚持把主要的内容翻译完。翻译的过程中会加入一些自己的看法,如果有不准确或错误的地方欢迎各种提意见指出~。

简单来说就是将数据从持久化存储中加载到cache中。这个模式可以提升系统性能,并且保证cache和底层存储中数据的一致性。PS:下文会用“存储空间”来表示data store,在实际的工程中可以代表数据库、文件等持久化到硬盘的存储容器。

Context and Problem 

传统的应用程序中经常使用cache来优化那种需要频繁、重复地访问存储中数据的情景。但一般情况下很难使cache中的数据与底层存储中的数据达到完全一致性。程序中必须实现一种策略,不仅能够使得cache中的数据尽可能与存储器中的数据同步,同时当cache中的数据变得陈旧(不同步)时能够感知并进行正确的处理。

Solution 

很多商业的缓存系统提供了穿透读(read-through)和穿透写(write-through)/write-behind(http://www.infoq.com/cn/articles/write-behind-caching/ 
这篇文章把write-behind讲得挺透彻的)。在这些系统中,应用程序都通过缓存来检索/读取数据,如果缓存中不存在所需要的数据,那么缓存会以一种对应用程序透明的方式来从存储器中取出数据并添加到缓存中。此外,任何对数据的改动都会在缓存中进行,而缓存会自动地将这些改动写到存储器中。

而对于那些不提供这些功能的cache来说,应用程序必须自己来维护缓存中的数据:

数据读取:

应用程序可以通过实现read-through策略来达到相同的效果,这种策略在需要将数据加载到cache中时会非常有效,Figure 1 总结了一下这个过程的步骤:

1.检查所要读取的数据是否在缓存中。

2.如果数据不在缓存中,就直接从存储空间中读取数据,将数据返回给应用程序。

3.将这份数据也同时保存到缓存中。

数据写入:

如果应用程序需要写入/更新数据,那么可以通过以下步骤来实现write-through:

1.先修改存储空间中的数据。

2.如果缓存中有对应数据,那么将该数据置为无效(抛弃)。如果之后用到这部分数据,那么缓存会再次从存储空间中加载数据。

Issues and Considerations 

当使用这一模式时需要注意以下几点:

1.缓存数据的生命周期。很多缓存实现了一种数据失效规则,即当数据在一个指定的时间内没有被使用时,就会被从缓存中移除。在实际使用中这种规则必须要根据应用程序访问数据的特性来好好设计,以使得缓存在系统中发挥最大作用。比如说不能将这个失效时间设置得过短,否则会导致应用程序频繁地访问存储空间,从存储空间加载数据并将数据插入到缓存。相应的也不应该将失效时间设置得过长,否则会导致缓存中保留许多非热点数据,造成存储空间的浪费。缓存中存放不变的并且会被频繁使用的数据时会发挥其最大作用。

2.缓存数据的清除(抛弃)。绝大多数缓存容量相比存储空间来说要小得多,所以缓存中只能存放相对来说极为有限的数据量,于是在必要的时候,缓存会对数据做清除动作。绝大多数缓存实现了least-recently-used策略来选择那些需要被清除的数据(即最近一段时间用的最少的数据会被清理出去),但这通常来说也是可以定制化的,通过配置缓存的全局数据超时时间等配置项,以及指定单条数据的超时时间,可以使缓存达到最高效率。此外,使用一个全局的缓存数据清除策略有的时候也并不是很合适,比如说有些数据重载代价非常高,那么相对一些使用频率相对来说较高,但重载开销较低的数据来说,这种数据更有必要保存在缓存里。

3.数据一致性。实现这一模式并不保证缓存中的数据和存储空间中的数据能实现一致性。存储空间中的数据很有可能在任意时间被其他进程所修改,此时在缓存中的这份数据不会做同步,除非之后能有操作使得这部分数据从存储空间中重新加载。如果系统频繁地在不同存储空间之间同步数据,那么这一问题会格外严重。

4.本地缓存。对于一个应用程序来说,缓存可以是在本地或者直接基于内存来实现的(原文中着重说明这点是因为在集群中存在利用分布式缓存(即非本地性缓存)或系统采用多层次分层存储(内存-SSD-硬盘),这里所指本地缓存应该指的仅仅是应用程序内部的缓存,比如说在同一个JVM内,并不包括不同进程但在同一物理节点的情况),这种情景下对于频繁读的业务来说,Cache-Aside模式能达到最好的效果。然而,本地内存是私有的,不同的应用程序实例(进程)都保有各自私有的缓存,这很容易造成数据的不一致,所以这种情况下需要将数据的失效时间设短,从而提高从存储空间中同步数据的频率。对于这种情况可以参考一下分布式缓存的实现原理。

PS:最近的确有和同事讨论过相关的话题,缓存这东西随着storm、spark的兴起作用不仅越来越重要,扮演的角色也从一个辅助者转正上位成了主角,是整体系统设计中一个很重要的点。相对于memcache、redis这种成熟的分布式缓存而言,伴随着spark而出现的tachyon似乎又开拓了一个新的路子。我个人是对tachyon中基于ramdisk以及lineage两个主要特色比较欣赏的。然而lineage这种策略有其优点,但也有很多场景并不是很适用。相反,我倒是很看好ramdisk在分布式缓存中扮演的角色。总而言之,期待社区在缓存这块的进步与发展~

时间: 2024-10-14 12:57:47

云计算设计模式翻译:Cache-Aside Pattern的相关文章

云计算设计模式翻译(五):Compute Resource Consolidation Pattern

这个模式所做的事情概括一下就是把多个不同的任务和操作合并到一个计算单元中,从而使云计算应用提高计算资源利用率,降低管理开销和任务之间连接交互的开销. PS:我这里对后文中所翻译的"计算单元"做个小小的注释,这里的计算单元可以认为是逻辑的运行容器,可以是基于cgroup的各种container,也可以是像Storm中的worker,Spark中的Executor等等.这个模式除了在自己设计分布式系统时能作为参考,在使用像Storm或Spark这样的框架时也很具有参考意义,可以帮助配置优化

云计算设计模式翻译(三):Compensating Transaction Pattern(事务修正模式)

先说明一下:这个模式的中文我一直找不到一个比较恰当的中文来表述,姑且在本文中称之为事务修正模式吧,如果各位觉得有更合适的称呼欢迎提出. 这个模式指的是对于一个由一系列步骤组成.并遵循最终一致性的操作来说,如果一个或多个中间步骤发生错误,那么就必须要对这次操作的步骤进行撤销.对于一个实现了复杂业务逻辑和工作流的云端应用来说,遵循最终一致性的操作随处可见,所以本模式应用场景还是比较多得. Context and Problem 运行在云端的应用程序通常会频繁地修改数据,而这些数据通常会在分布在不同物

云计算设计模式翻译(二):Circuit Breaker Pattern(断路器模式)

当连接使用远端服务或资源时,可能需要花不少精力来做好错误处理.这个模式可以有效提高程序的稳定性和弹性. Context and Problem 在像云这种分布式的环境中,应用程序的操作经常访问远端的资源和服务.然而这类操作有可能因为网络响应慢.超时.资源暂时不可用等瞬时性故障(transient faults)而失败.这些故障通常情况下会在一小段时间后自动恢复,而对于一个好的云应用来说,必须要有一个好的策略(比如尝试重试)来处理这种情况. 但是有时候错误是由一些难以预期的异常事件导致的,这种情况

云计算设计模式翻译(四):Competing Consumers Pattern(消费者竞争模式)

简单地来说,这个模式能够使多个并行的consumer处理同一个信道中收到的消息,从而使系统能够并发地处理大量消息来优化系统的吞吐量,提高系统的可扩展性和可用性,平衡负载. Context and Problem 一般来说,一个运行在云端的应用通常都需要处理大量的请求.相比于同步的方式来处理每一个请求来说,一个更加通用的技术是实现一个消息系统来实现异步地处理各个请求.另外,这种策略也能够使得业务逻辑不会在某个请求正在被处理时阻塞. 在系统运行过程中,有很多种原因会导致系统所处理的请求数量发生巨大变

云计算设计模式(二十一)——Sharding分片模式

云计算设计模式(二十一)——Sharding分片模式 将一个数据存储到一组水平分区或碎片.存储和访问大量数据时,这个模式可以提高可扩展性. 背景和问题 由一个单一的服务器托管的数据存储区可能会受到以下限制:•存储空间.一种数据存储为一个大型云应用可以预期含有数据量巨大,可以随着时间的推移显著增加.服务器通常提供的磁盘存储仅是有限的,但它可以是能与较大的取代现有的磁盘,或者添加另外的磁盘的机器作为数据量的增加.然而,由此,不能够容易地增加一个给定的服务器上的存储容量的系统最终将达到一个硬限制.•计

云计算设计模式(一)——缓存预留模式

云计算设计模式(一)--缓存预留模式 根据需求从数据存储缓存加载数据.这种模式可以提高性能,并有助于维持在基础数据存储在高速缓存中保持的数据和数据之间的一致性. 背景和问题 应用程序使用的高速缓存来优化重复访问的数据存储中保持的信息.然而,它通常是不切实际的期望缓存的数据将始终与在数据存储器中的数据完全一致.应用程序要实现一种策略,有助于确保在高速缓存中的数据是最新的,只要有可能,但也可以检测和处理的过程中出现,当在高速缓存中的数据已经变得陈旧的情况. 解决方案 许多商业缓存系统提供通读和直写式

云计算设计模式(八)——外部配置存储模式

云计算设计模式(八)--外部配置存储模式 移动配置信息从应用部署包到一个集中位置.这个模式可以提供机会,以便管理和配置数据的控制,以及用于跨应用程序和应用程序实例共享的配置数据. 背景和问题 大多数应用程序运行时环境包括位于应用程序文件夹内的在部署应用程序文件保持配置信息.在某些情况下也能够编辑这些文件来改变该应用程序的行为,它已经被部署之后.然而,在许多情况下,改变配置所需要的应用程序被重新部署,从而导致不可接受的停机时间和额外的管理开销. 本地配置文件还配置限制为单个应用程序,而在某些情况下

设计模式之适配器模式(Adapter Pattern)

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 1. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 模式中的角色 2.1 目标接口(Target):客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口. 2.2 需要适配的类(Adaptee):需要适配的类或适配者类. 2.3 适配器(Adapter):通过包装一个需要适配的对象,把

云计算设计模式(二十四)——仆人键模式

云计算设计模式(二十四)——仆人键模式 使用一个令牌或密钥,向客户提供受限制的直接访问特定的资源或服务,以便由应用程序代码卸载数据传输操作.这个模式是在使用云托管的存储系统或队列的应用中特别有用,并且可以最大限度地降低成本,最大限度地提高可扩展性和性能. 背景和问题 客户端程序和网络浏览器经常需要读取和写入文件或数据流,并从一个应用程序的存储空间.通常,应用程序将处理的运动数据,或者通过从存储读取它,并将其传输到客户端,或通过从客户机读取该载流并将其存储在数据存储中.然而,这种方法吸收了宝贵的资