5分钟内让你了解Apache Ignite - softwaremill


Apache Ignite是一个水平可扩展的,容错的分布式内存计算平台,用于构建实时应用程序,该应用程序可以以内存速度处理数TB的数据。
它是一个分布式系统。Apache Ignite形成一个集群,可以两种模式运行:分区和复制。

  • 分区意味着数据通过key分布在节点上,例如MongoDB中的分片,或Kafka和Cassandra中的分区。分区缓存是处理大型数据集且频繁更新的理想选择。
  • 复制 是在每个节点上存储所有数据,对于高速缓存读取比高速缓存写入要频繁得多且数据集较小的情况,此模式是理想的。

还可以设置备份数量。这是备份主节点但不处理任何请求的节点数。可以同步或异步完成对备份副本的写入。
另一个重要功能是可以将数据持久保存在符合ACID的分布式存储中:
Ignite本机持久性是一种分布式ACID和SQL兼容的磁盘存储,可透明地与Ignite的持久性内存集成。点燃持久性是可选的,可以打开和关闭。禁用后,Ignite将成为纯内存存储。
这里的本机意味着它内置在项目中,而不是e依赖Ignit的外部解决方案。

Apache Ignite最常见的用例是什么?
内存数据网格
为了应对快速写入,我们可以将Apache Cassandra用作数据存储,而要实现快速随机读取,我们可以将Apache Ignite用作内存中的数据网格。

分布式key-value存储
与数据网格类似,它是内存中的缓存层。它实现了JCache规范(JSR 107),实现了对位于同一位置的数据(位于同一节点上)的计算,并运行连续查询以通知客户端数据更新。
一个很好的例子是将Ignite用作HTTP会话存储实现。

数字集成中心
再次类似于数据网格,Ignite跨多个数据存储,可以查询,因为它将是一个统一的共享数据存储。
假设您有几个RDBMS,例如MySQL,PostgreSQL和Oracle DB,并且希望将它们作为一个可查询的数据库公开在一起。但是请注意表连接:它们将在Ignite内存中进行,因此所有必需的数据都将首先加载到Ignite内存中。
同样,所有写入操作都必须通过Apache Ignite进行,以防止内存中的内容与底层数据存储之间的不一致。

用于高性能计算
遵循MapReduce范式的计算可以在共置数据上运行。由于对内存和一个节点中加载的数据进行了计算,因此可以实现高性能。不需要通过网络进行数据改组和磁盘I / O操作。

共享给Apache Spark
将数据加载到内存中并将其作为RDD提供给Spark可以提高Spark应用程序的性能。

Apache Ignite与CAP定理?
与其他分布式系统(如Apache Kafka或Cassandra)类似,可以将Apache Ignite配置为实现更高的可用性(AP)或放弃可用性以确保一致性(CP)。
尽管文档中还不清晰,,但是配置如何影响可用性或一致性,但是我在邮件列表中发现了以下语句:

[i]当群集丢失分区的所有副本时,行为由[url=https://apacheignite.readme.io/docs/partition-loss-policies]PartitionLossPolicy[/url]定义。当前默认值为IGNORE,它的确是AP而不是CP选项。您可以将其设置为READ_WRITE_SAFE或READ_ONLY_SAFE以获取CP行为。[/i]

这篇有关Apache Ignite和CAP定理的博客文章提到了内部机制,这些机制使Ignite在设计上被视为CP系统。
除了CAP的一致性外,让我们看一下ACID中的一致性。存在三种原子模式,可以在其中执行高速缓存操作。
一个TRANSACTIONAL事务操作:
.…您可以将一个或多个键上的多个缓存操作分组为一个逻辑操作,称为事务。这些操作将在没有对指定键进行任何其他交错操作的情况下执行,并且将全部成功或全部失败。没有部分执行操作。

通过2PC(两阶段提交协议)支持完整的ACID事务,但是如果仅在一个节点上执行事务,则使用重量更轻的版本1PC。
一个ATOMIC原子性在另一方面操作执行一次为多个业务之一。
这些原子性模式是在客户端级别配置的,并且可能因调用而异。
在此TRANSACTIONAL模式下,支持两种锁定策略-悲观锁定和乐观锁定。在悲观锁定中,超时触发器将检测死锁。但是,客户端的责任是始终以相同的顺序获取锁,并使获取的锁的数量保持较低,并按节点对它们进行排序以减少网络流量。
使用乐观锁,在读取过程中会记录版本号,在写入时会将其与当前版本进行比较。在版本不匹配时,事务将回滚。
最后一个有趣的提示:如果在多个Ignite节点之间使用分布式事务,则在第二阶段中,一个节点可能无法提交,因此必须手动回滚该事务。那是2PC的乐趣。
此外,当一个数据存储完成提交并在第二个数据存储完成提交之前将其提供给客户端时,基础数据存储之间可能会发生不一致。如果第二次提交失败,则第一个提交不会自动回滚。

脑裂
当发生网络分区时,就会发生裂脑情况。您最终有两个集群,必须决定要做什么。接受请求并最终在节点之间恢复一致性(解决冲突)?还是禁用其中一个群集?
Apache Ignite有一些解决此问题的方法。
一种基于TCP / IP发现和基准拓扑,其中在分区的情况下,当分区固定后,两个群集将不再形成一个群集。这样可以防止数据被覆盖。但是,您有责任拆除并重新启动排除的节点,以便它们可以追上幸存的节点。同样,如果两个不相交的群集获得同一密钥的更新,则这些冲突的更改需要手动解决。
另一种裂脑解决策略是基于Zookeeper Discovery的。每个节点都知道群集拓扑。如果某个节点发现无法联系另一个节点,则会向Zookeeper投诉。Zookeeper拥有拓扑的全局概述,还提供有关谁可以看到谁的数据,并且可以通过告诉哪些节点保留在集群中以及哪些节点被排除在如何做出明智的决定上,从而决定如何解析网络分区。
GitHub上还有一个插件,以及GridGain的商业裂脑解析器。

流函数
是关于将数据移至Ignite,执行转换并对该数据进行连续查询。
流分批执行。它们按节点分组。这意味着,一个节点的批处理可以比另一个节点的发送更早,尽管一些消息到达较晚,但完成了该批处理,因为第一个仍在等待更多消息。换句话说,不保留排序。
由于批次可能会失败并重新交付,因此流式传输至少可以保证交付一次。因此,您必须在覆盖或忽略键值(已存在)之间进行选择。同样,第二批也不会等到第一批成功交付后再进行。因此,也不会保留特定节点内的排序。
通过Kafka连接器可以使用Kafka进行流的导入导出。

什么是Apache Ignite替代品或竞争产品?
与Apache Ignite相似,Hazelcast也被宣传为内存计算平台。同样,它与SQL数据库集成,但不支持事务。
Redisson,用于Redis的Java客户端还设有一个内存中数据网格。
在分析方面,Druid中提供了类似的功能。尽管支持连接,但仅限于较小的查找表。
最后但并非最不重要的一点是,Infinispan被宣传为具有两个主要用例(例如缓存或数据网格)的内存中数据存储。
总而言之,当需要执行复杂的SQL操作时,Apache Ignite似乎会发光。否则,替代工具可能会更好。