内存数据网格中的细粒度与粗粒度域模型

Fine grained vs coarse grained domain model In Memory Data Grid

我想知道哪种方法更好。我们是否应该在网格上使用细粒度实体,然后从细粒度实体构建功能丰富的域对象。

或者我们应该构建课程粒度域对象并将它们直接存储在网格和我们仅用于持久性的实体上。

编辑:我认为这个问题还没有完全回答。到目前为止,我们收到了来自 Hazelcast、Gemfire 和 Ignite 的评论。我们缺少 Infinispan、Coherence ....这是为了完成:)

我相信它可能因数据网格而异。我更熟悉 Apache Ignite,在这种情况下,细粒度方法效果更好,因为它更灵活,在许多情况下提供更好的数据分布,因此可扩展性更好。 Ignite 还提供了丰富的 SQL 功能 [1],允许加入不同的实体并执行索引搜索。这样你就不会失去细粒度模型的性能。

[1] https://apacheignite.readme.io/docs/sql-queries

我同意Valentin,主要看你想用什么系统。通常我会考虑直接存储增强的域对象,无论如何,如果你只有很少的对象但它们的大小很大,你最终会在节点上出现分布不均和内存使用不均的情况。如果您的域对象是 "normally" 大小并且您有很多,则不必担心。

在 Hazelcast 中,最好直接存储这些对象,但要注意使用良好的序列化系统,因为 Java 序列化速度很慢。如果您想查询域对象内的属性,您还应该考虑添加索引。

粗粒度对象的一个​​优点是数据一致性。该对象中的所有内容都以原子方式保存。但是,如果将该对象拆分为 4 个小对象,则 运行 存在 3 个对象保存而 1 个失败(无论出于何种原因)的风险。

我们使用 GemFire,并且倾向于支持粗粒度的对象……在某种程度上。例如,我们的客户对象包含一个地址列表。另一种设计是为 "Customer" 创建一个 GemFire 区域,为 "CustomerAddresses" 创建一个单独的 GemFire 区域,然后希望您可以使这些区域保持同步。

缺点是每次有人更新地址时,我们都会重新编写整个客户对象。这不是很有效,但我们的流量模式显示地址更改非常罕见(与所有其他 activity 相比),因此效果很好。

我们的一个经验是使用 Java 序列化进行长期数据存储的缺点。我们现在避免使用它,因为随着时间的推移,对象兼容性会引起所有问题。更不用说 .NET 客户端读取对象变得头疼了。 :)