7.2. 缓存可用性和降级模式
为保持数据一致性,数据网格可将缓存置于 DEGRADED
模式(如果使用 DENY_READ_WRITES
或 ALLOW_READS
分区处理策略)。
当以下条件满足以下条件时,Data Grid 会将缓存置于 DEGRADED
模式中:
-
至少一个片段丢失了所有所有者。
当多个节点等于或大于分布式缓存的所有者数量时,会出现这种情况。 -
分区中没有大多数节点。
大多数节点都是集群中最新稳定拓扑中节点总数的一半以上,这是集群重新平衡操作成功完成的时间。
当缓存处于 DEGRADED
模式时,Data Grid:
- 只有在条目的所有副本都驻留在同一分区中时,才允许读写操作。
如果分区不包含条目的所有副本,则拒绝读取和写入操作并引发
AvailabilityException
。注意借助
ALLOW_READS
策略,Data Grid 在DEGRADED
模式中的缓存允许读取操作。
DEGRADED
模式通过确保在不同分区中不会为同一密钥执行写入操作来确保一致性。另外,DEGRADED 模式还可防止在一个分区中更新密钥而出现过时的读取操作,但要在另一个分区中读取。
如果所有分区都处于 DEGRADED
模式,则只有在集群包含最新 stable 拓扑中的大多数节点并且每个条目至少有一个副本时,缓存才会再次可用。当集群至少有一个条目的副本时,没有丢失密钥,Data Grid 可以根据集群重新平衡期间的所有者数量创建新副本。
在某些情况下,一个分区中的缓存可在在另一个分区中输入 DEGRADED
模式时仍然可用。当可用分区发生时,通常会仍然缓存操作,而数据网格会尝试在这些节点上重新平衡数据。要将缓存合并到 Data Grid 时,始终从可用分区转移到 DEGRADED
模式中的分区。
7.2.1. 降级缓存恢复示例
本主题演示了数据网格如何使用 DENY_READ_WRITES
分区处理策略缓存从分割集群中恢复。
例如,Data Grid 集群有 4 个节点,包括每个条目有两个副本的分布式缓存(owners=2
)。缓存、k1、
和 k2
、k
3k4
中有四个条目。
使用 DENY_READ_WRITES
策略时,如果集群分割为分区,则数据网格只有在所有条目的副本都位于同一分区时才允许缓存操作。
在下图中,缓存被分成分区,而数据网格允许在分区 1 和 k4
上对 k1
进行读写操作。因为 1 分区 1 或分区 2 中只有一个 k2
和 k3
的副本,所以数据网格会拒绝对这些条目的读写操作。
当网络条件允许节点重新加入同一集群视图时,Data Grid 会在没有状态传输的情况下合并分区,并恢复正常的缓存操作。
7.2.2. 在网络分区中验证缓存可用性
确定数据网格集群上的缓存是否在网络分区期间处于 AVAILABLE
模式或 DEGRADED
模式。
当 Data Grid 集群分割为分区时,这些分区中的节点可以进入 DEGRADED
模式来保证数据一致性。在 DEGRADED
模式中,集群不允许缓存操作,从而导致可用性丢失。
流程
通过以下方法之一验证网络分区中的集群缓存的可用性:
-
检查 Data Grid 日志的
ISPN100011
消息,该消息指示集群是否可用,或者至少一个缓存处于DEGRADED
模式。 通过 Data Grid Console 或 REST API 获取远程缓存的可用性。
- 在任意浏览器中打开 Data Grid Console,选择 Data Container 选项卡,然后在 Health 列中找到可用性状态。
从 REST API 检索缓存健康状况。
GET /rest/v2/cache-managers/<cacheManagerName>/health
-
以编程方式使用 advanced
Cache
API 中的getAvailability ()
方法检索嵌入式缓存的可用性。
7.2.3. 使缓存可用
通过强制使用 DEGRADED
模式,使缓存可用于读取和写入操作。
只有在部署可以容忍数据丢失和不一致时,您应该强制使用 DEGRADED
模式的集群。
流程
使用以下方法之一提供缓存:
使用 REST API 更改远程缓存的可用性。
POST /v2/caches/<cacheName>?action=set-availability&availability=AVAILABLE
以编程方式使用
AdvancedCache
API 更改嵌入式缓存的可用性。AdvancedCache ac = cache.getAdvancedCache(); // Retrieve cache availability boolean available = ac.getAvailability() == AvailabilityMode.AVAILABLE; // Make the cache available if (!available) { ac.setAvailability(AvailabilityMode.AVAILABLE); }