【hazelcast入门系列之二】hazelcast的map

本文介绍hazelcast中map的相关操作,包括作为一个分布式的map有哪些功能、hazelcast的一些特色map功能。

一、安装hazelcast

官网下载最新版本的软件包。本次以Hazelcast IMDG 3.11.1进行示例。

  1. 下载后将zip包或者tar包拷贝到centos合适的目录
  2. 进入bin目录修改start.sh ,添加如下代码。可以开启对map的rest访问。

    1
    JAVA_OPTS="$JAVA_OPTS -Dhazelcast.rest.enabled=true"
  3. 到bin目录启动hazelcast, ./start.sh

二、map的常规操作

对于map,可以进行map的插入、更新、删除,同时hazelcast也提供了两种锁实现和map事件的监听。下面分节进行讲解。

2.1 插入、更新、删除

首先我们定义一个VO,方便后续操作。
Customer

1
2
3
4
5
6
7
8
9
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package com.roytrack.hazelcast.distributed.data.structure.map;

import java.io.Serializable;
import java.util.Objects;


public class Customer implements Serializable {
private String id;
private String name;
private Integer age;

public Customer(String id) {
this.id = id;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public Customer clone(Customer c) {
Customer newOne = new Customer(c.getId());
newOne.setAge(c.getAge());
newOne.setName(c.getName());
return newOne;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return Objects.equals(id, customer.id) &&
Objects.equals(name, customer.name) &&
Objects.equals(age, customer.age);
}

@Override
public int hashCode() {

return Objects.hash(id, name, age);
}

@Override
public String toString() {
return "id is " + id + " ,age is " + age + " ,name is " + name;
}

}

对map进行增删改查操作。
BasicMapOperations

1
2
3
4
5
6
7
8
9
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.roytrack.hazelcast.distributed.data.structure.map;

import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;

import java.util.concurrent.ConcurrentMap;

/**
* 注意添加到hazelcast中的内容需要增加序列化
* 所以添加一个对象不需要克隆就可以加很多了
*
* @author roytrack
* @time 2018/7/26 上午11:30
*/
public class BasicMapOperations {
private HazelcastInstance instance = Hazelcast.newHazelcastInstance();

public static void main(String[] args) {
BasicMapOperations basicMapOperations = new BasicMapOperations();
basicMapOperations.instance.addDistributedObjectListener(new SampleForListener());
Customer c = new Customer("22");
c.setName("roy");
c.setAge(23);
basicMapOperations.addCustomer(c);

c.setId("23");
basicMapOperations.addCustomer(c);

c.setId("22");
basicMapOperations.removeCustomer(c);
//不需要克隆了
//c = c.clone(c);
c.setId("24");
basicMapOperations.updateCustomer(c);
ConcurrentMap<String, Customer> customerConcurrentMap = basicMapOperations.instance.getMap("customers");
System.out.println(customerConcurrentMap.size());
((IMap<String, Customer>) customerConcurrentMap).destroy();
System.out.println(customerConcurrentMap.size());
basicMapOperations.addCustomer(c);
c.setId("2");
basicMapOperations.addCustomer(c);
c.setId("3");
basicMapOperations.addCustomer(c);
c.setId("4");
basicMapOperations.addCustomer(c);
System.out.println(customerConcurrentMap.size());
System.out.println(basicMapOperations.getCustomer("2"));
}

public Customer getCustomer(String id) {
ConcurrentMap<String, Customer> customerConcurrentMap = instance.getMap("customers");
Customer customer = customerConcurrentMap.get(id);
if (customer == null) {
customer = new Customer(id);
customer = ((IMap<String, Customer>) customerConcurrentMap).putIfAbsent(id, customer);
}
return customer;
}

public boolean updateCustomer(Customer customer) {
ConcurrentMap<String, Customer> customerConcurrentMap = instance.getMap("customers");
return (customerConcurrentMap.replace(customer.getId(), customer) != null);
}

public boolean removeCustomer(Customer customer) {
ConcurrentMap<String, Customer> customerConcurrentMap = instance.getMap("customers");
return customerConcurrentMap.remove(customer.getId(), customer);
}

public Customer addCustomer(Customer customer) {
ConcurrentMap<String, Customer> customerConcurrentMap = instance.getMap("customers");
return customerConcurrentMap.put(customer.getId(), customer);
}


}

2.2 乐观锁与悲观锁

乐观锁、悲观锁是我们经常在RDBMS中用来控制对记录并发访问时的操作方式。在hazelcast中,我们可以根据读写比来灵活选择。

  1. 悲观锁 map.lock map.unlock
  2. 乐观锁 map.replace
    LockingMapDemo
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    package com.roytrack.hazelcast.distributed.data.structure.map;

    import com.hazelcast.core.Hazelcast;
    import com.hazelcast.core.HazelcastInstance;
    import com.hazelcast.core.IMap;

    public class LockingMapDemo {

    public static void main(String[] args) throws Exception {

    LockingMapDemo demo = new LockingMapDemo();
    demo.pessimisticUpdateMember();
    demo.optimisticMember();

    }

    public void pessimisticUpdateMember() throws Exception {
    HazelcastInstance hz = Hazelcast.newHazelcastInstance();
    IMap<String, Customer> map = hz.getMap("map");
    String key = "1";
    Customer initCustomer = new Customer(key);
    initCustomer.setAge(1);
    initCustomer.setName("roy");
    map.put(key, initCustomer);
    System.out.println("Starting");
    for (int k = 0; k < 1000; k++) {
    map.lock(key);
    try {
    Customer customer = map.get(key);
    Thread.sleep(10);
    customer.setAge(customer.getAge() + 1);
    map.put(key, customer);
    } finally {
    map.unlock(key);
    }
    }
    System.out.println("Finished! Result = " + map.get(key).getAge());
    hz.shutdown();
    }

    public void optimisticMember() throws InterruptedException {
    HazelcastInstance hz = Hazelcast.newHazelcastInstance();
    IMap<String, Customer> map = hz.getMap("map");
    String key = "1";
    Customer initCustomer = new Customer(key);
    initCustomer.setAge(1);
    initCustomer.setName("roy");
    map.put(key, initCustomer);
    System.out.println("Starting");
    for (int k = 0; k < 1000; k++) {
    if (k % 10 == 0) System.out.println("At: " + k);
    for (; ; ) {
    Customer oldValue = map.get(key);
    Customer newValue = Customer.clone(oldValue);
    Thread.sleep(10);
    newValue.setAge(newValue.getAge() + 1);
    if (map.replace(key, oldValue, newValue))
    break;
    }
    }
    System.out.println("Finished! Result = " + map.get(key).getAge());
    hz.shutdown();
    }

    }

2.3 map的监听

对于map的变更事件,可以通过加载listener来监听对应事件,做出对应动作,例子如下:
Employee 实体类
MapListenerWithPredicate 监听类,启动一个hazelcast实例
Modify 对map进行更改,在另外一个实例中

可以得到如下结果:

对map的添加事件、移除事件的监听操作,就可以有进一步处理了。

三、map的REST查询

在前面hazelcast搭建中,我们打开了rest参数。通过post,可以put到hazelcast对象。

通过get即可获取map的值

本文标题:【hazelcast入门系列之二】hazelcast的map

文章作者:roytrack

发布时间:2018年12月23日 - 22:12

原始链接:http://www.roytrack.com/2018/12/id5/

许可协议: 转载请保留原文链接及作者。