我认为您的一般问题非常广泛,并且不只有一种推荐的方法可以涵盖所有 UC(主要是您的应用程序所需的所有数据分析视图/模型)。
此类问题涉及许多因素,例如单个数据元素的大小、数据量、访问频率或源自一个或多个应用程序的访问模式、信息的及时传递、数据需要的准确程度、大小你的集群,每台(虚拟)机器的物理资源,等等。因此,任何给定的方法无疑都需要应用程序调优,相应地调优 GemFire 和 JVM 调优,而不管您的数据模型如何。不过,精心设计的数据模型可以确定这种调整的程度。
具体而言,在 GemFire 中,此类调整将涉及不同的配置,例如但不限于:数据管理策略、驱逐(溢出)和过期(LRU,或者可能是自定义)设置以及不同的驱逐/过期阈值,可能将数据存储在Off-堆内存,采用不同的分区策略(PartitionResolver)等等。
例如,如果您的 Address 信息是相对静态的、不变的(即实际的“参考”数据),那么您可以考虑将 Address 数据存储在REPLICATE
Region中。频繁写入的数据(通常是“事务性”数据)最好放在PARTITION
Region中。
当然,如您所知,您在查询(使用 OQL)中“加入”的任何PARTITION
数据(在单独的Regions中管理)都必须并置。GemFire/Geode 目前不支持分布式连接。
此外,某些节点可以托管某些Regions,从而将您的集群划分为“事务”节点和“分析”节点,其中基于分析的节点是从事务节点中CacheListeners
的Regions更新的(注意这一点),或者可能更好,异步使用带有 AsyncEventListeners 的 AEQ。AEQ 也可以单独制成高可用性和耐用性。这种事务性与分析性的方法是CQRS的基础。
数据的大小还受其存储形式的影响,即序列化与非序列化,与 Java 序列化相比,GemFire 的专有序列化格式 (PDX) 非常理想。这完全取决于您的数据需要多么“可移植”,以及您是否可以将数据保存为序列化形式。
此外,您可能会考虑即时加入数据的成本。这意味着,如果您能够在运行时相对便宜地聚合、转换和丰富数据(计算与内存/存储),那么您可能会考虑使用 GemFire 的函数执行服务,将您的逻辑带到数据而不是数据到您的逻辑(MapReduce的基础)。
你应该知道,我相信你也知道,GemFire 是一个键值对存储,因此将一个复杂的对象图映射到单独的区域不是一个简单的问题。按引用划分对象(尤其是多对多)并准确知道何时急切加载和延迟加载它们是一个重载问题,尤其是在存在一致性和可用性权衡的分布式复制数据存储(如 GemFire)中。
有不同的 API 和框架来简化使用 GemFire 的持久性和查询。更值得注意的方法之一是Spring Data GemFire 对Spring Data Commons Repository 抽象的扩展。
这也可能是为工作使用正确的数据模型的问题。如果您有非常复杂的数据关系,那么使用图形数据库(例如 Neo4j)创建分析模型可能是一个更简单的选择。 Spring还为由 Neo4j 团队领导的 Neo4j提供了强大的支持。
毫无疑问,您所做的任何设计选择都将涉及混合方法。通常路径不清楚,因为它真的“依赖”(即依赖于应用程序和数据访问模式、负载等等)。
但有一点是肯定的,请确保您对底层数据存储及其数据管理功能有很好的粗略了解和理解,尤其是与一致性和可用性有关的内容,从这开始。
请注意,如果您在进行此架构设计时遇到更多具体问题,还可以使用GemFire 松弛频道和Apache DEV 邮件列表联系GemFire 专家和(高级)GemFire/Geode 用户社区小路。