2.3. 集群缓存模式
您可以将集群数据网格缓存配置为复制或分布式。
- 分布式缓存
- 通过在集群中创建每个条目的副本来最大化容量。
- 复制的缓存
- 通过在集群中的每个节点上创建所有条目的副本来提供冗余。
Read:Writes
考虑您的应用程序执行更多写入操作或更多读操作。通常,分布式缓存为写入提供最佳性能,而复制缓存则提供最佳读取性能。
要将 k1 放置到具有三个所有者的三个节点的分布式缓存中,Data Grid 写入 k1 两次。复制缓存中的相同操作意味着数据网格写入 k1 三次。每个写入复制缓存的额外网络流量量等于集群中的节点数量。在十个节点的集群上,复制缓存会导致流量增加,以便进行写入等。您可以使用带有多播的 UDP 堆栈来最小化流量。
要从复制缓存中获取 k1,每个节点都可以在本地执行读取操作。从分布式缓存中获取 k1,处理操作的节点可能需要从集群中的不同节点检索密钥,这会导致额外的网络跃点,并增加读取操作的时间。
客户端智能和近缓存
Data Grid 使用一致的哈希技术使 Hot Rod 客户端拓扑感知,并避免额外的网络跃点,这意味着读取操作的性能与复制缓存的性能相同。
热 Rod 客户端也可以使用接近缓存功能来在本地内存中保持频繁访问的条目,并避免重复读取。
分布式缓存是大多数数据网格服务器部署的最佳选择。您可以获得读写操作的最佳可能性能,以及集群缩放的弹性。
数据保障
由于每个节点包含所有条目,因此复制缓存可提供比分布式缓存更多的数据丢失保护。在三个节点的集群上,两个节点可能会崩溃,且不会丢失复制缓存中的数据。
在相同的场景中,具有两个所有者的分布式缓存将会丢失数据。为了避免使用分布式缓存的数据丢失,您可以通过以声明性方式为每个条目配置更多所有者或 numOwners () 方法来增加集群中的副本数量。
当节点故障发生时重新平衡操作
节点失败后重新平衡操作可能会影响性能和容量。当节点离开集群时,Data Grid 会在剩余的成员之间复制缓存条目,以恢复配置的所有者数。这个重新平衡操作是临时的,但增加的集群流量会对性能造成负面影响。性能降级越大,节点越多。当节点保留太多时,剩余的节点可能没有足够的容量来在内存中保留所有数据。
集群扩展
Data Grid 集群根据工作负载需求水平扩展,以便更有效地使用 CPU 和内存等计算资源。为了充分利用这种弹性,您应该考虑如何扩展或缩减节点对缓存容量的影响。
对于复制缓存,每次节点加入集群时,它都会获得数据集的完整副本。将所有条目复制到每个节点会增加节点加入并限制总容量所需的时间。复制缓存永远不会超过主机可用的内存量。例如,如果您的数据集的大小为 10 GB,则每个节点必须至少有 10 GB 可用内存。
对于分布式缓存,添加更多节点会增加容量,因为集群的每个成员仅存储了数据的子集。要存储 10 GB 数据,如果所有者数为 2,则每个节点有 8 GB 的可用内存,而无需考虑内存开销。加入集群的每个额外节点都会将分布式缓存的容量增加 5 GB。
分布式缓存的容量不受底层主机可用的内存量的限制。
同步或异步复制
当主所有者向备份节点发送复制请求时,数据网格可以同步或异步通信。
| 复制模式 | 对性能的影响 |
|---|---|
| 同步 | 同步复制有助于保持数据一致性,但给集群流量添加降低缓存写入吞吐量的延迟。 |
| asynchronous | 异步复制可减少延迟并增加写操作的速度,但会导致数据不一致,并降低对数据丢失的保证。 |
通过同步复制,数据网格会在备份节点上复制请求时通知原始节点。如果复制请求因为集群拓扑更改而失败,则数据网格会重试操作。当复制请求因为其他错误而失败时,Data Grid 会抛出客户端应用程序异常。
借助异步复制,Data Grid 不会为复制请求提供任何确认。这对应用程序的影响与所有请求都成功相同。但是,在 Data Grid 集群中,主所有者具有正确的条目,Data Grid 会将其复制到备份节点。如果主所有者崩溃,则备份节点可能没有条目的副本,或者可能没有日期副本。
集群拓扑更改也可以导致数据与异步复制不一致。例如,假设一个有多个主要所有者的 Data Grid 集群。由于网络错误或某些其他问题,一个或多个主要所有者会意外地使集群意外出现,因此 Data Grid 更新哪些节点是哪些部分的主要所有者。当发生这种情况时,有些节点理论上可以使用旧的集群拓扑,一些节点使用更新的拓扑。通过异步通信,这可能会导致一个较短的时间,其中 Data Grid 处理从以前的拓扑复制请求,并应用来自写入操作的旧值。但是,Data Grid 可以检测节点崩溃和更新集群拓扑更改,因为这种情况可能不会影响很多写入操作。
使用异步复制不能保证提高写入吞吐量,因为异步复制限制节点可在任何时间处理的备份写入数量(通过 JGroups per-sender 排序)。同步复制允许节点同时处理更多传入的写入操作,某些配置中可能会满足单个操作完成的时间,从而为您提供更高的吞吐量。
当节点发送多个请求以复制条目时,JGroups 会一次将消息发送到集群中其他节点的其余部分,这会导致每个原始节点只有一个复制请求。这意味着,Data Grid 节点可以与其他写入操作并行处理,从而从集群中的其他节点一个写入。
Data Grid 使用集群传输层中的 JGroups 流控制协议来处理对备份节点的复制请求。如果未确认的复制请求数量超过流控制阈值,使用 max_credits 属性设置(默认为 4MB),则对原始器节点上的写入操作会被阻断。这适用于同步和异步复制。
片段数
Data Grid 将数据划分为不同的片段,以便在集群间平均分配数据。即使片段分布也避免了过度加载单个节点,并使集群重新平衡操作更高效。
默认情况下,Data Grid 会为每个集群创建 256 个哈希空间片段。对于每个集群具有最多 20 个节点的部署,这个片段是理想的情况,不应更改。
对于每个集群具有超过 20 个节点的部署,增加片段的数量会增加数据的粒度,以便 Data Grid 可以更有效地在集群中分发数据。使用以下公式计算您应该配置的片段数:
Number of segments = 20 * Number of nodes
Number of segments = 20 * Number of nodes
例如,如果集群为 30 个节点,您应该配置 600 个片段。但是,为大型集群添加更多片段通常是一个不错的想法,但这个公式应该可让您了解适合您的部署的数量。
更改 Data Grid 创建片段的数量需要完全重启集群。如果您使用持久性存储,您可能还需要使用 StoreMigrator 工具更改片段数量,具体取决于缓存存储实施。
更改片段数量也可以导致数据损坏,因此您应该谨慎,并基于从基准测试和性能监控收集的指标。
Data Grid 始终将数据存储在内存中的数据。当您配置缓存存储时,Data Grid 并不总是将数据段到持久性存储中。
它依赖于缓存存储实现,但尽可能多地为缓存存储启用分段。在持久性存储中迭代数据时,分段缓存存储提高了数据性能。例如,通过基于 RocksDB 和 JDBC 字符串的缓存存储,分段可减少 Data Grid 从数据库检索的对象数量。