Статьи

Руководство для начинающих по Hazelcast, часть 2

Эта статья продолжает серию, которую я начал с Hazelcast , распределенной базы данных в памяти. Если кто-то не прочитал первый пост, пожалуйста, нажмите здесь .

Распределенные Коллекции

Hazelcast имеет несколько распределенных коллекций, которые можно использовать для хранения данных. Вот их список:

  • IList
  • ISet
  • IQueue

IList

IList — это коллекция, которая хранит порядок вставленных элементов и может иметь дубликаты. Фактически, он реализует интерфейс java.util.List. Это не потокобезопасно, и нужно использовать какой-то мьютекс или блокировку для контроля доступа многими потоками. Я предлагаю ILock Hazelcast.

ISet

ISet — это коллекция, которая не следит за порядком размещенных в ней предметов. Тем не менее, элементы являются уникальными. Эта коллекция реализует интерфейс java.util.Set. Как и ILists, эта коллекция не является поточно-ориентированной. Я предлагаю снова использовать ILock.

IQueue

IQueue — это коллекция, которая хранит порядок поступления и допускает дублирование. Он реализует java.util.concurrent.BlockingQueue, поэтому он безопасен для потоков. Это самая масштабируемая из коллекций, поскольку ее емкость увеличивается с увеличением количества экземпляров. Например, допустим, что для очереди существует ограничение в 10 пунктов. Как только очередь заполнится, больше никто не сможет туда войти, пока не появится другой экземпляр Hazelcast, тогда появятся еще 10 пробелов. Копия очереди также сделана. IQueues также может быть сохранен через реализацию интерфейса QueueStore.

Что у них общего

Все три из них реализуют интерфейс ICollection. Это означает, что к ним можно добавить ItemListener. Это позволяет узнать, когда элемент добавлен или удален. Примером этого является раздел «Примеры».

Scalablity

Что касается масштабируемости, ISet и IList не очень хорошо справляются с этим в Hazelcast 3.x. Это связано с тем, что реализация изменилась с карты на карту и стала коллекцией в MultiMap. Это означает, что они не разбивают и не выходят за пределы одной машины. Чередование коллекций может иметь большое значение или создание собственных, основанных на мощном IMap. Другой способ заключается в реализации spi Hazelcast.

Примеры

Вот пример ISet, IList и IQueue. Все три из них имеют ItemListener. ItemListener добавлен в файл конфигурации hazelcast.xml. Можно также добавить ItemListener программно для тех, кто склонен. Будет показан основной класс и фрагмент файла конфигурации, который настроил коллекцию.

CollectionItemListener

Я реализовал интерфейс ItemListener, чтобы показать, что все три коллекции могут иметь ItemListener. Вот реализация:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
package hazelcastcollections;
 
import com.hazelcast.core.ItemEvent;
import com.hazelcast.core.ItemListener;
 
/**
*
* @author Daryl
*/
public class CollectionItemListener implements ItemListener {
 
@Override
public void itemAdded(ItemEvent ie) {
System.out.println(“ItemListener – itemAdded: ” + ie.getItem());
}
 
@Override
public void itemRemoved(ItemEvent ie) {
System.out.println(“ItemListener – itemRemoved: ” + ie.getItem());
}
 
}

ISet

Код

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package hazelcastcollections.iset;
 
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ISet;
 
/**
*
* @author Daryl
*/
public class HazelcastISet {
 
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
HazelcastInstance instance2 = Hazelcast.newHazelcastInstance();
ISet<String> set = instance.getSet(“set”);
set.add(“Once”);
set.add(“upon”);
set.add(“a”);
set.add(“time”);
 
ISet<String> set2 = instance2.getSet(“set”);
for(String s: set2) {
System.out.println(s);
}
 
System.exit(0);
}
 
}

конфигурация

1
2
3
4
5
<set name=”set”>
<item-listeners>
<item-listener include-value=”true”>hazelcastcollections.CollectionItemListener</item-listener>
</item-listeners>
</set>

IList

Код

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package hazelcastcollections.ilist;
 
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IList;
 
