天天看點

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’配置項可以改善這個情況,除此之外,還可以調整檢查點的線程數以及同步頻率來提升預寫日志的效率,相關配置如下所示:

......

<!--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>
           

​ WAL有幾種模式可以選擇,可以關閉WAL或者強同步模式,保證資料在苛刻條件下也不會丢失,設定方式如下:

<!-- 設定持久化預寫日志模式. -->
<property name="walMode">
    <util:constant static-field="org.apache.ignite.configuration.WALMode.DEFAULT"/>
</property>
           
  1. 通過配置開啟持久化:

    ignite中對于存儲有個記憶體區的概念,每個cache預設使用的是Default_Region,可以自定義記憶體區,然後在定義緩存的時候指定緩存區,這樣可以做到個性化持久化,比如有些緩存的資料量比較小,那麼就沒有持久化的必要,而有些表資料量比較大,而且還在持續增長,需要開啟持久化防止記憶體溢出,這時可以通過自定義記憶體區将兩者緩存區分開來,實作定制化持久化。

xml配置:

<!-- 設定持久化預寫日志模式. -->
    <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>
           

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},有自己的持久化檔案,這裡IDX和UUID參數都是Ignite在節點啟動時自動計算的(這裡有較長的描述)。如果在持久化層次結構中已經有了若幹node{IDX}-{UUID}子目錄,那麼他們是按照節點先入先出的順序進行指派的。如果希望某節點即使重新開機也有專用目錄和專用的資料分區,需要在叢集範圍配置唯一的IgniteConfiguration.setConsistentId,這個唯一ID會在node{IDX}-{UUID}字元串中映、射setStoragePath(…)到、setWalArchivePath(…)ffUUID`。

1.2 自定義存儲區域的使用方式:

​ 預設配置下,緩存使用的是預設記憶體區(defaultDataRegionConfiguration),也可以自定義記憶體區,如上面配置檔案中定義的"500MB_Region"。這樣可以将需要持久化的資料和不需要持久化的資料分離出來,但是使用自定義的記憶體區的時候需要設定額外的屬性:

... ... // 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,再做調整;

  1. 持久化相關測試:

    持久化占用的磁盤空間大小,以及持久化對于節點啟動速度的提升:

資料量 磁盤占用 未持久化啟動 持久化後啟動

350w(生産資料) 分區檔案5.6g, 預寫日志7.0g 2分鐘 39s

2400w(本地資料) 分區檔案6.76g,預寫日志12.1g …(記憶體溢出) 12s

分類: apache ignite