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


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


    依据需求从数据存储缓存载入数据这样的模式能够提高性能,并有助于维持基础数据存储在快速缓存中保持的数据和数据之间的一致性。



    背景和问题



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

    解决方式



    很多商业缓存系统提供通读直写式/后写操作。在这些系统中,应用程序通过引用快速缓存中检索数据假设数据不在缓存中被透明地从数据存储中检索并加入到快速缓存不论什么改动在快速缓存中保持的数据被自己主动地写入到数据存储区以及。

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

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

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


    假设一个应用程序将更新的信息,能够模拟通写策略例如以下:
    1.依据改动到数据存储
    2.作废相应的在缓存中。

    该项目被下一个须要,可使用快速缓存预留策略将导致从数据存储中检索又一次加入到快速缓存中的更新数据



    问题和注意事项



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

    使用这个模式



    使用这样的模式
    缓存不提供原生通过,并通过写操作。
    •资源的需求是不可预測的这样的模式使应用程序可以按需载入数据它使不论什么如果有关的数据的应用程序将须要提前

    这样的模式可能不适合
    •当缓存的数据集是静态的。假设数据适合可用的快速缓存空间首要快速缓存中的数据在启动应用,防止数据政策
    对于托管在Web场中的Web应用程序缓存会话状态信息在这样的环境下应该避免引入基于client - server关系的依赖

    样例



    微软的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方法指定键(这部分功能的代码已经被省略了,由于这将数据存储相关)从缓存中删除缓存项


    注意:

    在这个序列中的步骤的次序是重要的。假设之前缓存更新被删除,对于client应用程序中的数据存储中的项目之前获取数据由于它没有在快速缓存中发现的)的机会已经改变一个小窗体,从而在缓存包括过期数据

    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

  • 相关阅读:
    SQL SERVER 性能优化四: 创建分区表
    SQL SERVER 性能优化一: 数据库中几百万数据查询优化
    SQL SERVER 性能优化二: 数据库初始值大小及增长方式设置
    C++连接SQL SERVER 数据库方式
    利用作业定时收缩SQL SERVER数据库
    jQuery easyUI datagrid 增加求和统计行
    jquery easyui DataGrid 数据表格 属性
    jQuery easyui中获取datagrid某一列的值之和
    Maven + Springboot + redis 配置
    mac os Catalina beta Jetbrains idea闪退解决方案
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4277329.html
Copyright © 2020-2023  润新知