Ignite 不同亲和键缓存间的搭配
Ignite collocation between caches with different affinity keys
假设我在单独的 Ignite 缓存中有两个 table,A
和 B
具有各自的键:
case class AKey(
@(QuerySqlField@field) id: Long,
@(AffinityKeyMapped@field)
@(QuerySqlField@field) parentId: Long
)
case class BKey(
@(AffinityKeyMapped@field)
@(QuerySqlField@field) aId: Long
)
其中 A.parentId
是对 table A
中另一个条目的自我引用,B.aId
是对 A.id
的引用。
如果我希望将具有相同 parentId
的所有 A
条目并置,但我还希望将所有 B
条目与 parentId
并置引用了 A
条目,如果不在 B
中包含 parentId
字段,我将如何设置这种关联关系?或者这是不可能的?
我不清楚 Ignite 的文档是如何在 table 之间建立亲和关系的。
Ignite 如何管理关联搭配
Ignite 并没有真正建立任何 "affinity relationship"。它所做的只是将缓存键映射到关联键。所有缓存中具有相同关联键的所有条目都保证并置。
例如使用以下键获取缓存
class KeyA { int a1; int a2; @AffinityKeyMapped int affKey; }
class KeyB { int b1; int b2; @AffinityKeyMapped int affKey; }
这里我们说 KeyA
和 KeyB
通过 affKey
并置 - 当 affKey
的值匹配时,条目将被并置。但实际上 Ignite 并不知道 KeyA
和 KeyB
之间的联系,它单独处理表。只有保证关联键到节点的映射是一致的才能使这项工作有效。换句话说,这些缓存之间的关系只存在于我们的头脑中,我们有责任确保搭配正确。
解决方案
最后,关于你的情况。这可能令人惊讶,但 parentId 并不是亲和键的理想候选者。假设我们在 A
中有三个值
{ id: 1, parentId: 0 }
{ id: 2, parentId: 1 }
{ id: 3, parentId: 2 }
这里可以预期所有值都被并置,因为所有值都在同一个 "chain" 中相互引用。但这是 Ignite 不知道的关系。它所知道的是存在三个不同的 parentId
值 - 因此,三个不同的关联键并且没有搭配。
要正确处理此问题,必须提供一些 groupdId
保证在所有值中都相同。 "tree" 中根元素的 ID 自然适合您的情况。然后 groupdId
将是 @AffinityKeyMapped
.
{ id: 1, parentId: 0, groupId: 1 }
{ id: 2, parentId: 1, groupId: 1 }
{ id: 3, parentId: 2, groupId: 1 }
不幸的是,第二个缓存必须引用亲和键的完全相同的值,如果不将其添加为字段就无法做到这一点。
{ aId: 2, aGroupId: 1 }
此外,尽管它与问题没有直接关系,但请确保 @AffinityKeyMapped
是缓存 key 的一部分,而不是值的一部分 -否则,它将被忽略。
假设我在单独的 Ignite 缓存中有两个 table,A
和 B
具有各自的键:
case class AKey(
@(QuerySqlField@field) id: Long,
@(AffinityKeyMapped@field)
@(QuerySqlField@field) parentId: Long
)
case class BKey(
@(AffinityKeyMapped@field)
@(QuerySqlField@field) aId: Long
)
其中 A.parentId
是对 table A
中另一个条目的自我引用,B.aId
是对 A.id
的引用。
如果我希望将具有相同 parentId
的所有 A
条目并置,但我还希望将所有 B
条目与 parentId
并置引用了 A
条目,如果不在 B
中包含 parentId
字段,我将如何设置这种关联关系?或者这是不可能的?
我不清楚 Ignite 的文档是如何在 table 之间建立亲和关系的。
Ignite 如何管理关联搭配
Ignite 并没有真正建立任何 "affinity relationship"。它所做的只是将缓存键映射到关联键。所有缓存中具有相同关联键的所有条目都保证并置。
例如使用以下键获取缓存
class KeyA { int a1; int a2; @AffinityKeyMapped int affKey; }
class KeyB { int b1; int b2; @AffinityKeyMapped int affKey; }
这里我们说 KeyA
和 KeyB
通过 affKey
并置 - 当 affKey
的值匹配时,条目将被并置。但实际上 Ignite 并不知道 KeyA
和 KeyB
之间的联系,它单独处理表。只有保证关联键到节点的映射是一致的才能使这项工作有效。换句话说,这些缓存之间的关系只存在于我们的头脑中,我们有责任确保搭配正确。
解决方案
最后,关于你的情况。这可能令人惊讶,但 parentId 并不是亲和键的理想候选者。假设我们在 A
中有三个值{ id: 1, parentId: 0 }
{ id: 2, parentId: 1 }
{ id: 3, parentId: 2 }
这里可以预期所有值都被并置,因为所有值都在同一个 "chain" 中相互引用。但这是 Ignite 不知道的关系。它所知道的是存在三个不同的 parentId
值 - 因此,三个不同的关联键并且没有搭配。
要正确处理此问题,必须提供一些 groupdId
保证在所有值中都相同。 "tree" 中根元素的 ID 自然适合您的情况。然后 groupdId
将是 @AffinityKeyMapped
.
{ id: 1, parentId: 0, groupId: 1 }
{ id: 2, parentId: 1, groupId: 1 }
{ id: 3, parentId: 2, groupId: 1 }
不幸的是,第二个缓存必须引用亲和键的完全相同的值,如果不将其添加为字段就无法做到这一点。
{ aId: 2, aGroupId: 1 }
此外,尽管它与问题没有直接关系,但请确保 @AffinityKeyMapped
是缓存 key 的一部分,而不是值的一部分 -否则,它将被忽略。