为了更好地理解Apache Ignite和用例的功能,理解它的体系结构和拓扑结构非常重要。通过更好地理解Ignite的体系结构,可以决定拓扑或缓存模式,以解决企业体系结构场景中的不同问题,并从内存计算中获得最大的益处。与主从设计不同,Ignite使用了一个完全对等的架构。ignite集群中的每个节点都可以接受读写,无论数据在哪里写入。本章主要内容:
- 功能概述
- 不同的集群拓扑
- 集群拓扑结构
- 缓存策略
- 集群划分
- 数据模型
- 多数据中心复制
- 异步支持
- SQL查询如何在Ignite中工作
- 弹性
功能概述
Ignite体系结构具有足够的灵活性和高级特性,可用于大量不同的体系结构模式和风格。您可以将Ignite看作是一组独立的、集成良好的内存中组件的集合,以提高应用程序的性能和可伸缩性。下面的示意图表示Apache Ignite的基本功能:
Ignite是以模块化的方式进行组织,并为每个功能提供一个jar(库)。您只需将所需的库应用到项目中,就可以使用Ignite。
集群拓扑
Ignite的设计表明整个系统本身就具有固有的可用性和可扩展性。ignite节点间通信允许所有节点接收更新,无需一个快速的主协调器。节点可以不受干扰地添加或删除,以增加可用RAM的数量。
Ignite数据结构具有完全的弹性,允许对单个服务器或多个服务器进行无干扰的自动检测和恢复。
客户端和服务端
Apache Ignite具有一个可选的服务概念,并提供了两种类型的节点:客户端和服务器节点。
- Server 包含数据、缓存、计算和流,并且可以是内存中的Map-Reduce任务的一部分。
-
Client 提供远程连接服务器以将元素放入/获取到缓存的能力。它还可以存储部分数据(近缓存),这是一个较小的本地缓存,存储最近和最频繁访问的数据。
还可以将服务器节点分组到一个集群中执行工作。在集群中,可以限制作业执行、服务部署、流和其他任务只在集群组中运行。
你可以基于任何谓词创建一个集群组。例如,您可以从一组节点创建一个集群组,其中所有节点负责为testCache缓存数据。默认情况下,所有节点都作为服务节点启动。客户端模式需要显式启用。注意,您不能物理地将数据节点与计算节点分离。在Apache Ignite中,包含数据的服务器也用于执行计算。Apache Ignite客户机节点也参与作业执行。乍一看,这个概念似乎很复杂,但让我们试着澄清这个概念。服务器节点总是存储数据,默认情况下可以参与任何计算任务。另一方面,客户端节点可以操作服务器缓存、存储本地数据并参与计算任务。通常,客户端节点用于从缓存中放置或检索数据。这种混合客户端节点在开发具有多个节点的大型Ignite网格时提供了灵活性。客户端和服务器节点都位于一个网格中,在某些情况下(例如,数据节点中的大容量acid事务),您不希望在数据节点上执行任何计算。在这种情况下,您可以通过创建相应的集群组来选择只在客户端节点上执行作业。通过这种方式,您可以在一个网格中将数据节点与计算节点分开。可以使用以下伪代码对客户端进行计算:
ClusterGroup clientGroup = ignite.cluster().forClients(); IgniteCompute clientCompute = ignite.compute(clientGroup);
// Execute computation on the client nodes. clientCompute.broadcast(() -> System.out.println("sum of: " + (2+2)));
这种方法有一个缺点。使用这种方法,数据将被分配给独立的节点,并且为了计算这些数据,所有的客户端节点都需要从服务器节点检索数据。它可以产生大量的网络连接并产生延迟。但是,您可以在一个主机上单独的JVM上运行客户机和服务器节点,以减少网络延迟。从部署的角度来看,Apache Ignite服务器可以分为以下几个组:
- 内置应用程序
- 服务器在单独的JVM
内置应用程序
使用这种方法,Apache Ignite节点与应用程序在同一个JVM上运行。它可以是运行在应用服务器上的任何web应用程序,也可以是独立的Java应用程序。例如,我们的独立HelloIgnite应用程序是来自第一章—是一个嵌入式的Ignite。Ignite服务器与应用程序一起在相同的JVM中运行,并与网格的其他节点连接。如果应用程序宕机或被关闭,则Ignite server也将关闭。拓扑如下图所示:
服务器在单独的JVM
在这种方法中,服务器节点将在独立的JVM中运行,客户机节点将远程连接到服务器。服务器节点参与缓存、计算执行、流等等。客户端还可以使用REST API连接到任何单独的节点。默认情况下,所有的Ignite节点都作为服务器节点启动;客户端节点需要显式启用。
这是最常见的方法,因为它在集群机制方面提供了更大的灵活性。Ignite服务器可以被离线并重新启动,不会对整个应用程序或集群产生任何影响。
客户机和服务器分别位于单个主机上的JVM中
当您的数据节点上有大量事务并计划在该节点上执行一些计算时,您可以考虑这种方法。您可以在一个容器(例如Docker或OpenVZ)中单独的JVM中执行客户机和服务器。容器可以位于单个主机中。容器将隔离资源(cpu、ram、网络接口等),JVM只使用分配给这个容器的独立资源。
这种方法也有它自己的缺点。在执行过程中,客户端(compute)节点可以从驻留在其他主机上的任何其他数据节点检索数据,并且可以增加网络延迟。
缓存拓扑
Ignite提供了三种不同的缓存拓扑的方法::分区,复制和本地。缓存模式分别为每个缓存配置。每个缓存拓扑都有其优缺点。默认缓存拓扑是分区的,没有任何备份选项。
分区缓存拓扑
这种拓扑的目标是获得极好的可扩展性。在这种模式下,Ignite集群透明地对缓存的数据进行分区,以便在整个集群中均匀地分配负载。通过均匀地划分数据,缓存的大小和处理能力随集群的大小呈线性增长。管理数据的职责在整个集群中自动共享。集群中的每个节点或服务器都包含其主数据,如果定义了备份副本,则包含备份副本。
对于分区缓存拓扑,缓存上的DML操作非常快,因为每个键只需要更新一个主节点(可选为一个或多个备份节点)。对于高可用性,应该配置缓存条目的备份副本。备份副本是一个或多个主副本的冗余副本,该副本将驻留在另一个节点中。有一个简单的公式可以计算,为了实现集群的高可用性,需要多少备份。
备份拷贝数= N-1,其中N为集群中节点的总数
假设集群中总共有3个节点。如果您总是希望从集群获得响应(当某些节点不可用时),备份副本的数量应该不少于2。在这种情况下,存在3个缓存条目副本,2个备份副本和1个主副本。当处理大型数据集时或更新非常频繁,分区是适合的方式。备份过程可以是同步的,也可以是异步的。在同步模式下,客户端应该在完成提交或写入之前等待远程节点的响应。
缓存复制拓扑
这种方法的目标是获得极高的性能。使用这种方法,缓存数据被复制到集群的所有成员。由于数据被复制到每个集群节点,因此可以使用它而无需等待。这为读取提供了可能的最高速度。每个成员都从自己的内存访问数据。缺点是频繁的写操作非常昂贵。更新复制缓存需要将新版本推给所有其他集群成员。如果更新频率很高,这将限制可伸缩性。
在上图中,相同的数据存储在所有集群节点中;复制缓存的大小受每个节点上可用内存大小的限制。这种模式适用于缓存读取比缓存写入频繁得多,而且数据集很小的场景。复制的可伸缩性与成员数量、每个成员更新的频率和更新的大小成反比。
本地模式
这是缓存模式的一个非常原始的版本;使用这种方法,没有数据分布到集群中的其他节点。就本地缓存而言,没有任何复制或分区过程,数据获取非常便捷和快速。它为最近和经常使用的数据提供零延迟访问。本地缓存主要用于只读操作。它对于读/写传递行为也非常有效,在这种行为中,数据是在缓存丢失时从数据源中加载的。与分布式缓存不同,本地缓存仍然具有分布式缓存的所有特性;它提供查询缓存、自动数据删除等功能。
缓存策略
随着高交易量的web应用程序和移动应用程序的激增,数据存储已成为性能的主要瓶颈。在大多数情况下,持久性存储(如关系数据库)不能通过添加更多的服务器来完美地扩展。在这种情况下,内存中的分布式缓存为解决数据存储瓶颈提供了一个很好的解决方案。
它扩展了多个服务器(称为网格),将它们的内存集中在一起,并在所有服务器上保持缓存的同步。在分布式内存缓存中有两种主要策略:
Cache-aside
在这种方法中,应用程序负责从持久性存储区进行读写。缓存根本不与数据库交互。这叫做cache-aside。缓存的行为就像一个快速扩展的内存数据存储。应用程序在查询数据存储之前检查缓存中的数据。此外,应用程序在对持久性存储进行任何更改后更新缓存。
然而,尽管cache-aside的速度非常快,但是这种策略也有一些缺点。如果多个应用程序处理相同的数据存储,应用程序代码可能变得复杂,并可能导致代码重复。当缓存数据丢失时,应用程序将查询数据存储、更新缓存并继续处理。如果不同的应用程序线程同时执行此处理,则可能导致多个数据存储访问。
Read-through and Write-through
这就是应用程序对内存缓存作为主要的数据存储,并读取数据并将数据写入。内存内缓存负责在缓存丢失时将查询传播到数据存储。此外,数据在缓存中更新时将自动更新。所有通读和写操作都将参与整个缓存事务,并作为一个整体提交或回滚。
Read-through and Write-through比cache-aside有许多优势。首先,它简化了应用程序代码。读入允许缓存在自动过期时从数据库重新加载对象。这意味着您的应用程序不必在高峰时间访问数据库,因为最新的数据总是在缓存中。
Write behind
也可以使用write-behind来获得更好的写性能。Write-behind允许应用程序快速更新缓存并返回。然后,它聚合更新并将其作为批量操作异步刷新到持久性存储中。同样,对于Write-behind,您可以指定节流限制,因此数据库写入速度不如缓存更新快,因此对数据库的压力更小。此外,您可以安排数据库写操作在非高峰时间发生,这可以最小化对数据库的压力。
Apache Ignite通过实现Java JCache特性提供了上述所有缓存策略。此外,Ignite提供了Ignite Cassandra模块,它通过使用Cassandra作为过期缓存条目的持久存储来实现Ignite缓存的持久性存储。
数据模型
Apache Ignite实现了键值数据模型,特别是JCache (JSR 107)规范。JCache为Java应用程序与缓存交互提供了一种常见的方式。
从设计的角度来看,JCache提供了一个非常简单的键值存储。键值存储是一个简单的Hashtable或Map,主要用于通过主键访问数据库表。您可以将键值作为传统RDBMS中的一个简单表,其中包含两个列,如键和值。值列的数据类型可以是任何原始数据类型,如字符串、整数或任何复杂的Java对象(或Blob - in Oracle术语)。应用程序可以提供一个键和值并将它们持久化。如果键已经存在,将覆盖该值,否则将创建一个新值。为了清晰起见,我们可以将键值存储与Oracle术语进行比较:
它有非常原始的操作,比如从存储中放置、获取或删除值。因为它总是使用主键访问,所以它们通常有很好的性能和可扩展性。Java缓存API定义了五个核心接口:CachingProvider、CacheManager、Cache、Entry和Expire。
- CachingProvider定义了建立、配置、获取、管理和控制零个或多个cachemanager的机制
- CacheManager定义了在CacheManager上下文中建立、配置、获取、管理和控制唯一命名缓存的机制。
- 缓存是类似于数据结构的哈希表,允许临时存储基于键的值。缓存属于单个CacheManager。
-
条目是存储在缓存中的一个键-值对。
键值对可以在图中很容易地进行说明。考虑以下缓存中的条目图:
通过键值存储,Java缓存API还提供了以下附加特性:
- 基本的缓存操作
- 原子操作,类似于java.util.ConcurrentMap
- 通读缓存
- 直写式高速缓存
- 条目处理器
- 缓存事件监听器
- 统计数据
- 完整的泛型API用于编译时的安全性
- 按引用存储(仅适用于堆缓存)和按值存储
除了JCache之外,Apache Ignite还提供了ACID事务、SQL查询功能、数据加载、异步模式和各种内存模型。Apache Ignite提供了IgniteCache接口,它扩展了使用缓存的Java缓存接口。
CAP定理
当第一次开始使用Apache Ignite时,想知道Ignite一方面支持ACID事务,另一方面,Ignite也是一个高度可用的分布式系统。在任何NoSQL数据存储中,支持ACID事务并同时提供高可用性都是一个具有挑战性的特性。要横向扩展,需要强大的网络分区容忍度,这需要放弃一致性或可用性。NoSQL系统通常通过放松关系可用性或事务语义来实现这一点。许多流行的NoSQL数据存储(如Cassandra和Riak)仍然没有事务支持,并被归类为AP系统。AP一词来源于著名的CAP定理10,意为可用性和分区容忍性,在NoSQL系统中,这比一致性更重要。
如上图所见,分布式系统只能具有以下三个属性中的两个:
- 分区容忍性:也就是说,如果在两个节点之间断开网络,系统仍然可以工作。
- 一致性:在集群中的每个节点有相同的数据。
- 可用性:如果可能的话总有一个节点可进行响应查询。
因此,让我们看看三种选择中有两种会如何影响系统行为,如下所示: - CA系统:在这种方法中,为了获得一致性和可用性,牺牲了分区容忍性。数据库系统提供了事务,系统是高度可用的。大多数关系数据库被归类为CA系统。该系统存在严重的扩展问题。
- CP系统:在CP系统中,为了一致性和容错而牺牲了可用性。在节点失败的情况下,将丢失一些数据。
-
AP系统:这个系统总是可用的和可分区的。此外,通过向集群添加节点,该系统可以轻松地扩展。Cassandra是这类系统的一个很好的例子。
现在,我们回到我们的问题,Ignite在CAP定理中的哪个位置?乍一看,Ignite可以被分到CP类,因为它是完全兼容ACID的分布式事务,具有分区容错性。但这只是一部分。Apache Ignite也可以看作是AP系统。为什么Ignite有两种不同的分类?因为它有两种不同的用于缓存操作、事务和原子的事务模式。
在事务模式中,您可以在一个事务中对多个DML操作进行分组,并在缓存中提交。在此场景中,Ignitet将通过悲观锁锁定一个访问的数据。如果您为缓存配置备份副本,则Ignite将使用2p提交协议来处理它的事务。
另一方面,在原子模式下,Ignite支持多个原子操作,一次一个。在原子模式下,每个DML操作要么成功要么失败,读和写操作都不会锁定数据。这种模式提供了比事务模式更高的性能。在Ignite cache中进行写入时,对于每一块数据,在主节点中将有一个主副本和一个备份副本(如果定义的话)。当您从Ignite grid读取数据时,总是从主节点读取数据,除非主节点关闭,这时数据将从备份中读取。从这个角度看,您获得了系统可用性和整个系统作为AP系统的分区容忍性。在原子模式中,Ignite与Apache Cassandra非常相似。然而,现实世界的系统很少完全属于上述所有类别,因此将CAP视为一个连续体会更有帮助。大多数系统将努力保持一致性、可用性和分区容错性,许多系统可以根据最重要的部分进行调优。
Clustering
Apache Ignite的设计目标是在集群中跨多个节点处理高工作负载。集群被设计为一组节点。客户端可以向集群中的任何节点发送读/写请求。Ignite节点可以自动发现彼此,并且数据分布在集群中的所有节点上。这有助于在需要时扩展集群,而不需要一次重新启动整个集群。Ignite提供了一种简单的方法来在网格中创建集群节点的逻辑组,并将相关数据配置到类似的节点中,以提高应用程序的性能和可伸缩性。
Cluster group
Ignite ClusterGroup提供了在集群中创建一组逻辑节点的简单方法。按照设计,Ignite集群中的所有节点都是相同的。然而,Ignite允许出于特定目的对任何应用程序的节点进行逻辑分组。例如,您可以将所有节点集中在一起,使用名称myCache服务缓存,或者所有访问缓存myCache的客户端节点。此外,你可能希望仅仅在远程节点上部署服务。你可以限制作业执行、服务部署、消息传递、事件和其他任务只在一些集群组中运行。
Ignite提供了以下三种方法来在Ignite Grid中创建逻辑集群:
- Predefined cluster group(预定义集群组)。Ignite提供了接口的ClusterGroup的预定义实现,以基于任何谓词创建集群组。谓词可以是远程节点、缓存节点、具有指定属性的节点等等。以下代码是一个示例集群组,其中包含缓存myCache的所有节点缓存数据:
IgniteCluster cluster = ignite.cluster();
//名称为“myCache”缓存数据的所有数据节点。
ClusterGroup dataGroup = cluster.forDataNodes("myCache");
- Cluster group with Node Attributes(具有节点属性的群集组)。尽管集群中的每个节点都是相同的,但用户可以配置节点为主节点或worker节点和数据节点。启动时,所有集群节点自动将所有环境和系统属性注册成为节点的属性。但是,用户可以通过配置来选择分配自己的节点属性:
IgniteConfiguration cfg = new IgniteConfiguration();
Map<String, String> attrs = Collections.singletonMap("ROLE", "master");
cfg.setUserAttributes(attrs);
Ignite ignite = Ignition.start(cfg);
在声明节点之后,可以使用属性master对节点进行分组,如下所示:
IgniteCluster cluster = ignite.cluster();
ClusterGroup workerGroup = cluster.forAttribute("ROLE", "master");
Collection<GridNode> workerNodes = workerGroup.nodes();
- Custom cluster group(自定义集群组)。有时它也称为动态集群组。可以根据某些谓词定义动态集群组。谓词可以基于任何指标,如CPU利用率或空闲堆空间。这样的集群组将始终只包含传递谓词的节点。下面是使用了小于256 MB堆内存的节点上的集群组的示例。注意,该组中的节点将根据使用的堆内存随时间而变化:
IgniteCluster cluster = ignite.cluster();
//使用的堆内存小于256MB的节点
ClusterGroup readyNodes = cluster.forPredicate((node) -> node.metrics().getHeapMemoryUsed(\ ) < 256);
Data collocation数据配置
数据配置术语是指将相同的相关数据分配到相同的节点。例如,如果我们有一个缓存为客户属性相关数据和另一个缓存为客户的事务类型的数据。我们可以将他们相关联的数据分配到相同的节点上。在此方法中,相关数据的网络往返次数减少,客户端应用程序可以从单个节点获取数据。在这种情况下,具有相同字段集的多个缓存被分配给相同的节点。
例如,客户信息及其帐户信息位于同一个Ignite主机上。为了实现这一点,用于缓存客户端对象的缓存键应该有一个带有@AffinityKeyMapped注释的字段或方法,这样为帐户对象的key配置提供value。为了方便,您还可以选择使用AffinityKey类,如下所示:
Object clientKey1 = new AffinityKey("Client1", "accId");
Object clientKey2 = new AffinityKey("Client2", "accId ");
Client c1 = new Client (clientKey1, ...);
Client c2 = new Client (clientKey2, ...);
cache.put("accId ", new Account(“credit card”));
cache.put(clientKey1, c1);
cache.put(clientKey2, c2);
要计算关联函数,可以使用任何一组字段,不需要使用任何类型的唯一键。例如,要计算客户端帐户关联函数,可以使用拥有account ID的 client ID。
Compute collocation with Data 数据计算配置
Apache Ignite还提供了将数据计算单元路由到所需数据缓存的节点的能力。这个概念被称为计算和数据的配置。它允许将整个工作单元路由到某个节点。要将计算与数据配置在一起,应该使用IgniteCompute.affinityrun(…)IgniteCompute.affinitycall(…)方法。
下面是如何在客户信息及其帐户信息分配的同一集群节点上配置计算。
String accId = "acountId";
ignite.compute().affinityRun("myCache", accId, () -> { Account account = cache.get(accId);
Client c1 = cache.get(clientKey1);
Client c2 = cache.get(clientKey2);
... });
计算单元以本地方式访问客户数据,这种方法大大降低了数据在集群中的网络往返,提高了数据处理的性能。
Apache Ignite通过两种关联函数实现:
- RendezvousAffinityFunction-这个函数允许在部分到节点的映射中有一点差异(例如,某些节点可能负责比其他节点多一点的分区)。但是,它保证当拓扑发生变化时,分区只能迁移到已连接的节点。集群中的现有节点之间不会发生数据交换。这是Apache Ignite使用的默认关联函数。
- FairAffinityFunction-这个函数试图确保集群节点之间的分区分布是均匀的。这是以集群中现有节点之间可能的分区迁移为代价的。
Zero SPOF 零单点故障
在任何分布式系统中,节点故障应该能够被预判的,特别是当集群的规模增大时。零单点故障(SPOF)设计模式确保系统的单个节点或部分的失效不能阻碍整个集群或系统工作。使用主-从复制或混合主-主系统的系统设计属于这一类。在Hadoop 2.0.0之前,Hadoop NameNode是HDFS集群中的一个SPOF。大多数企业不希望单点失败,原因显而易见。
Apache Ignite作为一个水平可伸缩的分布式系统,其设计方式是使集群中的所有节点都相等,你可以从集群中的任何节点进行读写。在Ignite集群中没有主-从通信。
数据在集群中备份或复制,因此任何节点的失败都不会导致整个集群或应用程序崩溃。通过这种方式,Ignite提供了一种动态的高可用性。这种方法的另一个好处是可以轻松地添加新节点。当新节点加入集群时,它们可以从现有节点上接管一部分数据。因为所有节点都是相同的,所以这种通信可以在运行的集群中无缝地进行。
在Ignite集群中使用SQL
在Ignite中处理SQL查询有两种主要方法:
- In-memory Map-Reduce:如果您正在对分区缓存执行任何SQL查询,Ignite将查询分解为内存中的映射查询和一个单一的reduce查询。map查询的数量取决于分区的大小和集群中的分区数量。然后,在参与缓存的所有数据节点上执行所有的map查询,将结果提供给reduce节点,从而在这些中间结果上运行reduce查询。如果您不熟悉Map-Reduce模式,可以将它想象成一个Java Fork-join过程。
- H2 SQL engine:如果您正在对复制的或本地缓存执行SQL查询,那么Ignite就知道所有数据在本地可用,并在H2数据库引擎中运行一个简单的本地SQL查询。需要注意的是,在复制缓存中,每个节点都包含其他节点的副本数据。H2数据库是一个用Java编写的免费数据库,可以在嵌入式模式下工作。根据配置的不同,每个Ignite节点都可以使用嵌入式H2 SQL引擎。
多数据中心复制
当前,多数据中心复制是任何数据库的主要需求之一,包括RDBMS和NoSQL。简单地说,多数据中心复制意味着在不同的数据中心之间复制数据。多个数据中心复制可以有几个场景:
-
地理位置的场景:在这个场景中,数据应该托管在不同的数据中心中,这取决于用户的位置,以便提供响应性的交换。在这种情况下,数据中心可以位于不同的地理位置,例如在不同的地区或在不同的国家。数据同步在数据中心中是完全透明的,是双向的。在应用程序逻辑代码中可以定义用户将连接到哪个数据中心。
-
实时备份的场景: 在这个场景中,大多数用户使用不同的数据中心作为实时备份,可以快速地用作后备集群。这个用例与灾难恢复非常相似。有时也叫被动复制。在被动复制中,复制发生在一个方向。从主复制到副本。客户端可以连接到一个数据中心的主数据库,并在数据库上执行所有CRUD操作。
为了确保两个数据库之间的一致性,副本作为只读数据库启动,只有从主复制的事务才能修改数据库内容。
Apache Ignite不支持多个数据中心复制。但是可以跨越不同数据中心的Ignite节点(例如,一个数据中心有10个节点,另一个数据中心有10个节点)。
跨越Ignite网格到多个数据中心可以引出一些问题: - Latency延迟:这将在服务端影响性能。如果来自不同数据中心的任何节点都有主数据的备份副本,则事务时间可能非常高。从长远来看,也可能会遇到数据一致性方面的问题。
- 连接到不同数据中心的客户端将面临不同的客户端操作延迟。
异步支持
通常,任何普通的(同步的)put/get或执行调用都会阻塞应用程序的执行,直到从服务器获得结果为止。之后,可以根据客户的需要对结果进行迭代和使用。这可能是处理任何持久性存储的最常见方式。但是,异步方法执行可以提供显著的好处,并且是现代系统的要求。Apache Ignite提供了在所有分布式api上使用异步和同步方法灵活调用的范例。它可以从存储中put/get任何条目,也可以在计算网格中执行作业。Ignite异步方法执行是一个非阻塞操作,并返回一个IgniteFuture对象而不是实际结果。可以通过调用IgniteFuture.get()方法获得结果。以下是一个使用异步调用从Ignite缓存中获取条目的非常简单的例子:
// 获得或者创建缓存
IgniteCache<Integer, String> cache = ignite.getOrCreateCache("testCache");
// 得到一个异步的缓存
IgniteCache<Integer, String> asynCache = cache.withAsync();
// 放一些数据进去
for(int i = 1; i <= 100; i++){
cache.put(i, Integer.toString(i));
}
//异步获取第一条记录
asynCache.withAsync().get(1);
// 获得 future promise
IgniteFuture<String> igniteFuture = asynCache.future();
// java 8 lamda expression
igniteFuture.listen(f-> System.out.println("Cache Value:" + f.get()));
在上面的代码中,我们将100个条目同步插入到Ignite缓存testCache中。然后,异步请求第一个条目并获得调用的future。接下来,异步地侦听要完成的操作。注意,Java main()方法的主线程并不等待任务完成,而是将任务交给另一个线程,然后继续。
- 弹性
Ignite客户端节点在本质上是完全弹性的。弹性这个词指的是服务器或系统在出现故障时快速恢复并继续运行的能力。在某些情况下,Ignite客户端节点可以从集群断开连接: - 主机宕机或重新启动;
- 缓慢的客户端可以被服务器断开连接。
当客户端确定一个节点与集群断开连接时,它尝试重新建立与服务器的连接。这一次,它将分配给一个新的节点ID,并尝试重新连接到集群。
安全
Apache Ignite是一个开源项目,它不提供任何安全特性。
结论
我们介绍了内存数据网格的基本概念。我们首先简要地描述了Ignite函数概述和具有不同拓扑结构的各种缓存策略。我们还介绍了一些基于标准数据访问模式的技术,如缓存、通读和写入。我们介绍了Ignite数据配置技术,并简要介绍了Ignite键值数据存储。