zoukankan      html  css  js  c++  java
  • apache ignite系列(四):持久化

    ignite持久化与固化内存

    1.持久化的机制

    ignite持久化的关键点如下:

    • ignite持久化可防止内存溢出导致数据丢失的情况;
    • 持久化可以定制化配置,按需持久化;
    • 持久化能解决在大量缓存数据情况下ignite节点启动缓慢的问题;
    • 使用持久化后,ignite能存储海量的数据;
    • 使用持久化之后需要手工启动集群;

    持久化涉及到的一个关键点就是WAL,所谓WAL就是预写日志,目的是为了保证在持久化机制下数据写入的性能,其原理图如下所示:

    ​ 在ignite中,对内存中数据的操作并不会立即同步到持久化文件(Partition File)中,而是先记录在预写日志(Write-Ahead Log)中,检查点线程(Checkpointing)将内存中的脏数据(dirty page)同步到持久化文件中,并且会将预写日志中的过期数据删除。

    ​ dirty page:在wal文件中但是还没写入partition files中,当dirty page 比例占到内存数据的2/3的时候会触发checkpoint机制。

    ​ checkpoint : 将内存中的数据同步到partition files中,当checkpoint结束之后,wal会归档,开启一个新的wal文件。

    ​ wal可以防止在极端情况下,比如断电,程序崩溃的情况下数据丢失,但是如果wal中的数据过多,那么在ignite启动的时候从wal读取数据势必会导致启动速度缓慢,因为从wal中读取数据的速度远比从partition files中读取数据的速度慢。缓存配置项中有个'writeThrottlingEnabled' 配置项可以改善这个情况,除此之外,还可以调整检查点的线程数以及同步频率来提升预写日志的效率,相关配置如下所示:

    <property name="dataStorageConfiguration">
    	<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
    	......
    	 <!-- Threads that generate dirty pages too fast during ongoing checkpoint will be throttled -->
    	 <property name="writeThrottlingEnabled" value="true"/>
            
         <!--Checkpointing frequency which is a minimal interval when the dirty pages will be written to the Persistent Store.-->
         <!-- 检查点频率 -->
         <property name="checkpointFrequency" value="180000"/>
            
         <!-- Number of threads for checkpointing.-->
         <!-- 检查点线程数 -->
         <property name="checkpointThreads" value="4"/>
            
         <!-- 在检查点同步完成后预写日志历史保留数量
         <!-- Number of checkpoints to be kept in WAL after checkpoint is finished.-->
         <property name="walHistorySize" value="20"/>       
    	......
    	</bean>
    </property>
    

    ​ WAL有几种模式可以选择,可以关闭WAL或者强同步模式,保证数据在苛刻条件下也不会丢失,设置方式如下:

        <!-- 设置持久化预写日志模式. -->
        <property name="walMode">
            <util:constant static-field="org.apache.ignite.configuration.WALMode.DEFAULT"/>
        </property>
    

    2. 通过配置开启持久化:

    ignite中对于存储有个内存区的概念,每个cache默认使用的是Default_Region,可以自定义内存区,然后在定义缓存的时候指定缓存区,这样可以做到个性化持久化,比如有些缓存的数据量比较小,那么就没有持久化的必要,而有些表数据量比较大,而且还在持续增长,需要开启持久化防止内存溢出,这时可以通过自定义内存区将两者缓存区分开来,实现定制化持久化。

    • xml配置:
    <!-- Consistent globally unique node identifier which survives node restarts. -->
    <!-- 设置节点固定的一致性id,使得节点使用专用目录和数据分区 -->
    <property name="consistentId" value="ABC"/>
    
    <!-- 节点自定义存储配置 -->
    <property name="dataStorageConfiguration">
        <bean class="org.apache.ignite.configuration.DataStorageConfiguration">
            <!-- Redefining the default region's settings -->
            <property name="defaultDataRegionConfiguration">
                <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                    <property name="name" value="Default_Region"/>
                    <!-- 设置默认内存区最大内存为 1GB. -->
                    <property name="maxSize" value="#{1L * 1024 * 1024 * 1024}"/>
                    <!-- 默认内存区开启持久化. -->
                    <property name="persistenceEnabled" value="true"/>
                </bean>
            </property>
            <property name="dataRegionConfigurations">
                <list>
                    <!-- 自定义内存区并开启持久化-->
                    <bean class="org.apache.ignite.configuration.DataRegionConfiguration">
                        <!-- 内存区名. -->
                        <property name="name" value="500MB_Region"/>
                        <!-- 100 MB initial size. -->
                        <property name="initialSize" value="#{100L * 1024 * 1024}"/>
                        <!-- 500 MB maximum size. -->
                        <property name="maxSize" value="#{500L * 1024 * 1024}"/>
                        <!-- 开启持久化. -->
                        <property name="persistenceEnabled" value="true"/>
                    </bean>
                </list>
            </property>
    
            <!-- 设置持久化预写日志模式. -->
            <property name="walMode">
                <util:constant static-field="org.apache.ignite.configuration.WALMode.DEFAULT"/>
            </property>
    
            <!-- 持久化文件存储路径. -->
            <!-- <property name="storagePath" value="D:\Test\db" /> -->
            <property name="storagePath" value="/data/local/db" />
    
            <!-- 预写日志存储路径. -->
            <!-- <property name="walPath" value="D:\Test\db\wal" /> -->
            <property name="walPath" value="/data/local/db/wal" />
    
            <!-- 预写日志解压路径. -->
            <!-- <property name="walArchivePath" value="D:\Test\db\wal\archive" /> -->
            <property name="walArchivePath" value="/data/local/db/wal/archive" />
    
        </bean>
    </property>
    
    • java配置:

      	private static final String usrDir = System.getProperty("user.dir");
      	private static final String separator = File.separator;
      	private static final String DB = "db";
      	private static final String WAL = "wal";
      	private static final String ARCHIVE = "archive";
      	
      	/**设置一致性Id*/
         igniteCfg.setConsistentId("ABC");
          /**ignite持久化配置*/
          DataStorageConfiguration dcfg = igniteCfg.getDataStorageConfiguration();
          dcfg.getDefaultDataRegionConfiguration()
                  .setMaxSize(4L * 1024 * 1024 * 1024) //设置默认区域的最大可用内存
                  .setPersistenceEnabled(true); //默认区域开启持久化
          //设置持久化路径
          dcfg.setStoragePath(String.format("%s%s%s", usrDir, separator, DB));
          dcfg.setWalPath(String.format("%s%s%s%s%s", usrDir, separator, DB, separator, WAL));
          dcfg.setWalArchivePath(String.format("%s%s%s%s%s%s%s", usrDir, separator, DB, separator, WAL, separator, ARCHIVE));
      
    • 相关说明:

      1.1 设置consistentId的原因:

      ​默认状态下,如果节点重启,那么ignite会随机生成一个全局唯一的consistentId, 而持久化的磁盘路径是用consistentId 区分的,如果重启之后那么无法再读取原来区间的持久化文件,但是指定consistentId就可以使用固定空间,使用之前的持久化文件。

    如果一台主机启动了若干个节点,那么每个节点进程都会在一个预定义的唯一子目录中,比如${IGNITE_HOME}/work/db/node{IDX}-{UUID},有自己的持久化文件,这里IDXUUID参数都是Ignite在节点启动时自动计算的(这里有详细描述)。如果在持久化层次结构中已经有了若干node{IDX}-{UUID}子目录,那么他们是按照节点先入先出的顺序进行赋值的。如果希望某节点即使重启也有专用目录和专用的数据分区,需要在集群范围配置唯一的IgniteConfiguration.setConsistentId,这个唯一ID会在node{IDX}-{UUID}字符串中映、射setStoragePath(...)到、setWalArchivePath(...)ffUUID`。

    1.2 自定义存储区域的使用方式:

    ​ 默认配置下,缓存使用的是默认内存区(defaultDataRegionConfiguration),也可以自定义内存区,如上面配置文件中定义的"500MB_Region"。这样可以将需要持久化的数据和不需要持久化的数据分离出来,但是使用自定义的内存区的时候需要设置额外的属性:

    <property name="cacheConfiguration">
        <list>
            <bean class="org.apache.ignite.configuration.CacheConfiguration">
              ...
                <property name="dataRegionName" value="500MB_Region"/>
              ...
            </bean>
        </list>
    </property>
    
    // Creating a cache configuration.
    CacheConfiguration cacheCfg = new CacheConfiguration();
    // Binding the cache to the earlier defined region.
    cacheCfg.setDataRegionName("500MB_Region");
    

    1.3 启用持久化之后需要手工激活集群:

    集群激活
    注意如果开启了Ignite持久化,集群默认是未激活的,无法进行任何的CRUD操作。用户需要手工激活集群,后面会介绍如何进行操作。

    集群激活方式:

    a. 代码激活:

            // Activating the cluster once all the cluster nodes are up and running.
            if(!ignite.active()) {
                ignite.active(true);  //如果集群未启动则启动集群
            }
    

    b. web控制台:

    img

    c. 命令激活:

    在命令行中,使用$IGNITE_HOME/bin文件夹中的control.sh|bat脚本,比如
    .sh:
    control.sh|bat

    ./control.sh --activate
    

    .bat:

    ./control.bat --activate
    

    1.4 ignite的destroyCache()方法同样会清除持久化文件.

    destroyCache同样会清除持久化文件,但是持久化的缓存配置不会清除, 所以重启之后会出现容量为空的cache。如果要动态修改cache配置,必须先destroyCache,再做调整;

    3. 持久化相关测试:

    持久化占用的磁盘空间大小,以及持久化对于节点启动速度的提升:

    数据量 磁盘占用 未持久化启动 持久化后启动
    350w(生产数据) 分区文件5.6g, 预写日志7.0g 2分钟 39s
    2400w(本地数据) 分区文件6.76g,预写日志12.1g .......(内存溢出) 12s

  • 相关阅读:
    Silverlight项目笔记1:UI控件与布局、MVVM、数据绑定、await/async、Linq查询、WCF RIA Services、序列化、委托与事件
    斯坦福iOS7公开课1-3笔记及纸牌Demo
    使用CocoaPods管理第三方开源类库
    Mac下安装Django
    iOS与H5界面JSBridge交互Demo
    手动导入swift三方danielgindi/Charts到OC工程中教程
    button自适应宽度 并根据屏幕宽自动换行排列
    ReactNative中iOS和Android的style分开设置教程
    react-native DatePicker日期选择组件的实现
    react-native Simulator com+r不能刷新模拟器
  • 原文地址:https://www.cnblogs.com/cord/p/9431865.html
Copyright © 2011-2022 走看看