7.2. 缓存可用性和降级模式
为了保持数据一致性,如果将缓存配置为使用 DENY_READ_WRITES
或 ALLOW_READS
分区处理策略,则 Data Grid 可以将缓存置于 DEGRADED
模式。
当以下条件满足时,Data Grid 会将缓存置于 DEGRADED
模式:
-
至少一个片段丢失了所有所有者。
当多个节点等于或大于分布式缓存的所有者数量时,会出现这种情况。 -
分区中没有大多数节点。
大多数节点都比集群中节点从最新的稳定拓扑中的一半大于一半,这是集群重新平衡操作成功完成的时间。
当缓存处于 DEGRADED
模式时,Data Grid:
- 只有在条目的所有副本都位于同一分区中时,才允许读取和写入操作。
拒绝读取和写入操作,并在分区不包含条目的所有副本时抛出
AvailabilityException
。注意使用
ALLOW_READS
策略时,Data Grid 允许以DEGRADED
模式对缓存进行读操作。
DEGRADED
模式通过确保在不同的分区中不会对同一密钥进行写入操作保证一致性。另外,DEGRADED
模式可防止在一个分区中更新密钥但在另一个分区中读取时发生的过时的读操作。
如果所有分区都处于 DEGRADED
模式,则缓存仅在集群包含最新稳定拓扑中的大多数节点时再次可用,且每个条目至少有一个副本。当集群至少有一个副本的每个条目时,不会丢失密钥,Data Grid 可以在集群重新平衡过程中根据所有者数量创建新副本。
在某些情况下,在另一个分区中输入 DEGRADED
模式时,一个分区中的缓存可以保持可用。当发生这种情况时,可用分区会正常继续缓存操作,Data Grid 会尝试跨这些节点重新平衡数据。要将缓存合并为 Data Grid,始终将可用分区中的状态转移到 DEGRADED
模式中的分区。
7.2.1. 降级缓存恢复示例
本节介绍 Data Grid 从使用 DENY_READ_WRITES
分区处理策略的缓存从分割集群中恢复。
例如,一个 Data Grid 集群有四个节点,并包括一个分布式缓存,其中包含每个条目的两个副本(owners=2
)。缓存( k1
)、k2
、k2、k3
和 k4
中有四个条目。
使用 DENY_READ_WRITES
策略时,如果集群分割为分区,则当条目的所有副本都位于同一分区中时,Data Grid 才允许缓存操作。
在以下示意图中,当缓存分割为分区时,Data Grid 在分区 1 和分区 2 上允许
的读写操作。由于分区 1 或分区 2 上只有一个 k
1k2
和 k3
副本,因此 Data Grid 拒绝这些条目的读写操作。
当网络条件允许节点重新加入相同的集群视图时,Data Grid 合并了没有状态传输的分区,并恢复普通的缓存操作。
7.2.2. 在网络分区过程中验证缓存可用性
确定在网络分区过程中 Data Grid 集群上的缓存是否处于 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/container/health
-
使用
AdvancedCache
API 中的getAvailability ()
方法,以编程方式检索嵌入式缓存的可用性。
7.2.3. 使缓存可用
通过强制缓存使用 DEGRADED
模式,使缓存可用于读写操作。
只有在部署可以容忍数据丢失和不一致时,才应强制集群处于 DEGRADED
模式。
流程
通过以下方法之一提供缓存:
- 打开 Data Grid Console 并选择 Make available 选项。
使用 REST API 更改远程缓存的可用性。
POST /rest/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); }