2.3. 缓存 API
数据网格提供了一个 缓存 接口,用于公开添加、检索和删除条目的简单方法,包括 JDK 的 ConcurrentMap 接口公开的 atomic 机制。根据所用的缓存模式,调用这些方法将触发一些问题,甚至可能包括将条目复制到远程节点或在远程节点中查找条目,或可能缓存存储。
对于简单用法,使用 Cache API 不应与使用 JDK Map API 的不同,因此从基于 map 到数据网格缓存的简单内存缓存迁移都应该无关紧要。
Certain Map Methods 的性能调优
当与 Data Grid 搭配使用时,某些在映射中公开的方法具有某些性能后果,如 size ()、value ()、keySet () 和 entrySet ()。有关 keySet、值 和 entrySet 的具体方法,请参见其 Javadoc 以了解更多详情。
在全球范围内尝试执行这些操作会对性能有大的影响,并成为可扩展性瓶颈。因此,这些方法应该只用于信息或调试目的。
请注意,在 withFlags () 方法中使用某些标记可以缓解这些问题,请检查每种方法的文档以了解更多详细信息。
Mortal 和 Immortal 数据
除了仅存储条目,Data Grid 的缓存 API 可让您将分散信息附加到数据。例如,只需使用 put (key, value) 即可创建一个 非 仲裁条目,即:位于缓存中有的条目(位于缓存中时),直到它被删除(或被驱除内存以防止内存不足)。但是,如果使用 put (key, value, Lifespan, timeunit) 将数据放置在缓存中,这将创建一个 mortal 条目(例如,在那个 lifespan后具有固定寿命和过期的条目)。
除了 lifespan 外,数据网格还支持 maxIdle 作为附加指标,以确定过期时间。可以使用 lifespans 或 maxIdles 的任意组合。
putForExternalRead operation
Data Grid's Cache 类包含一个名为 putForExternalRead 的不同 'put' 操作。当将 Data Grid 用作保留在其他位置的数据临时缓存时,此操作特别有用。在大量读取方案下,缓存中的竞争不应延迟实时事务,因为缓存应只是采用优化方式,而不是采用这种方式。
要达到此目的,putForExternalRead () 充当一个只能在缓存中不存在键的放置调用,并且如果另一个线程尝试同时存储同一密钥,则会失败并静默失败。在这种特定场景中,缓存数据是优化系统的一种方法,因此,缓存中的故障不会影响到持续事务中的故障,因此故障是处理失败的原因。putForExternalRead () 被视为一个快速操作,因为无论是否成功完成,也不会等待任何锁定,因此无法及时返回调用者。
要了解如何使用此操作,让我们来看一下基本的示例。想象一下 Person 实例的缓存,每个由 PersonId 进行键,其数据源自于单独的数据存储。以下代码显示了在此示例中使用 putForExternalRead 的最常见模式:
请注意,putForExternalRead 不应用作使用新 Person 实例(从修改 Person 地址)更新缓存的机制。更新缓存的值时,请使用标准 放置 操作,否则可能会缓存损坏数据。
2.3.1. AdvancedCache API 复制链接链接已复制到粘贴板!
除简单的缓存界面外,Data Grid 还提供了 高级缓存 接口,面向扩展作者。AdvancedCache 提供了访问某些内部组件的功能,也可应用标志来更改某些缓存方法的默认行为。以下代码片段描述了如何获取 AdvancedCache:
AdvancedCache advancedCache = cache.getAdvancedCache();
AdvancedCache advancedCache = cache.getAdvancedCache();
2.3.1.1. 标记 复制链接链接已复制到粘贴板!
标志应用于常规缓存方法,以改变某些方法的行为。有关所有可用标志及其影响的列表,请查看 标记 枚举。使用 AdvancedCache.withFlags () 应用标志。这个构建器方法可用于将任意数量的标志应用到缓存调用,例如:
advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING)
.withFlags(Flag.FORCE_SYNCHRONOUS)
.put("hello", "world");
advancedCache.withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_LOCKING)
.withFlags(Flag.FORCE_SYNCHRONOUS)
.put("hello", "world");
2.3.2. 异步 API 复制链接链接已复制到粘贴板!
除了 Cache.put ()、 Cache.remove () 等同步 API 方法之外,数据网格还具有异步非阻塞 API,您可以实现同样的结果。
这些方法以类似的方式命名,其块程序带有 "Async" 附加。 E.g., Cache.putAsync() , Cache.removeAsync() , etc. 这些异步对应一个包含操作实际结果的 CompletableFuture 会返回一个 CompletableFuture。
例如,在 cache 参数ized as Cache<String, String>, Cache.put (String value, String value) returns String while Cache.putAsync (String key, String value) 返回 Complet ableFutureString<String>。
2.3.2.1. 为什么要使用这样的 API? 复制链接链接已复制到粘贴板!
非阻塞 API 功能强大,它们能提供同步通信的所有保证 - 能够处理通信失败和异常 - 在调用完成前,无需阻止任何操作。 这可让您更好地使用系统中的并行性。 例如:
2.3.2.2. 哪些进程实际发生异步发生? 复制链接链接已复制到粘贴板!
数据网格有 4 个事情,可视为典型的写入操作的关键路径。即,按成本顺序排列:
- 网络调用
- marshalling
- 写入缓存存储(可选)
- 锁定
使用 async 方法将获取网络调用并汇总关键路径。 由于各种技术的原因,写入缓存存储和获取锁,但仍发生在调用者的线程中。