通过将数据的工作集放入系统内存中,内存中方法可以达到极高的速度。 当所有数据都保存在内存中后,处理使用传统旋转磁盘引起的问题的需求就消失了。 例如,这意味着无需维护数据的其他缓存副本并管理它们之间的同步。 但是这种方法还有一个缺点,因为数据仅在内存中,如果整个集群都终止了,数据将无法生存。 因此,根本不认为此类数据存储具有持久性。
在这篇博客文章中,我将努力探索Apache Ignite的本机持久性新功能,并提供清晰易懂的图片,说明Apache Ignite的本机持久性如何工作。
在大多数情况下,您不能(不应)将整个数据集存储在应用程序的内存中,通常,您应该存储相对较小的热数据或活动数据子集,以提高应用程序的性能。 其余数据应存储在低成本磁盘或磁带中的某个位置以进行归档。 有两种主要的内存数据库存储需求:
- 如果需要将内存数据库重新加载到内存中,则永久介质可以存储已提交的事务,从而保持持久性并用于恢复目的。
- 永久存储,用于保存整个内存数据库的备份副本。
永久性存储或媒体可以是任何分布式或本地文件系统,SAN,NoSQL数据库,甚至是RDBMS(例如Postgres或Oracle)。 Apache Ignite(从1.5版开始)提供了一种优雅的方式来连接持久性数据存储(例如RDBMS或NoSQL DB,例如Mongo DB或Cassandra)。 RDBMS中的持久性通常是瓶颈,并且您永远不会在系统中进行水平扩展。 有关更多信息,我建议您阅读“ 使用Apache Ignite进行高性能内存计算 ”一书中的示例章节。
因此,从版本2.1.0开始 ,Apache Ignite提供了与ACID和SQL兼容的磁盘存储,该磁盘存储与Ignite的持久性内存透明集成,作为可选的磁盘层,用于存储SSD,Flash,3D XPoint和其他类型的非易失性数据和索引仓库。
Apache Ignite本机持久性使用新的持久性内存架构 ,该架构允许存储和处理数据以及在内存中和磁盘上建立索引。 只要启用该功能,Apache Ignite就会根据其容量将超数据集存储在磁盘上,并将一部分数据存储在RAM中。 如果RAM中缺少数据子集或索引,则耐用内存将从磁盘中取出数据,如下图所示。
数据也可以存储在中央磁盘存储中,所有Ignite节点都连接在中央磁盘存储中,如下所示。
在开始之前,让我们在沙盒中介绍项目的先决条件:
- Apache Ignite版本2.1.0
- JVM 1.8
- Apache Maven版本> 3.0.3
- *基于nix的操作系统
安装。
基本上有两种使用Apache Ignite的方法:
- 下载二进制发行版,然后将归档文件解压缩到操作系统中的某个位置,然后使用spring config文件运行./ignite.sh bash脚本。
- 使用所需的Apache Ignite依赖关系创建一个maven项目,通过Java代码配置节点并运行它。
在这里,我将使用第一个选项。
步骤1。
- 下载 Apache Ignite二进制发行版,并将发行版解压缩到沙箱中的某个位置。
- 修改IGNITE_HOME / examples / config / persistentstore / example-persistent-store.xml文件,并注释高速缓存配置的以下部分。
<property name="cacheConfiguration">
<list><bean class="org.apache.ignite.configuration.CacheConfiguration"><property name="name" value="testCache"/><property name="backups" value="1"/><property name="atomicityMode" value="TRANSACTIONAL"/><property name="writeSynchronizationMode" value="FULL_SYNC"/><property name="indexedTypes"><list><value>java.lang.Long</value><value>org.apache.ignite.examples.model.Organization</value></list></property></bean></list>
</property>
请注意,要启用Ignite本机持久性,只需传递以下配置(PersistentStoreConfiguration的实例),该配置已在example-persistent-store.XML文件中进行了预配置。
<property name="persistentStoreConfiguration">
<bean class="org.apache.ignite.configuration.PersistentStoreConfiguration"/>
</property>
- 从IGNITE_HOME目录运行以下命令。
./ignite.sh $IGNITE_HOME/examples/config/persistentstore/example-persistent-store.xml
Step 2. create a Maven project with the following command.
mvn archetype:create -DgroupId=com.blu.imdg -DartifactId=ignite-persistence
- 在pom.xml中添加以下依赖项
<dependency><groupId>org.apache.ignite</groupId><artifactId>ignite-core</artifactId><version>2.1.0</version></dependency><dependency><groupId>org.apache.ignite</groupId><artifactId>ignite-spring</artifactId><version>2.1.0</version></dependency><dependency><groupId>org.apache.ignite</groupId><artifactId>ignite-indexing</artifactId><version>2.1.0</version></dependency>
- 创建具有以下内容的Java类。
public class HelloWorld {public static void main(String[] args) {System.out.println("Hello Ignite");// create a new instance of TCP Discovery SPITcpDiscoverySpi spi = new TcpDiscoverySpi();// create a new instance of tcp discovery multicast ip finderTcpDiscoveryMulticastIpFinder tcMp = new TcpDiscoveryMulticastIpFinder();tcMp.setAddresses(Arrays.asList("localhost")); // change your IP address here// set the multi cast ip finder for spispi.setIpFinder(tcMp);// create new ignite configurationIgniteConfiguration cfg = new IgniteConfiguration();cfg.setClientMode(true);// set the discovery§ spi to ignite configurationcfg.setDiscoverySpi(spi);// Start igniteIgnite ignite = Ignition.start(cfg);ignite.active(true);// get or create cacheIgniteCache cache = ignite.getOrCreateCache("testCache");// put some cache elementsfor (int i = 1; i <= 100; i++) {cache.put(i, Integer.toString(i));}// get them from the cache and write to the consolefor (int i = 1; i <= 100; i++) {System.out.println("Cache get:" + cache.get(i));}ignite.close();}
}
请注意,我们使用Ignite客户端模式来处理数据。 运行HelloWorld应用程序后,应在缓存中插入100个元素(缓存名称
testCache )。
第三步
- 让我们使用ignitevisor命令工具检查数据。 在ignitevisor命令工具中使用cache -scan命令。 您应该在控制台中得到类似的插图。 缓存中的所有100个元素。
- 现在,让我们看看引擎盖下发生了什么。
du -h .
您应该在控制台中得到如下所示的内容。
如果启用Apache Ignite本机持久性,则Ignite将在所有群集节点上的内存和磁盘上持久存储所有数据和索引。
如果要浏览目录db / 0_0_0_0_0_0_0__10_211_55_2_10_37_129_2_127_0_0_1_192_168_1_37_47500(在我的情况下),则将为每个缓存找到单独的文件夹。 名称为cache-testCache的文件夹将包含我们刚刚插入的所有缓存条目(100个元素)。
文件index.bin是缓存条目的索引,每个缓存元素都获取其各自的页面文件。 为什么会这样呢? 现在,Ignite体系结构是基于页面的体系结构。 让我们仔细看看,内存现在分为区域->区域分为段->段分为页。 页面可以交换到磁盘中。 页面可以存储:
- 数据
- 元数据
- 指数
页面是固定长度的块,它还支持自动碎片整理。 如果仔细看一下页面大小,它们全都是14 KB。 每当Ignite需要从磁盘加载数据时,它只会加载页面文件,因此速度非常快。
同样,在预写日志(WAL)上还有另一个概念。 如果进行更新,则首先将更新内存中的数据并将页面标记为脏,然后将数据持久保存到预写日志中。 点燃只是将更新附加到WAL文件中。 WAL文件与Cassandra commitlog文件非常相似,但有一个区别。 Cassandra将并行写入内存和磁盘上的commitlog文件,另一方面,Ignite首先将数据更新到内存中,然后将数据附加到WAL中。 有关更多信息,我建议您看看
文档 ,这是非常详尽的。
第四步。
- 重新启动Ignite节点,并检查缓存
testCache与
点火器 。 您最终会感到惊讶,因为没有数据进入缓存。
- 让我们稍微修改一下helloworld类,然后再次运行该应用程序,注释或删除以下代码片段,如下所示。
// put some cache elements
for (int i = 1; i <= 100; i++) {cache.put(i, Integer.toString(i));
}
Run the application and check the cache testCache through ignitevisor and you application console.
每当发生任何读取请求时,Ignite首先都会将数据检入内存。 如果内存中不存在该数据集,则Ignite立即从磁盘加载缓存条目并加载到内存中。 还要注意的是,所有条目都以堆的形式进入内存。
好处 。
使用Ignite本机持久性,现在您可以轻松地进行数据恢复备份,Denis Magda通过使用Ignite本机持久性撰写了一篇有关数据恢复的综合文章 。 我在这里必须提到的一件事是集群之间的数据复制。 通过使用Ignite本机持久性,现在您可以在线将数据从一个群集复制到另一个群集。 您可以使用任何基于磁盘的标准数据复制工具将已更改的数据集从主数据中心复制到备用数据中心或Ignite群集。
翻译自: https://www.javacodegeeks.com/2017/09/apache-ignite-native-persistence-brief-overview.html