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

简介: 云计算设计模式(一)——缓存预留模式 根据需求从数据存储缓存加载数据。这种模式可以提高性能,并有助于维持在基础数据存储在高速缓存中保持的数据和数据之间的一致性。

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


根据需求从数据存储缓存加载数据这种模式可以提高性能,并有助于维持基础数据存储在高速缓存中保持的数据和数据之间的一致性。



背景和问题



应用程序使用的高速缓存来优化重复访问数据存储中保持的信息然而,它通常是不切实际的期望缓存的数据将始终与在数据存储器中的数据完全一致。应用程序要实现一种策略,有助于确保高速缓存中的数据是最新的,只要有可能,可以检测和处理的过程中出现,当在高速缓存中的数据已经变得陈旧的情况。

解决方案



许多商业缓存系统提供通读直写式/后写操作。在这些系统中,应用程序通过引用高速缓存中检索数据如果数据不在缓存中被透明地从数据存储中检索并添加到高速缓存任何修改在高速缓存中保持的数据被自动地写入到数据存储区以及。

缓存提供此功能,则使用该缓存保持高速缓存中的数据的应用程序的责任。

一个应用程序可以通过实现高速缓存预留战略模拟式高速缓存的功能。这种策略有效地将数据加载需求高速缓存图1总结了该过程中的步骤。

图1  - 使用Cache-除了图案将数据存储在高速缓冲存储器


如果一个应用程序将更新的信息,可以模拟通写策略如下:
1.根据修改到数据存储
2.作废对应的在缓存中。

该项目被下一个需要,可使用高速缓存预留策略将导致从数据存储中检索重新添加到高速缓存中的更新数据



问题和注意事项



