apache ignite系列(四):持久化

ignite持久化與固化內存

1.持久化的機制

ignite持久化的關鍵點以下:java

  • ignite持久化可防止內存溢出致使數據丟失的狀況;
  • 持久化能夠定製化配置,按需持久化;
  • 持久化能解決在大量緩存數據狀況下ignite節點啓動緩慢的問題;
  • 使用持久化後,ignite能存儲海量的數據;
  • 使用持久化以後須要手工啓動集羣;

持久化涉及到的一個關鍵點就是WAL,所謂WAL就是預寫日誌,目的是爲了保證在持久化機制下數據寫入的性能,其原理圖以下所示:node

​ 在ignite中,對內存中數據的操做並不會當即同步到持久化文件(Partition File)中,而是先記錄在預寫日誌(Write-Ahead Log)中,檢查點線程(Checkpointing)將內存中的髒數據(dirty page)同步到持久化文件中,而且會將預寫日誌中的過時數據刪除。web

​ dirty page:在wal文件中可是還沒寫入partition files中,當dirty page 比例佔到內存數據的2/3的時候會觸發checkpoint機制。apache

​ checkpoint : 將內存中的數據同步到partition files中,當checkpoint結束以後,wal會歸檔,開啓一個新的wal文件。緩存

​ wal能夠防止在極端狀況下,好比斷電,程序崩潰的狀況下數據丟失,可是若是wal中的數據過多,那麼在ignite啓動的時候從wal讀取數據勢必會致使啓動速度緩慢,由於從wal中讀取數據的速度遠比從partition files中讀取數據的速度慢。緩存配置項中有個'writeThrottlingEnabled'配置項能夠改善這個狀況,除此以外,還能夠調整檢查點的線程數以及同步頻率來提高預寫日誌的效率,相關配置以下所示:ide

<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

相關文章
相關標籤/搜索