java - 关于 Ignite AffinityKey 的严重问题

标签 java memcached ignite

我是 Apache Ignite 的初学者。最近,我试图弄清楚 AffinityKey 是如何工作的,但遇到了一些问题。这是我的类(class),您可以从 Apache Ignite Example 获取:

public class Person implements Serializable {

private static final AtomicLong ID_GEN = new AtomicLong();

public Long id;

public Long orgId;

private transient AffinityKey<Long> key;

    public Person(Long org, String firstName, String lastName, double salary, String resume) {
    // Generate unique ID for this person.
    id = ID_GEN.incrementAndGet();

    orgId = org;

    this.firstName = firstName;
    this.lastName = lastName;
    this.salary = salary;
    this.resume = resume;
}

public Person(Long id, String firstName, String lastName) {
    this.id = id;

    this.firstName = firstName;
    this.lastName = lastName;
}

public AffinityKey<Long> key() {
    if (key == null)
        key = new AffinityKey<>(id, orgId);

    return key;
}

/*Getters and Setters*/
}



public class Organization {

private static final AtomicLong ID_GEN = new AtomicLong();

private Long id;

private String name;

public Organization(long id, String name) {
    this.id = id;
    this.name = name;
}

}

Person类中,似乎我将PersonOrganization并置,它们应该放在同一个节点中。但是,它可能是错误的。这是我的一些例子。

        // People.
        Person p1 = new Person((long)1, "John", "Doe", 2000, "John Doe has Master Degree.");
        Person p2 = new Person((long)2, "Jane", "Doe", 1000, "Jane Doe has Bachelor Degree.");
        Person p3 = new Person((long)2, "John", "Smith", 1000, "John Smith has Bachelor Degree.");


        Person p4 = new Person((long)2, "Jane", "Smith", 2000, "Jane Smith has Master Degree.");
        Person p5 = new Person((long)2, "John", "Harden", 1000, "John Harden has Bachelor Degree.");
        Person p6 = new Person(*(long)5*, "Jane", "Harden", 2000, "Jane Harden has Master Degree.");
        Person p7 = new Person(*(long)5*, "John", "Christopher", 1000, "John Christopher has Bachelor Degree.");
        Person p8 = new Person(*(long)5*, "Jane", "Christopher", 2000, "Jane Christopher has Master Degree.");
        Person p9 = new Person((long)6, "John", "Bush", 1000, "John Bush has Bachelor Degree.");
        Person p10 = new Person((long)3, "Jane", "Bush", 2000, "Jane Bush has Master Degree.");
        Person p11 = new Person((long)3, "John", "Gay", 1000, "John Gay has Bachelor Degree.");
        Person p12 = new Person((long)3, "Jane", "Gay", 2000, "Jane Gay has master Degree.");

        personCache.put(p1.key(), p1);
        personCache.put(p2.key(), p2);
        personCache.put(p3.key(), p3);
        personCache.put(p4.key(), p4);
        personCache.put(p5.key(), p5);
        personCache.put(p6.key(), p6);
        personCache.put(p7.key(), p7);
        personCache.put(p8.key(), p8);
        personCache.put(p9.key(), p9);
        personCache.put(p10.key(), p10);
        personCache.put(p11.key(), p11);
        personCache.put(p12.key(), p12);


        //irrelevant cache to interfere AffinityKey
        IgniteCache<Long,String> addCache=ignite.getOrCreateCache("addCache");
        addCache.put((long)1, "1");
        addCache.put((long)2, "2");
        addCache.put((long)3, "3");
        addCache.put((long)4, "4");
        //this pair has the same value with the orgId of person6-person8
        addCache.put((long)5, "5");
        addCache.put((long)6, "6");

一开始,我启动了一个节点,它显示:

local size PERSON with aff  : 12
local size ORG with aff  : 5
local size add with aff  : 6

然后,我启动了另一个节点,它显示:

local size PERSON with aff  : 9
local size ORG with aff  : 5
local size add with aff  : 5

结果显示 person6-person8 已经与配对——(5,"5")搭配在一起,这在逻辑上是我不希望的。

我认为 AffinityKey 的工作原理是这样的:它搜索所有缓存以找出与 AffinityKey.key() 具有相同 key 的对,并将它们并置在一起。

例如:我想将A与B搭配,然后我编写代码

AffinityKey<Integer> key=new AffinityKey<>(A.id,B.id);

但C与B具有相同的id,与B完全没有任何关系;

如果恰好有缓存B则

IgniteCache<Integer,B>

并缓存 C

IgniteCache<Integer,C>

那我就不知道该和A搭配哪一个了。

总而言之,我应该怎样做才能避免这个问题呢?那么 AffinityKey 究竟是如何工作的?我很困惑。

最佳答案

将 key 映射到节点的工作原理如下:

  • 每个键都将映射到分区上。亲和函数决定 哪个分区将包含一个 key 。
  • 然后通过亲和函数确定每个分区到一个节点。

使用 Affinity Key 时,Ignite 不会在所有缓存中进行搜索。只是不是将 key 传递到亲和性函数中,而是传递亲和性 key (在您的情况下,将传递组织 id,而不是人员 id)。在这种情况下,来自一个组织的所有人员都将映射到该组织的同一分区上。如果分区相同,则节点也将相同。

在您的情况下,所有缓存都具有相同的亲和函数(我猜它是具有默认设置的 RendezvousAffinityFunction),键具有相同的类型(长),因此来自 addCache 和 personCache 的条目(亲和键用于亲和函数,即组织 id )具有相同键的缓存被映射到相同的节点上。您可以删除关联键,并看到具有相同键(例如 1L)的组织和人员将映射到同一分区,从而映射到同一节点。

有关它的更多详细信息,您可以在那里找到 https://apacheignite.readme.io/docs/affinity-collocation

关于java - 关于 Ignite AffinityKey 的严重问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45385313/

相关文章:

java - 将 JLabel 放入 Swing 表中时出现问题

java - 如何用java中的另一个列表项替换一个列表项?

mysql - 如何通过后端通过过滤器获取计数

java - Ignition.ignite 返回 "Grid instance was not properly started or was already stopped"

java - Java 中的 Akka Actor 模型实现

java - java中的for循环和i的值

基于Java的memcached客户端,优化将数据放入memcache

networking - 如何从pcap文件中提取数据

java - 如何解决ignitecheckedException : make sure all objects in cache configuration are serializable

java - 使用 IgniteFuture 进行单元测试