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