很多人会问,Ignite有没有持久化存储,或者说是不是一个单纯的内存存储?
答案是都有,Ignite的原生持久化可以打开,也可以关闭。这使得Ignite可以存储比可用内存量大得多的数据集,也就是说,少量的操作型数据集可以只存储于内存中,而内存装不下的更大的数据集可以存储在磁盘上,这样将内存作为一个缓存层,性能会更好。
Ignite原生持久化
Ignite原生持久化是一个分布式的支持ACID和兼容SQL的磁盘存储,它可以与Ignite的固化内存架构透明地集成。Ignite的持久化是可选的,可以打开也可以关闭,如果关闭,Ignite就是一个纯内存的存储。
打开原生持久化之后,Ignite会始终在磁盘上存储数据的超集,然后根据内存的容量在其中存储尽可能多的数据。比如,一共有100条数据,然后内存容量只能存储20条,那么所有的100条都会存储于磁盘上,然后在内存中只缓存20条数据,这样性能会更好。
此外,还要注意,和内存存储的场景一样,如果打开了持久化,每一个节点只会持有所有数据的一个子集,只会包含该节点作为主/备节点所属分区的数据,而整个集群则包含完整的数据集。
不同于作为备份持久层的第三方数据库,Ignite的原生持久化有如下的关键特性:
- SQL查询可以跨越内存和磁盘的完整数据集,这意味着Ignite可以作为以内存为中心的分布式SQL数据库;
- 不需要将所有的数据和索引放在内存中,Ignite持久化可以在磁盘上存储数据的超集,然后只将最常用的子集保存在内存中;
- 即时集群重启。如果整个集群下线,那么不需要从Ignite持久化中通过数据预加载对内存进行预热,只要所有节点组成集群,那么整个集群就会变为可用状态;
- 数据和索引以类似的格式存储于内存和磁盘上,这样有助于在内存和磁盘之间移动数据时昂贵的转换开销;
- 通过接入第三方的解决方案,可以创建完整的或者增量的集群快照功能。
用法
要启用原生持久化,需要给集群节点的配置传递一个DataStorageConfiguration
对象:
启用持久化之后,数据和索引将存储于所有对应节点的内存和磁盘上,下图显示了每个节点中文件系统层面的Ignite持久化的结构。
内存区和缓存级的持久化
Ignite可以为具体的某个内存区开启持久化,从而也可以为某个缓存开启持久化,具体细节可以参见内存区配置相关章节的介绍。
节点中部署的每个缓存都有一个唯一的目录,从上图可以看到,节点至少维护了两个缓存(Cache_A
和Cache_B
)。
对于该节点(不管是主节点还是备节点)的每个分区,持久化都会在文件系统中创建专用的文件,比如在上图所示的节点中,负责了分区1,10和564,而索引是每个缓存一个文件。
缓存组和分区文件
如果Cache_A
和Cache_B
属于同一个缓存组,则会只有一个目录,两个缓存会共享分区文件,具体细节可以参见缓存组的相关文档。
最后,还有和预写日志有关的文件和目录,具体细节可以参见预写日志和检查点的相关文档。
集群激活
要注意,如果使用Ignite的原生持久化,集群默认会处于非激活状态,无法进行任何CRUD操作,用户需要手工对集群进行激活,关于如何激活集群的更多信息,可以参见基线拓扑的相关内容。
上面描述的文件层次结构,默认位于${IGNITE_HOME}/work/db
共享目录下,要改变存储和WAL文件的默认位置,可以分别使用DataStorageConfiguration
的setStoragePath(...)
,setWalPath(...)
和setWalArchivePath(...)
方法。
如果在一台主机上启动了多个节点,那么每个节点进程会在一个比如${IGNITE_HOME}/work/db/node{IDX}-{UUID}
这样的唯一子文件夹中有自己的持久化文件,这里的IDX
和UUID
由Ignite在节点启动时自动计算,这里有详细的计算方法。如果在持久化文件层次结构中已经有了若干node{IDX}-{UUID}
子目录,那么会按照先进先出的顺序在节点间进行分配。如果要为一个节点分配固定的子文件夹,即使节点重启也不会发生变化,可以在集群范围使用IgniteConfiguration.setConsistentId()
配置一个唯一值,这个唯一性ID在node{IDX}-{UUID}
字符串中会映射到UUID
。
单主机中隔离集群的节点
Ignite可以在一台主机中运行彼此隔离的多个节点,这种情况下,每个集群需要在不同的目录结构中存储自己的持久化文件,使用DataStorageConfiguration
的setStoragePath(...)
、setWalPath(...)
和setWalArchivePath(...)
方法可以对这些路径进行修改。
事务保证
Ignite的原生持久化是一个兼容ACID的分布式存储,每个写入存储的更新都会先附加到WAL日志,该更新由一个唯一ID进行标识,这就是说,在故障或者重新启动后,集群始终可以恢复到最近成功提交的事务或者原子更新。
SQL支持
Ignite原生持久化可以将Ignite作为一个分布式的SQL数据库。
如果希望在整个集群中执行SQL查询,那么不需要将所有的数据都保存在内存中,Ignite是可以同时在内存和磁盘上执行SQL查询的,也就是只要集群启动运行,就可以执行SQL查询了,虽然也可以选择在集群重启后将数据从持久化预加载到内存中,但是这不是必须的。
Ignite持久化的内部设计
Ignite持久化的文档,提供的是一个高层视图,如果希望了解更底层的技术细节,可以看下面的资料:
性能提示
相关的性能优化建议,可以参见固化内存调优相关章节的文档。
示例
如果要了解Ignite原生持久化在实践中是如何使用的,可以参见GitHub上的示例代码,它也会随着每个Ignite发行版一起提供。
来源:oschina
链接:https://my.oschina.net/u/1259554/blog/3008875