zoukankan      html  css  js  c++  java
  • Coherence Step by Step 第三篇 缓存(三)实现Storage和Backing Maps(翻译)

    本章使用backing maps提供信息存储。

     
    1.Cache Layers
     
    在coherence中,Partitioned(distributed) cache服务有三个明显的层:
    • Client View  这个客户端视图表示了一个虚拟的层,提供对底层分布式数据的访问。这一侧可以使用NamedCache接口来访问。在这个层,你能创建合成的数据结构,如NearCahce或者 ContinuousQueryCache。
    • Storage Manager storage manager是服务端的层,用来处理从客户端层发来的和缓存相关的请求。它管理持有真是缓存数据(primary和backup副本)的锁信息、事件监听器、映射触发器等的数据结构。
    • backing map  backing map是服务端数据结构,持有真实数据。
    Coherence允许用户配置一些即用的backing mapo实现和自定的实现。基本上,唯一的限制是所有的映射实现必须知道的是理解Storage Manager提供的所有的key和value的内部形式。为了处理内部数据和对象形式的互相转化,Storage Manager能够用BackingMapManagerContext应用支持Backing Map实现。
     
    下图示backing map 概念上的展示

     
    2.Local Storage
     
    Local storage 引用数据结构,实际上是被Coherence管理的存储和缓存的数据。一个对象要提供local storage,它必须提供相同标准的集合接口,java.util.map。当一个local storage的实现被coherence用来存储replicated 或者distributed数据,这成为backing map,因为Coherence实际上通过local storage 实现来备份的。local storage最常用在distributed cache中的前面和distributed cache的后面作为备份。
     
    Coherence 支持下面local storage 实现:
    • Safe HashMap: 这个默认的无损的实现。无损的实现是一个类似java的Hashtable类的,没有大小限制和自动过期。换句话说,它不会从自身中剔除任何缓存条目。这个特殊的HashMap的实现对非常高的线程级别的并发是最佳的。对于默认的实现,用com.tangosol.until.SafehaspMap类;当一个实现需要提供缓存事件时,用com.tangosol.util.ObservalbleHashMap。这些实现是线程安全的。
    • Local Cache: 这是默认的size-limiting和atuo-expiring的实现。local cache下面会详细说,但是重点要记住的是他能够限制缓存的大小,它能够实现在一个确定周期后自动过期。对于默认的实现,使用com.tangosol.net.cache.LocalCache;这个实现是线程安全的,支持缓存事件,con.tangosol.net.CacheLoader,CacheStore和可配置的/插入式的逐出规则。
    • 读/写 Backing map: 这是默认的backing map的实现,当一个缓存没有找到,从数据库中加载。他能配置成read-only cache(消费者模型)或者是一个write-through 或者是write-behind cache(消费者/生产者模型).write-through和write-behind模型专为distributed cache服务所设计。如果使用near cache,near cache必须和distributed cache保持同步,可能结合使用支持Seppuku-based near cache的backing map。对于默认的实现,使用com.tangosol.net.cache.ReadWriteBackingMap类。
    • Binary Map(Java NIO):这个backing map的实现,能够在内存中存储它的信息,而不是在java heap之外或甚至在memory-mapped文件,这意味着它不会影响java 堆的大小,和相关jcm垃圾回收的性能,能够对应用的暂停负责。这个实现也对distributed cache 备份有效,对于read-mostly 和read-only的换取特别有用,尤其要求高可用性的备份,因为这意味着backup不影响java堆的大小,二爷在失效备援时候能够立即可用。
    • Serialization Map:这个backing map的实现转换它的数据位一种能够存储在硬盘上的形式,引用一种序列化的形式。这要求一个独立的的com.tangosol.io.BinaryStore对象,以序列化形式的数据存储;通常,这是内建的LH磁盘的存储实现,但是serialization map支持任何自定义的BinaryStore实现。对于默认的serialization map,shiyongcom.tangosol.net.cache.SerializationMap.
    • Serialization Cache: 这个是SerializationMap的扩展,支持LRU啊逐出规则,使用com.tangosol.net.cache.SerializationCache。
    • Overflow Map:overflow map没有正式的提供存储,但是在这里应该提到,因为它能够结合两种local storage 实现,当第一个填满时候,它填充第二个。对于overflowmap的默认实现,使用com.tangosl.net.cache.OverflowMap。
    3.Operations
    有几种操作类型执行Backing Map
    • 自然访问和更新操作由应用的使用所引起。例如,NamedCache.get()的调用自然的导致了Map.get()的调用,以回应backing map;NamedCache.invoke()调用可能引起一系列的Map.put()和Map.get()操作;NamedCache.keySet(filter)调用可能引起Map.entrySet().iterator循环等等。
    • 移除操作由基于时间的过期或者基于大小的逐出所引起。例如,从客户端层调用NamedCache.get()或者NamedCache.size()可能引起Map.remove()调用,缘由于条目的过期时间到;或者NamedCache.put()调用导致一个Map.Remove()调用,缘由于在backing map中总共的数量达到了water-mark的配置值。
    • 插入操作可能导致一个CacheStore.load()操作。(对于配置了read-through或者read-ahead特性的backing map)
    • 人工访问或者更新是由于partition distribution引起的(这反过来可能是cluster节点失效或者回滚造成的)。这个例子中,没有应用层的调用,有些条目可能从backing map中被插入或者删除。
    4.容量规划
     
    根据实际的实现,backing map存储缓存数据用一下几种方式
    • on-heap memory
    • off-heap memory
    • disk(memory-mapped files 或者 in process DB)
    • solid state device(日志文件)
    • 以上任意的结合
    自然的在内存中保存数据,极大的减少了访问和更新的演示,这是最常用的。
     
    通常,应用程序必须确保所有的数据被放进了date grid,没有超出预定的内存。这个能够通过应用层的逻辑或者自动的使用size-或者expiry-based逐出来直接做到。很自然的,在coherence cache持有的所有数据等于相应的backing maps中的数据量的综合(每个cluster节点运行在启用了storage enabled模式的相应的partitioned cache service)。
     
    思考下面的缓存配置节选:
    
    
    <backing-map-scheme>
      <local-scheme/>
    </backing-map-scheme>
    
    

    上面的backing map是一个com.tangosol.net.cache.LocalCache的实例,没有任何预定的大小限制,且必须显式的控制。如果不这么做,可能导致JVM内存不足。

    <backing-map-scheme>
      <local-scheme>
        <eviction-policy>LRU</eviction-policy>
        <high-units>100m</high-units>
        <unit-calculator>BINARY</unit-calculator>
      </local-scheme>
    </backing-map-scheme>

    上面的backing map也是com.tangosol.net.cache.LocalCache,有一个100MB的容量限制。如果backing map所持有的数据超出了这个watermark,一些条目将会从backing map被移除,使得容量降低到低的watermark值(<low-units>配置元素,默认是<high-units>的75%)。移除条目的选择是基于LRU逐出规则。其它的参数有LFU和Hybird。<high-units>限制是2GB。要超过这个限制,使用<unit-factor>元素。例如,用<unit-factor>为1048576和<high-units>值为8192,结果是一个high watermark的值为8GB(8192*1048576)。

    <backing-map-scheme>
      <local-scheme>
        <expiry-delay>1h</expiry-delay>
      </local-scheme>
    </backing-map-scheme>

    上面的bakcing map自动逐出任何一条木,只要它有超过1小时没有更新。注意,这种逐出是一种"lazy"方式,一谈有更新发生,会在任何时间触发。唯一保证Coherence提供了超过1小时的条目不会回调。

     
    下面的backing map是一个com.tangosol.net.cache.SerializationCache的实例,在extended(nio) memory存储值,有一个100MB的限制。
    
    
    <backing-map-scheme>
      <external-scheme>
        <nio-memory-manager>
          <initial-size>1MB</initial-size>
          <maximum-size>100MB</maximum-size>
        </nio-memory-manager>
        <high-units>100</high-units>
        <unit-calculator>BINARY</unit-calculator>
        <unit-factor>1048576</unit-factor>
      </external-scheme>
    </backing-map-scheme>
    
    

    配置这个缓存的backup storage为off-heap(or file-mapped):

    
    
    <backup-storage>
      <type>off-heap</type>
      <initial-size>1MB</initial-size>
      <maximum-size>100MB</maximum-size>
    </backup-storage>
    
    

    5.使用Partitioned Backing Maps

    传统的backing map实现为所有相应节点所拥有的partitions包含了条目。(在partition传输过重中,它也能持有"in flight"条目,从客户端的角度来说是暂时的不属于任何人)。
    下图展示了一个传统backing map实现的概念视图。

    partitioned的backing map是一个基本的多个真是映射的实现,每个都只包含了属于同一个partition的条目。

    下图是partitioned backing map实现的概念视图

    配置partitioned backing map,增加一个<partitioned>元素,值为true,例如:

    <backing-map-scheme>
      <partitioned>true</partitioned>
      <external-scheme>
        <nio-memory-manager>
          <initial-size>1MB</initial-size>
          <maximum-size>50MB</maximum-size>
        </nio-memory-manager>
        <high-units>8192</high-units>
        <unit-calculator>BINARY</unit-calculator>
        <unit-factor>1048576</unit-factor>
      </external-scheme>
    </backing-map-scheme>
    backing map是com.tangosol.net.partition.PartitionSplittingBackingMap的实例,随着单独的分区持有的映射被com.tangosol.net.cache.SerializationCache实例化,每个值存储在extended(nio) memory。单独的nio 缓存有个50MB的限制,而backing map有一个蒸发容量为8GB(8192*1048576)的限制。
    再一次重复,你必须为这个缓存配置backup storage为off-heap或者file-mapped的
     
    6.使用Elastic Data Feature 来存储数据
     
    Elastic Date feature用来无缝的在内存和基本磁盘的谁被间存储数据。这个特性是特别值得欣赏的,利用了快速的基于磁盘的设备,如SSD且从SSD读取数据或存储数据使得接近内存速度。Elastic Date feature 使用了成为journaling的技术来优化在内存和磁盘间的存储。
     
    Elastic date包含两个不同的组件:RAM journal 用来在in-memory中存储数据,flash journal用来在基于磁盘的设备上存储数据。这些可以用不同的组合方式组合,通常用在backing maps和backup storage,但是也能和composite cache一起使用(例如,near cache)。RAM journal总是用flash journal使得数据无缝的流向磁盘。
     
    Cache使用RAM或者是flash journal是作为缓存配置文件中缓存方案定义的一部分作为配置。Journaling behavior被配置,更具需要,通过使用一个operational override file来覆盖即用的配置。
     
    6.1 Journaling 概述
    Journaling引用了一种技术,记录一个队列的修改的状态变化,称为journal。当变化发生时,journal就会为每个指定的键记录每个值,一个树形结构被存储在内存中,用来跟踪哪个journal条目包含了特定键的当前值。为了找到一个条目的值,查找树中的键,它包含了指向包含最新值的journal条目的指针。
     
    如由于为一个键写了新的值使得journal里的变化成为淘汰的,旧的值在journal堆积。每隔一段时间,旧的值会被逐出,让出控件给新的值。
     
    Elastic Data feature包含了RAM journal 实现和flash journal 实现,两者无缝的工作。如果,例如RAM journal 用尽内存,flash journal自动接收从ram journal流出的数据,允许缓存扩大,远远超出内存的大小。
     
    NOTE:当journaling 是开启的,如果你正在执行data grid operation(如查询和聚合),要求额外的容量规划。
     
    resource manager 控制journaling。这resource manager 创建和使用binary store在journal上执行操作。binary store是JournalBinaryStore 类的实现。
     
    所有的读和写操作通过binary store由resource manager处理。有一个为RAM journal的resource manager(RamJournalRM)和一个为flash journalFlashJournalRM。最后,journaling使用SimpleSerializationMap类作为backing map的实现。如果有需要可以使用自定义的SimpleSerializationMap的实现。
     
     
    6.2 定义Journal方案
    <ramjoural-scheme>和<flashjournal-scheme>元素用来配置缓存配置文件中的RAM和FLash journal。
     
    6.2.1 配置RAM Jouranl Backing Map
     
    配置RAM journal backing map,在缓存定义中的<backing-map-schmem>元素中增加一个<ramjournal-scheme>元素。下面的列子创建了一个distributed cache中使用RAM journal作为backing map。当RAM journal超出了配置的内存大小时,会自动委托给flash journal。
    <distributed-scheme>
       <scheme-name>distributed-journal</scheme-name>
       <service-name>DistributedCacheRAMJournal</service-name>
       <backing-map-scheme>
          <ramjournal-scheme/>
       </backing-map-scheme>
       <autostart>true</autostart>
    </distributed-scheme>

     

    6.2.2 配置Flash Journal Backing Map

    配置flash journalbacking map,在缓存定义中的<backing-map-scheme>元素中增加一个<flashjournal-scheme>的元素。下面的例子创建了一个distributed scheme,使用了flash journal 作为bakcing map。
     
    6.2.3 引用Journal Scheme
     
    RAM和flash journal scheme都支持使用方案的引用来重用方案定义。下面的例子创建了一个distributed cache ,通过引用名为default-ram的RAM scheme定义来配置RAM journal backing map。
    <caching-schemes>
       <distributed-scheme>
          <scheme-name>distributed-journal</scheme-name>
             <service-name>DistributedCacheJournal</service-name>
             <backing-map-scheme>
                <ramjournal-scheme>
                   <scheme-ref>default-ram</scheme-ref>
                </ramjournal-scheme>
             </backing-map-scheme>
             <autostart>true</autostart>
       </distributed-scheme>
    
       <ramjournal-scheme>
          <scheme-name>default-ram</scheme-name>
       </ramjournal-scheme>
    </caching-schemes>

     

    6.2.4 使用Journal Scheme作为Backup Storage

    Journal scheme也可以像backing map一样用来作为backup storage。默认的,distributed scheme配置类使用RAM journal作为backing map,也为backup storage使用RAM journal。同样的,使用flash journal作为backing map的distributed scheme也使用flash journal作为backup storage。这个默认的行为能够通过使用<backup-storage>明确指定存储类型来修改。下面的配置使用一个RAM journal 作为backing map和志明配置一个flash journal作为backup storage:

    <caching-schemes>
       <distributed-scheme>
          <scheme-name>default-distributed-journal</scheme-name>
             <service-name>DistributedCacheJournal</service-name>
             <backup-storage>
                <type>scheme</type>
                <scheme-name>example-flash</scheme-name>
             </backup-storage>
             <backing-map-scheme>
                <ramjournal-scheme/>
             </backing-map-scheme>
          <autostart>true</autostart>
       </distributed-scheme>
    
       <flashjournal-scheme>
          <scheme-name>example-flash</scheme-name>
       </flashjournal-scheme>
    </caching-schemes>
    6.2.5 为Journal Scheme启用自定义的映射实现
     
    Journal scheme可以根据需求来配置使用自定义的映射。自定义的映射实现必须继承SimpleSerializationMap类,且声明相同集合的公共构造函数。使得能用,自定义的实现,增加一个<calss-scheme>元素,值为完全引用一个自定义类的名字。任何要求的参数都可以使用<init-params>元素来一个一个自定义类。下面的例子使用了一个名为MySimpleSerializationMap的自定义映射的实现。
    6.3 改变Journaling Behavior
     
    resource manager控制journaling behavior。有一个为RAM journals(RamJournalRM)的resource manager和一个味Flash journals(FlashJournalRM)的resource manager。resource manager在tangosol-coherence-override.xml operational override file中对cluster进行配置。resource manager如果没有配置覆盖,那么使用默认的即用设置。
     
     
    6.3.1 配置RAM Journal Resource Manager
     
    用<ramjournal-manager>元素配置Ram Journal Behavior。下面的列表提供了由resource manager设置的默认值的详细汇总。
     
    • 二进制值默认限制为64KB(最大4MB)
    • 一个单独的缓冲区(一个journal file)限制在2MB(最大2GB)
    • journal 由最多512个文件组成
    • journal总共能用的内存是默认为1GB(最大64GB)
    NOTE: 如果设置了二进制值,或者内存设置或者两个都设置了,falsh journal会被自动使用。
     
    配置RAM joural resource manager,在<journaling-config>中增加一个<ramjournal-manager>元素并且定义要被覆盖的子元素。下面的例子演示了覆盖了可用的子元素。
    <?xml version='1.0'?>
    
    <coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
       xsi:schemaLocation="http://xmlns.oracle.com/coherence/
       coherence-operational-config coherence-operational-config.xsd">
       <cluster-config>
          <journaling-config>
             <ramjournal-manager>
                <maximum-value-size>64K</maximum-value-size>
                <maximum-size>2G</maximum-size>
             </ramjournal-manager>
          </journaling-config>
       </cluster-config>
    </coherence>

     

    6.3.2 配置Flash Journal Resource Manager

    <flashjournal-manager>元素用来配置flash journal behavior。下面的列表提供了一个由resouce manager设置的默认值的详细汇总。
    
    
    • 二进制值默认限制为64MB
    • 一个单独的缓冲区(一个journal file)限制在2GB(最大4GB)
    • journal 由最多512个文件组成
    • journal 默认限制在1TB,理论上是2TB
    配置flash journal resouce manager,在<journaling-config>元素中增加<flashjournal-manager>元素,定义用来覆盖的子元素。下面的例子演示了覆盖各个有效的子元素:
    <?xml version='1.0'?>
    
    <coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
       xsi:schemaLocation="http://xmlns.oracle.com/coherence/
       coherence-operational-config coherence-operational-config.xsd">
       <cluster-config>
          <journaling-config>
             <flashjournal-manager>
                <maximum-value-size>64K</maximum-value-size>
                <maximum-file-size>8M</maximum-file-size>
                <block-size>512K</block-size>
                <maximum-pool-size>32M</maximum-pool-size>
                <directory>/coherence_storage</directory>
                <async-limit>32M</async-limit>
             </flashjournal-manager>
          </journaling-config>
       </cluster-config>
    </coherence>
    NOTE:用来存储journal文件的目录必须存在。如果不存在,会有警告信息,并且使用JVM指定的默认的临时文件目录。

    7.使用差异备份

    差异备份是一种当主要的entry发生改变时,用来将变化的部分保存进backup binary entry 而不是将整个entry给替换。差异备份对于需要更新的东西非常庞大,但是只有很小的一部分发生变化的场景是非常理想的。在这种情况下,改变的代价只是enrry的一小部分,小于重写整个entry的代价,结果是性能更好。如果改变超过50% ,差异备份通常可以证明几乎没有什么性能上的增加。
    
    差异备份使用了压缩器,对比两个in-memory 缓冲区中包含的旧值和新值,产生了一个结果(称为差异),能够在旧值的基础上创建新值。Coherence 为POF和non-POF格式提供了标准的差异压缩器。也能根据需要来创建自定义的压缩器。
     
    7.1 开启差异备份
     
    差异备份只对distributed cache有效,默认是关闭的。差异备份能够对单独的每个distributed cache开启,也能对所有的distributed cache服务类型的实例开启。
     
    开启distributed cache的差异备份,在<distributed-scheme>元素中增加一个<compressor>元素,设置为standard。例如:
    <distributed-scheme>
       ...        
       <compressor>standard</compressor>
       ...
    </distributed-scheme>
    为所有的distributed cache 服务类型的实例开启差异备份。在operational override file中覆盖部分缓存服务的compressor 初始参数。例如:
    <?xml version='1.0'?>
    
    <coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
       xsi:schemaLocation="http://xmlns.oracle.com/coherence/
       coherence-operational-config coherence-operational-config.xsd">
       <cluster-config>
          <services>
             <service id="3">
                <init-params>
                   <init-param id="22">
                      <param-name>compressor</param-name>
                      <param-value
                         system-property="tangosol.coherence.distributed.compressor">
                         standard</param-value>
                   </init-param>
                </init-params>
             </service>
          </services>
       </cluster-config>
    </coherence>
    tangosol.coherence.distributed.compressor 系统属性也被用来为所有的distributed cache 服务类型开启差异备份而不用operational override file。例如:
     
    -Dtangosol.coherence.distributed.compressor=standard
     
    7.2 使用自定义的差异备份Compressor
     
    为执行差异备份使用自定义的compressor,抱在在<instance>元素内,提供一个完整的实现DeltaCompressor接口的的引用类名。下面的例子使用了在MyDeltaCompressor类中实现的自定义compressor。
    <distributed-scheme>
       ...        
       <compressor>
          <instance>
             <class-name>package.MyDeltaCompressor</class-name>
          </instance>
       </compressor>
       ...
    </distributed-scheme>

    作为可选的方案,<instance>元素支持使用<class-factory-name>元素来使用工厂类来负责创建DeltaCompressor实例,<method-name>元素在工厂类上指定了静态工厂方法来执行对象实例化。下面的例子通过使用MyCompressorFactory类中的getCompressor方法来获取一个自定义的compressor实例。

    <distributed-scheme>
       ...        
       <compressor>
          <instance>
             <class-factory-name>package.MyCompressorFactory</class-factory-name>
             <method-name>getCompressor</method-name>
          </instance>
       </compressor>
       ...
    </distributed-scheme>

    需要任何的初始参数可以通过<init-params>元素类指定。下面的例子设置iMaxTime参数为2000。

    <distributed-scheme>
       ...        
       <compressor>
          <instance>
             <class-name>package.MyDeltaCompressor</class-name>
             <init-params>
                <init-param>
                   <param-name>iMaxTime</param-name>
                   <param-value>2000</param-value>
                </init-param>
             </init-params>
          </instance>
       </compressor>
       ...
    </distributed-scheme>
     
     
     

     

     

  • 相关阅读:
    显示和隐藏一个div的问题
    javascript高级程序设计笔记-第八章(BOM)
    javascript高级程序设计笔记-第七章(函数表达式)
    javascript高级程序设计笔记-第六章(面向对象编程)
    javascript高级程序设计笔记-第五章(引用类型)
    javascript高级程序设计笔记-第四章(变量、作用域)
    javascript高级程序设计笔记-第三章(基本概念)
    css设计指南-笔记7
    CocoaPods 1.1.0上传遇到swift问题
    Attribute富文本使用方法
  • 原文地址:https://www.cnblogs.com/danye/p/CoherenceCaches3.html
Copyright © 2011-2022 走看看