/**
*
* @author Daryl
*/
public class HazelcastIlist {
 
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
HazelcastInstance instance2 = Hazelcast.newHazelcastInstance();
IList<String> list = instance.getList(“list”);
list.add(“Once”);
list.add(“upon”);
list.add(“a”);
list.add(“time”);
 
IList<String> list2 = instance2.getList(“list”);
for(String s: list2) {
System.out.println(s);
}
System.exit(0);
}
 
}

конфигурация

1
2
3
4
5
<list name=”list”>
<item-listeners>
<item-listener include-value=”true”>hazelcastcollections.CollectionItemListener</item-listener>
</item-listeners>
</list>

IQueue

Код

Я оставил этот последний, потому что я также реализовал QueueStore. В IQueue нет вызова для добавления QueueStore. Нужно настроить его в файле hazelcast.xml.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package hazelcastcollections.iqueue;
 
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IQueue;
 
/**
*
* @author Daryl
*/
public class HazelcastIQueue {
 
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
HazelcastInstance instance2 = Hazelcast.newHazelcastInstance();
IQueue<String> queue = instance.getQueue(“queue”);
queue.add(“Once”);
queue.add(“upon”);
queue.add(“a”);
queue.add(“time”);
 
IQueue<String> queue2 = instance2.getQueue(“queue”);
for(String s: queue2) {
System.out.println(s);
}
 
System.exit(0);
}
 
}

Код QueueStore

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package hazelcastcollections.iqueue;
 
import com.hazelcast.core.QueueStore;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
*
* @author Daryl
*/
public class QueueQStore implements QueueStore<String> {
 
@Override
public void store(Long l, String t) {
System.out.println(“storing ” + t + ” with ” + l);
}
 
@Override
public void storeAll(Map<Long, String> map) {
System.out.println(“store all”);
}
 
@Override
public void delete(Long l) {
System.out.println(“removing ” + l);
}
 
@Override
public void deleteAll(Collection<Long> clctn) {
System.out.println(“deleteAll”);
}
 
@Override
public String load(Long l) {
System.out.println(“loading ” + l);
return “”;
}
 
@Override
public Map<Long, String> loadAll(Collection<Long> clctn) {
System.out.println(“loadAll”);
Map<Long, String> retMap = new TreeMap<>();
return retMap;
}
 
@Override
public Set<Long> loadAllKeys() {
System.out.println(“loadAllKeys”);
return new TreeSet<>();
}
 
}

конфигурация

Некоторые упоминания необходимо учитывать при настройке QueueStore. Есть три свойства, которые не передаются в реализацию. Двоичное свойство имеет дело с тем, как Hazelcast отправит данные в хранилище. Обычно Hazelcast сохраняет сериализованные данные и десериализует их перед отправкой в ​​QueueStore. Если свойство имеет значение true, то данные отправляются в сериализованном виде. По умолчанию установлено значение false. Ограничение памяти — это количество записей, которые хранятся в памяти перед помещением в QueueStore. Ограничение памяти 10000 означает, что 10001-й отправляется в QueueStore. При инициализации IQueue записи загружаются из QueueStore. Свойство массовой загрузки — это количество, которое можно извлечь из QueueStore за один раз.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
<queue name=”queue”>
<max-size>10</max-size>
<item-listeners>
<item-listener include-value=”true”>hazelcastcollections.CollectionItemListener</item-listener>
</item-listeners>
<queue-store>
<class-name>hazelcastcollections.iqueue.QueueQStore</class-name>
<properties>
<property name=”binary”>false</property>
<property name=”memory-limit”>10000</property>
<property name=”bulk-load”>500</property>
</properties>
</queue-store>
</queue>

Вывод

Я надеюсь, что кто-то узнал о распределенных коллекциях внутри Hazelcast. ISet, IList и IQueue были обсуждены. ISet и IList остаются только в том экземпляре, в котором они созданы, в то время как в IQueue сделана копия, его можно сохранить, и его емкость увеличивается с увеличением количества экземпляров. Код можно увидеть здесь.

использованная литература

  • Книга Hazelcast: www.hazelcast.com
  • Документация Hazelcast (поставляется с загрузкой Hazelcast)