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},有自己的持久化文件,这里IDX和UUID参数都是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控制台:

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 |
apache ignite系列(四):持久化的更多相关文章
- apache ignite系列(九):ignite调优
1,配置文件调优 1.1 设置页面大小(pagesize) 先查看系统pagesiz,使用PAGE_SIZE或者PAGESIZE # getconf PAGE_SIZE 4096 # getconf ...
- apache ignite系列(八):问题汇总
1,java.lang.ClassNotFoundException Unknown pair 1.Please try to turn on isStoreKeepBinary in cache s ...
- apache ignite系列(二):配置
ignite有两种配置方式,一种是基于XML文件的配置,一种是基于JAVA代码的配置: 这里将ignite常用的配置集中罗列出来了,一般建议使用xml配置. 1,基于XML的配置 <beans ...
- apache ignite系列(一): 简介
apache-ignite简介(一) 1,简介 ignite是分布式内存网格的一种实现,其基于java平台,具有可持久化,分布式事务,分布式计算等特点,此外还支持丰富的键值存储以及SQL语法(基于 ...
- Apache Shiro系列四,概述 —— Shiro的架构
Shiro的设计目标就是让应用程序的安全管理更简单.更直观. 软件系统一般是基于用户故事来做设计.也就是我们会基于一个客户如何与这个软件系统交互来设计用户界面和服务接口.比如,你可能会说:“如 ...
- apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存
博客又断了一段时间,本篇将记录一下基于ignite对jdbc支持的特性在实际使用过程中的使用. 使用ddl和dml脚本初始化ignite 由于spring-boot中支持通过spring.dataso ...
- apache ignite系列(六): 服务网格
简介 服务网格本质上还是远程方法调用(RPC),而在ignite中注册的服务本质体现还是以cache的形式存在,集群中的节点可以相互调用部署在其它节点上的服务,而且ignite集群会负责部署服务的 ...
- apache ignite系列(三):数据处理(数据加载,数据并置,数据查询)
使用ignite的一个常见思路就是将现有的关系型数据库中的数据导入到ignite中,然后直接使用ignite中的数据,相当于将ignite作为一个缓存服务,当然ignite的功能远不止于此,下面以 ...
- Redis系列(四)--持久化
持久化就是将数据的更新异步的保存到磁盘中 持久化方式: 1.快照:某个时间点数据的备份 MySQL dump.Redis RDB 2.写日志:MySQL BinLog.HBASE Hlog.Redis ...
随机推荐
- 如何实现css渐变圆角边框
最近设计师的风格发生突变,一句话概括就是,能用渐变的地方绝对不用纯色.这不,就整出了一个渐变圆角边框.这渐变好做,圆角好做,渐变圆角也没问题,可是在加个边框还是有点坑的.没办法,看看怎么实现吧 bor ...
- windows server2012 nVME和网卡等驱动和不识别RAID10问题
安装2012---不识别M.2 nVME,下官方驱动,注入到系统里 缺多驱动---用ITSK万能驱动添加:|Win8012R2.x64(可解决不支持操作系统,win10与server2012R2通用) ...
- 使用idea在linux上启动springboot项目
springboot项目启动方式 1.改成war包放到tomcat上,网上方法很多不再介绍. 2.直接用jar包启动,比较方便,不需要修改项目文件,推荐使用jar包起 将项目和package打成jar ...
- 种族并查集模板题分析 -----P2024 [NOI2001]食物链
本文参考了:洛谷p2024题解 题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都 ...
- MySQL基础(用的贼鸡儿多)
整理有点乱,业余也玩玩系统,经常碰见这些玩意,有点烦,老是记不住 MySQL 基础语法 一.连接 MYSQL格式: mysql -h 主机地址 -u 用户名 -p 用户密码. 1.连接到本机上的 MY ...
- vue-cli报错:Class constructor FileManager cannot be invoked without 'new'
bug:vue-cli3开发的项目,今天项目重新下载依赖启动项目的时候出现错误:Class constructor FileManager cannot be invoked without 'new ...
- mac下面有epoll?
没有的,但是mac下面有kqueue,跟epoll原理是差不多的. 这个是没办法的,如果实在需要,就用Ubuntu吧,这个也可以无缝迁移. 更多资源,更多文章由小白技术社提供(是我啦)
- Redis学习总结(二)--Redis数据结构
Redis支持六种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 结构类型 存储的值 string 可以是字符串.浮 ...
- python 27 异常处理
目录 异常处理 1. 错误分类 2. 异常 3. 异常处理 4. 异常处理的两种方法 5. try的结构 5.1 结构一:单分支结构 5.2 结构二:多分支结构 5.3 结构三:万能异常 5.4 结构 ...
- Codeforces 976F
题意略. 思路:为了保证每个点都有至少k条边覆盖,我们可以让二分图的左半边与源点s相连,连容量为indegree[i] - k的边(如果正着想不好想,我们可以想它的反面, 限制它反面的上限,从而保证我 ...