第 10 章 配置锁定和并发


Data Grid 使用多版本的并发控制(MVCC)来改进对共享数据的访问。

  • 允许并发读取器和写入器
  • 读取器和写入者不会阻断另一个内容
  • 可以检测到并处理写 skews
  • 内部锁定可以是条带的

10.1. 锁定和并发

多版本的并发控制(MVCC)是一个与关系数据库和其他数据存储流行的并发方案。MVCC 与粗粒度 Java 同步(甚至 JDK Locks)提供了许多优点,以访问共享数据。

Data Grid 的 MVCC 实现利用最小的锁和同步,更倾向于采用无锁定技术,如 比较 和交换以及无锁定数据结构,这有助于针对多 CPU 和多核环境进行优化。

特别是,Data Grid 的 MVCC 实现会对读者进行大量优化。读取器线程不会获取条目的显式锁定,而是直接读取问题中的条目。

另一方面,作者需要获取写锁。这样可确保每个条目只有一个并发写入器,从而导致并发写入器在线更改条目。

要允许并发读取,写器通过嵌套 MVCCEntry 中的条目来制作他们要修改的条目的副本。此副本隔离并发读取器来查看部分修改的状态。写入完成后,MVCCEntry.commit () 将清空对数据容器的更改,后续的读取器将看到写入的更改。

10.1.1. 集群缓存和锁定

在 Data Grid 集群中,主所有者节点负责锁定密钥。

对于非事务缓存,Data Grid 将写操作转发到密钥的主所有者,以便它能够锁定它。然后,Data Grid 将写入操作转发到其他所有者,或者在无法锁定密钥时抛出异常。

注意

如果操作为条件并在主所有者上失败,则 Data Grid 不会将它转发到其他所有者。

对于事务缓存,主所有者可以使用最佳锁定模式锁定密钥。Data Grid 还支持不同的隔离级别,以控制事务之间的并发读取。

10.1.2. LockManager

LockManager 是一个组件,它负责锁定写条目。LockManager 使用 LockContainer 找到/hold/create 锁定。LockContainers 有两个广泛的 flavours,它支持锁定条带,并支持每个条目一个锁定。

10.1.3. 锁定条带

锁定条带要求使用固定大小、整个缓存的锁定共享集合,锁定会根据条目的哈希代码分配给条目。与 JDK 的 ConcurrentHashMap 分配锁定的方式类似,这允许在交换过程中具有高度可扩展的固定位锁定机制,以便同一锁定阻止了与相关的条目。

另一种方法是禁用锁定条带 - 这意味着 每个条目创建一个新的 锁定。这种方法 可能会 为您提供更高的并发吞吐量,但它将是额外的内存用量、垃圾收集时间等。

默认锁定条带设置

默认情况下禁用锁定条带,因为当不同键锁定在同一锁定条带中时可能会出现潜在的死锁。

可以使用 < locking /> 配置元素的 concurrencyLevel 属性调整锁定条带使用的共享锁定集合的大小。

配置示例:

<locking striping="false|true"/>
Copy to Clipboard Toggle word wrap

或者

new ConfigurationBuilder().locking().useLockStriping(false|true);
Copy to Clipboard Toggle word wrap

10.1.4. 并发级别

除了确定条带锁定容器的大小外,这个并发级别还用于调整任何基于 JDK ConcurrentHashMap 的集合。有关并发级别的详细讨论,请参阅 JDK ConcurrentHashMap Javadocs,因为此参数在 Data Grid 中完全相同。

配置示例:

<locking concurrency-level="32"/>
Copy to Clipboard Toggle word wrap

或者

new ConfigurationBuilder().locking().concurrencyLevel(32);
Copy to Clipboard Toggle word wrap

10.1.5. 锁定超时

锁定超时指定等待内容锁定的时间长度(以毫秒为单位)。

配置示例:

<locking acquire-timeout="10000"/>
Copy to Clipboard Toggle word wrap

或者

new ConfigurationBuilder().locking().lockAcquisitionTimeout(10000);
//alternatively
new ConfigurationBuilder().locking().lockAcquisitionTimeout(10, TimeUnit.SECONDS);
Copy to Clipboard Toggle word wrap

10.1.6. 一致性

单个所有者被锁定(而不是所有所有者被锁定)不会破坏以下一致性保证:如果密钥 K 对节点 {A、B} 和事务 TX1 进行哈希处理时,让我们在 A 上取得一个锁定。如果另一个事务 TX2B (或任何其他节点)上启动,TX2 会尝试锁定 K,然后其将失败,因为锁定已持有 TX1。这样做的原因是,无论事务源自的位置,K 的锁始终、确定地获取到集群的同一节点上。

10.1.7. 数据版本控制

Data Grid 支持两种形式的数据版本: simple 和 external。简单的版本控制用于写入偏移检查。

外部版本控制用于在 Data Grid 内封装一个外部的数据源,例如将 Data Grid 与 Hibernate 搭配使用时,后者又直接从数据库获取其数据版本信息。

在这个方案中,传递版本的机制变得有必要,而 put ()putForExternalRead () 的超载版本将在 AdvancedCache 中提供,采用外部数据版本。然后,这存储在 InvocationContext 中,并在提交时应用到条目。

注意

无法编写 skew 检查,在外部数据版本控制时不会执行。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat