2.3. Cache API
Data Grid 提供了一个 Cache 接口,它公开简单的方法来添加、检索和删除条目,包括 JDK 的 ConcurrentMap 接口公开的原子机制。根据所使用的缓存模式,调用这些方法会触发多个事情,甚至可能包括将条目复制到远程节点或从远程节点查找条目,或可能缓存存储。
对于简单使用,使用 Cache API 不应与使用 JDK Map API 不同,因此从基于映射到 Data Grid 的缓存的简单内存缓存迁移应该很简单。
Certain Map 方法的性能一致性
与 Data Grid 一起使用时,在 Map 中公开的某些方法具有一定的性能后果,如 size ()、value ()、keySet () 和 entrySet ()。有关 keySet
、value 和 entrySet
的具体方法,请参阅其 Javadoc 了解更多详情。
试图全局执行这些操作会对性能有很大的影响,并成为可扩展性瓶颈。因此,这些方法应该仅用于信息或调试目的。
应注意,在 withFlags () 方法中使用某些标记可以缓解其中的一些问题,请检查每个方法的文档以了解更多详情。
Mortal 和 Immortal Data
除了仅存储条目外,Data Grid 的缓存 API 允许您向数据附加 mortality 信息。例如,只是使用 put (键,值) 会创建一个 immortal 条目,例如,一个存在于缓存中的条目(永久存在),直到它被删除(或逐出内存以防止耗尽内存)。但是,如果您使用 put (key, value, lifespan, timeunit) 将数据放入缓存中,这会创建一个 mortal 条目,即具有固定生命周期的条目,并在该生命周期后过期。
除了 Lifespan 外,Data Grid 还支持 maxIdle 作为额外的指标,以决定到期。可以使用任何 lifespans 或 maxIdles 的组合。
putForExternalRead
操作
Data Grid 的 Cache 类包含不同的"put"操作,称为 putForExternalRead。当 Data Grid 用作在其他位置保留数据的临时缓存时,此操作特别有用。在大量读取场景中,缓存中的竞争不应延迟实时事务,因为缓存应该只是优化,而不是以某种方式获得。
要达到此目的,putForExternalRead ()
充当 put 调用,只有在缓存中不存在密钥时才运行,并在另一个线程尝试同时存储同一密钥时失败。在这个特殊情况下,缓存数据是优化系统的方法,而不需要缓存失败会影响到持续的事务,因此为什么以不同的方式处理失败。putForExternalRead ()
被视为快速操作,因为无论它是否成功,它都不会等待任何锁定,因此会立即返回到调用者。
要了解如何使用此操作,让我们来看基本的示例。试想一下,个人实例的缓存,每个由 PersonId 的密钥,其数据源自于单独的数据存储中。以下代码显示了在此示例上下文中使用 putForExternalRead 的最常见模式:
请注意,putForExternalRead 不应用作使用源自应用程序执行的新 Person 实例更新缓存的机制(例如,来自修改人员地址的事务)。更新缓存的值时,请使用标准 放置 操作,否则可能会出现缓存损坏数据的可能性。
2.3.1. AdvancedCache API 复制链接链接已复制到粘贴板!
除了简单缓存接口外,Data Grid 还提供 AdvancedCache 接口,并提供给扩展作者。AdvancedCache 提供了访问某些内部组件,并应用标志来改变某些缓存方法的默认行为。以下代码片段描述了如何获取 AdvancedCache:
AdvancedCache advancedCache = cache.getAdvancedCache();
AdvancedCache advancedCache = cache.getAdvancedCache();
2.3.1.1. 标记 复制链接链接已复制到粘贴板!
标志应用到常规缓存方法,以更改某些方法的行为。有关所有可用标志及其效果的列表,请查看 标记 枚举。使用 AdvancedCache.withFlags () 应用标志。此 builder 方法可用于将任意数量的标记应用到缓存调用,例如:
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. Asynchronous API 复制链接链接已复制到粘贴板!
除了同步的 API 方法(如 Cache.put ()、Cache.remove () 等)之外,数据网格也有一个异步的非阻塞 API,您可以在其中实现相同的结果。
这些方法的命名方式与阻塞计数器类似,并附加"Async"。 例如,Cache.putAsync ()、Cache.removeAsync () 等。 这些异步对应部分返回一个包含操作实际结果的 CompletableFuture。
例如,在 cache 参数中,在 Cache<String, String>
, Cache.put (String key, String value)
返回 String
while Cache.putAsync (String key) returns Complet
ableFuture<String>
;。
2.3.2.1. 为什么使用这种 API? 复制链接链接已复制到粘贴板!
非阻塞 API 非常强大,它们提供了所有同步通信保证 - 能够处理通信故障和例外 - 在调用完成后不需要阻止。 这可让您更好地利用系统中的并行性。 例如:
2.3.2.2. 哪些进程实际发生在异步中? 复制链接链接已复制到粘贴板!
Data Grid 中有 4 个事情,它们被视为典型写入操作的关键路径。这些是成本顺序:
- 网络调用
- Marshalling
- 写入缓存存储(可选)
- 锁定
使用 async 方法将取网络调用和划分出关键路径。 然而,出于各种技术原因,写入缓存存储和获取锁定,但仍然出现在调用者的线程中。