# 持久化

# 1.Ignite持久化

Ignite原生持久化是一个分布式的兼容ACID和SQL的磁盘存储,它与Ignite的固化内存透明地集成在一起。Ignite持久化是可选的,可以打开和关闭。关闭时,Ignite就是一个纯粹的内存存储。

启用原生持久化后,Ignite就会在磁盘上存储数据的超集,然后会根据容量在RAM中存储尽可能多的数据。例如,如果有100个条目且RAM只能存储20个,那么所有100个将存储在磁盘上,只有20个将缓存在RAM中以获得更好的性能。

此外,值得一提的是,与纯内存的场景一样,当启用持久化时,每个节点仅持有数据的一个子集,仅包括节点做为主节点或备份节点的分区。而整个集群则持有完整的数据集。

具体的细节可以参见Java版本的持久化文档。

# 1.1.用法

要启用原生持久化,需要在节点的配置中配置DataStorageConfiguration

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
  <!-- Enabling Apache Ignite native persistence. -->
  <property name="dataStorageConfiguration">
    <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
      <property name="defaultDataRegionConfiguration">
        <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
          <property name="persistenceEnabled" value="true"/>
        </bean>
      </property>
    </bean>
  </property>

  <!-- Additional setting. -->

</bean>

启用持久化后,所有数据和索引都将存储在对应节点的内存和磁盘上。

# 2.第三方持久化

# 2.1.概述

除了Ignite原生持久化之外,Ignite C++还可以使用第三方存储来实现持久化。可以使用关系数据库这样的底层存储,然后将缓存配置为通写后写或者通读模式。通过这些配置,Ignite C++可以自动地将所有更新发送给持久化层,也可以对数据进行按需预加载。

注意

目前,Ignite C++没有实现整套缓存存储相关的API。如果需要只有Java版本才有的功能,那就得使用Java版本。

# 2.2.通读和通写

如果需要通读或通写功能,就得配置争取的缓存存储。通读就是数据在缓存中不可用,就会从底层存储中读取,而通写则是如果在缓存中更新了数据,数据会自动持久化。所有的通读和通写操作都将参与整体缓存事务,并将作为整体提交或回滚。

要配置通读和通写,需要配置CacheConfigurationcacheStoreFactoryreadThroughwriteThrough属性,如下所示:

自定义存储:

<bean class="org.apache.ignite.configuration.IgniteConfiguration">
  ...
    <property name="cacheConfiguration">
      <list>
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
          ...
          <property name="cacheStoreFactory">
            <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf">
              <constructor-arg value="foo.bar.MyPersonStore"/>
            </bean>
          </property>
          <property name="readThrough" value="true"/>
          <property name="writeThrough"  value="true"/>
        </bean>
    	</list>
    </property>
  ...
</bean>

CacheJdbcBlobStoreFactory:

<bean id= "simpleDataSource" class="org.h2.jdbcx.JdbcDataSource"/>

<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
  ...
   <property name="cacheConfiguration">
     <list>
       <bean class="org.apache.ignite.configuration.CacheConfiguration">
         ...
           <property name="cacheStoreFactory">
             <bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcBlobStoreFactory">
               <property name="user" value = "user" />
               <property name="dataSourceBean" value = "simpleDataSource" />
             </bean>
           </property>
       </bean>
      </list>
    </property>
  ...
</bean>

CacheJdbcPojoStore:

<bean id= "simpleDataSource" class="org.h2.jdbcx.JdbcDataSource"/>

<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
  ...
    <property name="cacheConfiguration">
      <list>
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
          ...
            <property name="cacheStoreFactory">
              <bean class="org.apache.ignite.cache.store.jdbc.CacheJdbcPojoStoreFactory">
                <property name="dataSourceBean" value = "simpleDataSource" />
              </bean>
            </property>
        </bean>
      </list>
    </property>
</bean>

CacheHibernateBlobStore:

<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
  ...
    <property name="cacheConfiguration">
      <list>
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
          <bean class="org.apache.ignite.cache.store.hibernate.CacheHibernateBlobStoreFactory">
           <property name="hibernateProperties">
             <props>
               <prop key="connection.url">jdbc:h2:mem:</prop>
               <prop key="hbm2ddl.auto">update</prop>
               <prop key="show_sql">true</prop>
             </props>
           </property>
         </bean>
       </list>
    </property>
  ...
</bean>

Ignite C++缓存存储

目前,可以使用Java Spring XML配置来配置CacheStore及其属性,在以后的版本中将支持原生C++的方式。

# 2.3.后写

在简单的通写模式中,每个缓存的写入和删除操作都会涉及一个对应持久化存储的请求,因此缓存更新的总持续时间可能相对较长。此外,密集的缓存更新也可能会导致极高的存储负载。

对于这种场景,Ignite提供了一个异步持久化更新的选项,也称为后写。此方法的关键点是累积更新,然后将其作为批量操作异步刷新到底层数据库。实际的数据持久化可以由相关的事件触发刷新,这些事件可以基于时间(数据条目驻留在队列中的最长时间是有限的),也可以基于队列大小(当队列大小达到某个特定点时),也可以同时使用两者。

更新顺序

使用后写方法,只有对条目的最后更新才会写入底层存储。如果键为key1的缓存条目分别按照值value1value2value3的顺序更新,则只有(key1value3)的单个数据对存储请求会被传播到持久化存储。

更新性能

批量存储操作通常比单个存储操作序列更有效。可以通过在后写模式下启用批处理操作来开启该功能。可以将类似类型(写入或移除)的更新序列分为多个批次,例如,(key1,value1),(key2,value2),(key3,value3)这样的顺序写入操作,可以作为一个批量写入操作。

后写缓存可以通过CacheConfiguration.writeBehindEnabled(boolean)配置属性来开启:

<bean class="org.apache.ignite.configuration.CacheConfiguration">
    ...
    <property name="readThrough" value="true"/>
    <property name="writeThrough" value="true"/>
    <property name="writeBehindEnabled" value="true"/>
    <property name="writeBehindFlushSize" value="0"/>
    <property name="writeBehindFlushFrequency" value="10000"/>
    <property name="writeBehindFlushThreadCount" value="2"/>
    <property name="writeBehindBatchSize" value="1024"/>
    ...
</bean>

# 2.4.缓存加载

要将数据从持久化存储加载到缓存,可以使用Cache::LoadCache()方法。它通常用于在启动时热加载缓存,不过也可以在缓存启动后的任何时刻调用。

要仅在本地节点上加载,请使用Cache.LocalLoadCache()方法。

注意

在预加载分区缓存期间,将自动丢弃节点既不是主节点也不备份节点的数据。

// Preparing cache configuration.
IgniteConfiguration cfg;
cfg.springCfgPath = "my_ignite_config.xml";

Ignite node = Ignition::Start(cfg);

// Starting the cache.
Cache<int32_t, Person> cache = node.GetOrCreateCache<int32_t, Person>("myCache");

// Initiating cache loading.
cache.LoadCache();
最后更新时间:: 3/15/2020, 9:48:01 AM