Reputation: 21
I am a beginner in Apache Ignite. Lately, I'm trying to figure out how AffinityKey works and I encountered some problems. Here are my classes which you can get from 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;
}
}
In Person class, it seems that I collocate Person with Organization and they should be put together in the same node.However, it might be wrong.Here is some of my example.
// 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");
At the beginning,I started a node, and it showed:
local size PERSON with aff : 12
local size ORG with aff : 5
local size add with aff : 6
Then, I started another node, and it showed:
local size PERSON with aff : 9
local size ORG with aff : 5
local size add with aff : 5
The result shows that person6-person8 have been collocated with the pair——(5,"5") which I logically don't want to.
I think AffinityKey works like that: It searches all the caches to find out a pair with the same key as the AffinityKey.key() and collocate them together.
For example: I want to collocate A with B. and I write the code
AffinityKey<Integer> key=new AffinityKey<>(A.id,B.id);
But C has the same id with B which doesn't have any relationship with B at all;
If there happens to be cache B that
IgniteCache<Integer,B>
and cache C that
IgniteCache<Integer,C>
Then I don't know which one is going to be collocated with A.
In a word, what should I do exactly to avoid this problem? And how AffinityKey works on earth?I'm so confused.
Upvotes: 1
Views: 1078
Reputation: 421
Mapping a key to a node are working by the following scenario:
When Affinity Key used, Ignite doesn't search in all caches. Just instead of key into affinity function will pass affinity key (in your case instead of person id, organization id will be passed). In this case all persons from one organization will be mapped on the same partition that and organization. If partition the same hence node will be the same too.
In your case all caches have the same affinity function (I guess that it's RendezvousAffinityFunction with default settings), keys have the same type (long) and hence entries from addCache and personCache (affinity key is used for affinity function i.e. organization id) caches with the same keys were mapped on the same nodes. You can remove affinity key and see that organization and person with the same key (for example 1L) will be mapped on the same partition and hence node.
More details about it you can find there https://apacheignite.readme.io/docs/affinity-collocation
Upvotes: 1