zoukankan      html  css  js  c++  java
  • 微软企业库4.1学习笔记(十八)缓存模块6 缓存的设计目的

    设计缓存的目的

      缓存模块可以用来实现下列功能:

    •   提供了一系列的API
    •   它使得开发者不需要学习很多内部的工作机制,就可以将常用的缓存功能加入应用
    •   使用企业库的配置工具很容易配置
    •   性能高效
    •   线程安全,内部的代码考虑到了在多个线程调用,没有非预期的内部交互。
    •   使用后端存储,使得发生以外也可以保持数据的完整无缺。
    •   保证了内存中的数据和后端存储保持数据同步。

      本节讲述一些缓存模块设计的亮点,和设计的细节。还包括一些过期处理的设计和扫描处理的设计。

      1、设计亮点

     

      上图显示的是缓存模块中关键类之间的关系。

      当你用CacheFactory初始化一个CacheManager对象的时候,在内部创建了一个CacheManagerFactory对象,创建了一个Cache对象。常见Cache对象之后,在后端存储的所有数据被加载到内存中,放在Cache对象中。然后应用可以用CacheManager发出请求,获取数据添加数据,删除数据。

      当应用向CacheManager发送请求,使用GetData方法从缓存中获取数据的时候,CacheManager对象会请求Cache对象。如果请求项存在的话,返回缓存的数据,如果不存在返回null,如果对象过期,也返回null。

      当应用使用CacheManager的add方法,向缓存中添加项的时候,CacheManager同样将请求发送给Cache对象。如果已经存在一个同样key的项的话,Cache首先会删除原来的项,然后加入新项。如果缓存的后端存储是默认的NullBackingStore,数据只是写入内存。如果添加项的时候,达到了缓存存储数据量的上限的话,BackgroundSchedule对象就会开始扫描,进行过期处理。

      如果添加的项在内存缓存中没有的话,Cache首先创建一个复制品,然后添加到内存的hashtable中,然后锁定内存中的项,添加项到后端存储,然后替代内存hashtable中的项。如果在写入后端存储的时候发生异常,就会从内存缓存中删除那个复制品。缓存模块拥有很强的异常安全保护,意味着如果加入项的时候发生异常,缓存的状态可以回滚的添加之前的状态。换句话说,除非添加项成功,否则缓存的状态不会改变。(同样也适用于删除项和清空项)

      BackgroundSchedule对象周期性的监测缓存中的项。当一个项过期,BackgroundSchedule首先会移除项,然后有可能会通知应用,项被移除。这时候,应用的责任就是更新缓存。

      2、设计细节

      CacheManager是一个接口类型,所有的缓存操作都通过接口调用。如果开发者没有修改直接使用缓存模块的话,CacheManager对象提供了访问缓存需要的全部方法,获取、添加、删除、清空项。每个方法都是线程安全的。

      使用CacheFactory类创建一个CacheManager对象,还会创建一个CacheManagerFactory类。CacheManagerFactory类会创建实现一个CacheManager所需要的内部类。

      不同的缓存不能共享相同的后端储存,每个CacheManager都只能对应一个后端存储。Cache对象接收从CacheManager对象发送过来的请求,实现了所有的在内存缓存和后端储存之间的操作。包含了一个hashtable来存储内存中对应的数据,一个数据项作为一个CacheItem对象。这个对象包括数据本身,还包括了项的key,优先级,RefreshAction对象,和过期策略。这些信息都存放在一个hashtable中,Cache也是线程安全的。Cache用一个同步的hashtable控制应用和BackgroundSchedule对缓存中的项的访问。

      BackgroundSchedule对象的责任就是进行过期处理,扫描低级别的项。PollTimer对象激活过期循环,一个数字是一次扫描处理移除的项目。这些都在配置文件中可以设置。

      缓存模块中的缓存存储类包括DataBackingStore、IsolateStorageBackingStore、和NullBackingStore。如果你想要实现自定义的后端存储,你需要实现IBackingStore接口,或者是继承BaseBackingStore类,这个类也实现了IBackingStore接口。这个基类包含了实现任何后端存储所需要的策略和工具方法。

      当后段存储是使用数据库的时候,可以用DataBackingStore类。在配置工具中,对应于一个数据库实例的名称。

      DataBackingStroe和IsolatedBackingStore类可以在持久化之前加密缓存项。加密缓存项可以通过配置来激活。使用配置工具,缓存存储可以使用配置好的加密算法provider。provider的name在从缓存中读取数据,然后在显示之前解密的时候同样需要。

       过期策略的设计

      缓存模块的过期处理是靠BackgroundSchedule来执行的。它会周期性的检查hashtable中的缓存项,看是否有过期项。你可以在配置缓存模块的时候设置检查周期的时间。

      缓存模块提供了四个过期策略:

    •   Absolute,意味着缓存项在一个特定的时间过期
    •   Sliding,意味着缓存项在最后一次访问之后的固定时间过期,默认为2分钟。
    •   Expended format,你可以详细描述过期条件,例如,可以设定为每个星期六晚上10:00,或者是每个月的第三个星期日。Expended formats在ExpendedFormat.cs文件中列出来很多。
    •   File dependency,意味着当一个文件被修改,缓存项就过期

      前三个过期选项都是以时间为基础的,如果数据的更新时间是规则的,或者是在一个特定的时间更新,你可以使用前三个选项。

      第四个,文件依赖,是以通知为基础的。它指定缓存项的过期依赖一个特定的文件,如果文件被修改,缓存项就过期,就会删除缓存项。

      Add方法有两个重载,一个设置了默认的过期策略,NeverExpired。另外一个你可以设置适合自己的过期策略。你甚至可以设置自定义的策略,如果你为一个缓存项设置了多个策略,  如果由一个策略符合条件,缓存项就会过期。

      标记和清除

      过期包括两个步骤。一个就是标记,另外一个就是清除。分为两个步骤,就是为了避免BackgroundSchedule清除一个应用正在使用的缓存项可能发生的冲突。

      在标记过程中,BackgroundSchedule会拷贝一份hashtable,然后检查里面的每一个缓存项,看看有没有过期的。这时候会锁定缓存项,如果发现过期的,就会打个标记。

      在清除过程中,BackgroundSchedule会重新检查缓存项的标记,看看在打上标记之后是否有访问记录。如果有访问记录,就保留缓存项。如果没有,就过期它,删除它。缓存项过期的时候,会引发WMI事件。

      回调callbacks

      开发者可以选择add方法的另外一个重载,使得在缓存项过期,删除缓存项的时候发通知给应用,如果有必要,应用可以更新缓存。

      扫描处理的设计

      缓存模块的扫描处理也是由BackgroundSchedule执行的。在每次有缓存项加入的时候都会检查,缓存项的数目是否达到设置的最大值。数量是设置在CacheManager实例上的。

      当加入一个缓存项的时候,可以设置优先级,有四个选项:Low,Normal,High,NotRemovable。删除的时候会按照优先级的高低进行处理,优先级低的会先被清除。默认值是Normal。

      当你想让一个缓存项直到它过期才被清除的话,可以设置为NotRemovable。最好不要设置为NotRemovable,因为缓存是用来提升性能的,不应该被作为一种持久化手段。

      不想过期处理包括两个过程,扫描处理只有一个过程。

      未完待续。。。。。。。。。。。。。。。。。。。。。。

  • 相关阅读:
    ReactNative入门 —— 动画篇(下)
    浅谈浏览器http的缓存机制
    ReactNative入门 —— 动画篇(上)
    小小改动帮你减少bundle.js文件体积(翻译)
    ReactNative入门(安卓)——API(上)
    《高性能javascript》一书要点和延伸(下)
    巧用 mask-image 实现简单进度加载界面
    降低首屏时间,“直出”是个什么概念?
    AlloyTeam2015前端大会都说了啥
    作为前端er,写在年末的一些话
  • 原文地址:https://www.cnblogs.com/lmule/p/1801442.html
Copyright © 2011-2022 走看看