Hazelcast 是一个开源的可嵌入式数据网格(社区版免费,企业版收费)。你可以把它看做是内存数据库,不过它与 Redis 等内存数据库又有些不同。项目地址:http://hazelcast.org/
Hazelcast 使得 Java 程序员更容易开发分布式计算系统,提供了很多 Java 接口的分布式实现,如:Map, Queue, Topic, ExecutorService, Lock, 以及 JCache 等。它以一个 JAR 包的形式提供服务,只依赖于 Java,并且提供 Java, C/C++, .NET 以及 REST 客户端,因此十分容易使用。
Hazelcast自称"分布式数据网格”,那他最基本、最重要的功能就是时时刻刻都在多台服务器之间工作,这样必须有网络环境对其分布式功能提供支持。Hazelcast在网络环境中工作分为2个阶段:首先是组网阶段,随后是数据传输阶段。
组网是指每个Hazelcast节点启动时,都会搜寻是否有Hazelcast节点可以连接,组网过程支持多种协议。完成组网后,节点会和其他组建成集群的节点进行通信,这个阶段就是数据传输阶段,此时只支持使用TCP/IP协议来传递数据。Hazelcast的所有网络行为,都是通过*元素配置决定的。*元素用来配置组建集群的相关的参数。
本文章内容只介绍基于springboot的实际操作,中间将会对重要内容及源码进行注解.在idea中新建服务,相关可以参考
<properties>
<spring.cloud-version>Hoxton.SR1</spring.cloud-version>
<spring.alibaba.cloud-version>2.2.2.RELEASE</spring.alibaba.cloud-version>
<spring.boot-version>2.2.2.RELEASE</spring.boot-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.alibaba.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
package org.knowledge.config.hazelcast;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "hazelcast.multicast")
@EnableConfigurationProperties(CmbMultiCastConfig.class)
public class CmbMultiCastConfig {
private boolean enabled;
}
package org.knowledge.config.hazelcast;
import com.hazelcast.config.NetworkConfig;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
@EqualsAndHashCode(callSuper = true)
@Data
@Component
@ConfigurationProperties(prefix = "hazelcast.network")
@EnableConfigurationProperties(CmbMultiCastConfig.class)
public class CmbNetConfig extends NetworkConfig {
private int portCount;
}
TcpIpConfig如下
package org.knowledge.config.hazelcast;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
@ConfigurationProperties(prefix = "hazelcast.tcp.ip")
@EnableConfigurationProperties(CmbMultiCastConfig.class)
public class CmbTcpIpConfig{
private boolean enabled;
private String requiredMember;
private int connectionTimeoutSeconds;
private List<String> members;
}
HazelcastConfigation如下:
package org.knowledge.config;
import com.hazelcast.config.*;
import lombok.Data;
import org.knowledge.config.hazelcast.CmbMultiCastConfig;
import org.knowledge.config.hazelcast.CmbNetConfig;
import org.knowledge.config.hazelcast.CmbTcpIpConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Data
@Component
@ConfigurationProperties(prefix = "hazelcast")
@EnableConfigurationProperties(CmbMultiCastConfig.class)
public class HazelcastConfiguration {
private String groupName;
private String instanceName;
private String mapConfigName;
@Resource
CmbNetConfig cmbNetConfig;
@Resource
CmbMultiCastConfig cmbMultiCastConfig;
@Resource
CmbTcpIpConfig cmbTcpIpConfig;
@Bean
public Config hazelcastConfig() {
Config config = new Config();
JoinConfig joinConfig = new JoinConfig();
MulticastConfig multicastConfig = new MulticastConfig();
multicastConfig.setEnabled(cmbMultiCastConfig.isEnabled());
TcpIpConfig tcpIpConfig = new TcpIpConfig();
tcpIpConfig.setEnabled(cmbTcpIpConfig.isEnabled());
tcpIpConfig.setConnectionTimeoutSeconds(cmbTcpIpConfig.getConnectionTimeoutSeconds());
tcpIpConfig.setRequiredMember(cmbTcpIpConfig.getRequiredMember());
tcpIpConfig.setMembers(cmbTcpIpConfig.getMembers());
//禁止组播协议(Multicast)组建集群,使用tcp/ip协议进行配置集群
joinConfig.setMulticastConfig(multicastConfig);
joinConfig.setTcpIpConfig(tcpIpConfig);
cmbNetConfig.setJoin(joinConfig);
//设置组网的群组名称,每个节点的组名称必须一致且唯一
config.setGroupConfig(new GroupConfig(groupName))
//集群的相关配置
.setNetworkConfig(cmbNetConfig)
//注册hazelcast的名称
.setInstanceName(instanceName)
.addMapConfig(new MapConfig()
.setName(mapConfigName)
.setMaxSizeConfig(new MaxSizeConfig(200, MaxSizeConfig.MaxSizePolicy.FREE_HEAP_SIZE))
.setEvictionPolicy(EvictionPolicy.LRU)
.setTimeToLiveSeconds(1));
return config;
}
}
yaml文件
spring:
application:
name: knowledge-provider
profiles:
active: node1
---
server:
port: 10002
spring:
profiles: node1
hazelcast:
groupName: cmb-hazelcast
instanceName: hazelcast-instance
mapConfigName: cmb-map-configuration
# 端口限制个数,一般在伪集群使用
network:
portCount: 10
# 禁止组播协议(Multicast)组建集群,使用tcp/ip协议进行配置集群
multicast:
enabled: false
tcp:
ip:
# 使用tcp/ip协议进行组网
enabled: true
# 加入集群的成员IP地址,只有这些IP地址的成员存在时集群才会组建
requiredMember: 192.168.56.1
# 定义连接超时时间。Hazelcast尝试连接到一个已知的节点(member元素指定)的最大超时时间
connectionTimeoutSeconds: 6000
# 设置组网发现的ip限制,只有list中的ip才能被发现
members:
- 192.168.56.1
- 192.168.56.2
- 192.168.56.3
---
server:
port: 10003
spring:
profiles: node2
hazelcast:
groupName: cmb-hazelcast
instanceName: hazelcast-instance
mapConfigName: cmb-map-configuration
# 端口限制个数,一般在伪集群使用
network:
portCount: 10
# 禁止组播协议(Multicast)组建集群,使用tcp/ip协议进行配置集群
multicast:
enabled: false
tcp:
ip:
# 使用tcp/ip协议进行组网
enabled: true
# 加入集群的成员IP地址,只有这些IP地址的成员存在时集群才会组建
requiredMember: 192.168.56.1
# 定义连接超时时间。Hazelcast尝试连接到一个已知的节点(member元素指定)的最大超时时间
connectionTimeoutSeconds: 6000
# 设置组网发现的ip限制,只有list中的ip才能被发现
members:
- 192.168.56.1
- 192.168.56.2
- 192.168.56.3
---
server:
port: 10004
spring:
profiles: node3
hazelcast:
groupName: cmb-hazelcast
instanceName: hazelcast-instance
mapConfigName: cmb-map-configuration
# 端口限制个数,一般在伪集群使用
network:
portCount: 10
# 禁止组播协议(Multicast)组建集群,使用tcp/ip协议进行配置集群
multicast:
enabled: false
tcp:
ip:
# 使用tcp/ip协议进行组网
enabled: true
# 加入集群的成员IP地址,只有这些IP地址的成员存在时集群才会组建
requiredMember: 192.168.57.1
# 定义连接超时时间。Hazelcast尝试连接到一个已知的节点(member元素指定)的最大超时时间
connectionTimeoutSeconds: 6000
# 设置组网发现的ip限制,只有list中的ip才能被发现
members:
- 192.168.57.1
- 192.168.57.2
- 192.168.57.3
使用分为两种;嵌入式和客户端服务器,相关可以参考
package org.knowledge.web;
import com.hazelcast.core.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class HazelcastController {
@Resource
HazelcastInstance hazelcastInstance;
@PostMapping("/write")
public String writeData() {
IMap<Object, Object> map = hazelcastInstance.getMap("test");
map.put("name", "张三");
return "map name is: test";
}
@GetMapping("/get")
public Object getData() {
IMap<Object, Object> map = hazelcastInstance.getMap("test");
return map.get("name");
}
}
使用多播机制来找寻其他的的节点,但是一般生产环境会禁用UDP,所以一般不使用这种机制来发现节点.