在决定如何实现这个模式时,请考虑以下几点
缓存数据的生命周期很多缓存实现一个过期策略,导致数据无效,并从缓存中移除如果它不是在指定时间内访问。对于缓存一边是有效的确保了过期策略相匹配的访问用于使用数据的应用程序的模式。不要使有效期限太短,因为这会导致应用程序不断地从数据存储中检索数据,并将其添加到缓存中。同样,不要使保质期这么久,缓存的数据很可能会变得陈旧记住,缓存是最有效的相对静态的数据或者数据频繁地读出。
驱逐数据高速缓存具有其中数据源自数据存储区只有有限的大小并在必要时它们将收回的数据。大多数缓存采用最近最少使用的政策选择项目驱逐但是这可能是定制的。配置全局到期属性高速缓存的其它性能并且每个高速缓存的到期属性以帮助确保缓存成本效益。可能并不总是适合于高速缓存中的应用全球驱逐政策,每一个项目例如,如果缓存项非常昂贵的,从数据存储中检索,也可能是有益的,保留频繁地访问但不昂贵的物品费用此产品的高速缓存中
灌注缓存许多解决方案,预填充的应用程序可能需要作为启动处理的一部分数据高速缓存。如果某些数据已到期,被驱逐缓存除了图案可能仍然是有用的
•一致性执行缓存除了图案不保证数据存储高速缓存之间的一致性。在数据存储中的项目可以在任何时候被改变由外部的过程中,这种变化可能不反映在高速缓存中的项目被装载到高速缓存,直到下一次一个系统,整个数据存储复制数据,如果同步发生非常频繁这个问题可能会变得尤为突出
•本地(内存缓存缓存可以是本地的应用程序实例,并存储在内存中缓存预留如果应用程序多次访问相同的数据可以在该环境中是有用的。然而本地高速缓存是私有的,因此不同的应用程序实例各自具有相同的缓存数据的副本。数据可能很快变成高速缓存之间不一致,所以可能有必要到期专用高速缓存中保存的数据更经常地刷新。这些场景中可能是适当的,调查使用了共享或分布式缓存机制。

使用这个模式



使用这种模式
缓存不提供原生通过,并通过写操作。
•资源的需求是不可预测的这种模式使应用程序能够按需加载数据它使任何假设有关的数据的应用程序将需要提前

这种模式可能不适合
•当缓存的数据集是静态的。如果数据适合可用的高速缓存空间首要高速缓存中的数据在启动应用,防止数据政策
对于托管在Web场中的Web应用程序缓存会话状态信息在这种环境下应该避免引入基于客户端 - 服务器关系的依赖

例子



微软的Azure,您可以使用Azure的缓存来创建一个分布式缓存,可以通过一个应用程序的多个实例可以共享下面的代码示例中的GetMyEntityAsync方法给出了基于Azure的缓存Cache后备模式的实现方法从利用读虽然方法缓存中的对象。

一个目的确定一个整数ID作为键。GetMyEntityAsync方法生成基于此键在Azure缓存API使用键值字符串)的字符串值,并尝试检索与从缓存中这一关键的项目。如果匹配的项目被发现被返回。如果在缓存中没有匹配,则GetMyEntityAsync方法从一个数据存储中的对象时,把它添加到缓存中,然后将其返回(即实际上获得从数据存储中的数据代码已经被省略,因为数据存储依赖注意,缓存项被配置防止其成为陈旧如果是在别处更新过期。

private DataCache cache;
...

public async Task<MyEntity> GetMyEntityAsync(int id)
{  
  // Define a unique key for this method and its parameters.
  var key = string.Format("StoreWithCache_GetAsync_{0}", id);
  var expiration = TimeSpan.FromMinutes(3);
  bool cacheException = false;

  try
  {
    // Try to get the entity from the cache.
    var cacheItem = cache.GetCacheItem(key);
    if (cacheItem != null)
    {
      return cacheItem.Value as MyEntity;
    }
  }
  catch (DataCacheException)
  {
    // If there is a cache related issue, raise an exception 
    // and avoid using the cache for the rest of the call.
    cacheException = true;
  }

  // If there is a cache miss, get the entity from the original store and cache it.
  // Code has been omitted because it is data store dependent.  
  var entity = ...;

  if (!cacheException)
  {
    try
    {
      // Avoid caching a null value.
      if (entity != null)
      {
        // Put the item in the cache with a custom expiration time that 
        // depends on how critical it might be to have stale data.
        cache.Put(key, entity, timeout: expiration);
      }
    }
    catch (DataCacheException)
    {
      // If there is a cache related issue, ignore it
      // and just return the entity.
    }
  }

  return entity;
}


注意:

示例使用了Azure的缓存API来访问存储和检索缓存信息。有关Azure的缓存API的更多信息请参阅MSDN上使用微软的Azure缓存

下面所示的UpdateEntityAsync方法说明如何在高速缓存中的对象无效,当该值是由应用程序改变。这是一个写通方法的实例。该代码更新原始数据存储,然后通过调用Remove方法指定键(这部分功能的代码已经被省略了,因为这将数据存储相关)从缓存中删除缓存项


注意:

在这个序列中的步骤的次序是重要的。如果之前缓存更新被删除,对于客户端应用程序中的数据存储中的项目之前获取数据因为它没有在高速缓存中发现的)的机会已经改变一个小窗口,从而在缓存包含过期数据

public async Task UpdateEntityAsync(MyEntity entity)
{
  // Update the object in the original data store
  await this.store.UpdateEntityAsync(entity).ConfigureAwait(false);

  // Get the correct key for the cached object.
  var key = this.GetAsyncCacheKey(entity.Id);

  // Then, invalidate the current cache object
  this.cache.Remove(key);
}

private string GetAsyncCacheKey(int objectId)
{
  return string.Format("StoreWithCache_GetAsync_{0}", objectId);
}


本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn589799.aspx

目录
相关文章
|
3天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
5天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3月前
|
存储 安全 JavaScript
云计算浪潮中的网络安全之舵探索Node.js中的异步编程模式
【8月更文挑战第27天】在数字化时代的风帆下,云计算如同一片广阔的海洋,承载着企业与个人的数据梦想。然而,这片海洋并非总是风平浪静。随着网络攻击的波涛汹涌,如何确保航行的安全成为了每一个船员必须面对的挑战。本文将探索云计算环境下的网络安全策略,从云服务的本质出发,深入信息安全的核心,揭示如何在云海中找到安全的灯塔。
|
21天前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
18 3
|
27天前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
51 4
|
2月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
2月前
|
设计模式 Java Spring
spring源码设计模式分析-代理设计模式(二)
spring源码设计模式分析-代理设计模式(二)
|
23天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
31 0