Configure Hazelcast With EC2
Hazelcast is hands down a great caching tool when it comes to a JVM based application. If you use Amazon Web Services, Hazelcast integrates wonderfully.
Join the DZone community and get the full member experience.
Join For FreeHazelcast is hands down a great caching tool when it comes to a JVM-based application. If you use Amazon Web Services, Hazelcast integrates wonderfully.
The first task is to create a policy responsible for describing instances. We shall name this policy describe-instances-policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1467219263000",
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances"
],
"Resource": [
"*"
]
}
]
}
Applications that have to access Amazon resources should either use a user or a role that has the policies for the resources we need attached. Using an Amazon user for your application is a bad practice, and it becomes a maintenance headache managing keys, let alone security issues. Therefore, we will focus on Hazelcast configuration using IAM roles.
Our role will be called my-ec2-role and will have the policy describe-instances-policy attached.
By doing so, an EC2 instance with Hazelcast would be able to retrieve the private IPs of other EC2 instances and, therefore, would attempt to identify which instances are eligible to establish a distributed cache.
Now we can proceed to the Hazelcast configuration. We can either do a Java-based configuration or an XML-based configuration.
Let's start with the XML configuration:
<hazelcast
xsi:schemaLocation="https://hazelcast.com/schema/config https://hazelcast.com/schema/config/hazelcast-config-3.7.xsd"
xmlns="http://www.hazelcast.com/schema/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<field>ec2-group</field>
<password>ec2-password</password>
</group>
<network>
<join>
<multicast enabled="false">
</multicast>
<tcp-ip enabled="false">
</tcp-ip>
<aws enabled="true">
<!--optional, default is us-east-1 -->
<region>eu-west-1</region>
<iam-role>my-ec2-role</iam-role>
<!-- optional, only instances belonging to this group will be discovered, default will try all running instances -->
<security-group-field></security-group-field>
<tag-key></tag-key>
<tag-value></tag-value>
</aws>
</join>
</network>
</hazelcast>
And the main class to load the XML file:
package com.gkatzioura.hazelcastec2;
import com.hazelcast.config.*;
import com.hazelcast.core.Hazelcast;
/**
* Created by gkatzioura on 7/26/16.
*/
public class HazelCastXMLExample {
public static void main(String args[]) {
Config config = new ClasspathXmlConfig("hazelcast.xml");
Hazelcast.newHazelcastInstance(config);
}
}
Notice that multicast and TCP/IP should be disabled. Because we specify an IAM role, there is no need to provide credentials. Tag-key and Tag-value represent the tags that you can add on an EC2 machine. If you specify tag key and value, a connection will be established only on machines that have the same tag and value.
You can leave the security-group-field empty. Hazelcast uses this information for instance filtering; however, you must make sure the security group that the EC2 instance uses has ports 5701, 5702, and 5703 open for inbound and outbound traffic.
The Java configuration follows the same rules:
package com.gkatzioura.hazelcastec2;
import com.hazelcast.aws.AWSClient;
import com.hazelcast.config.AwsConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.GroupConfig;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
/**
* Created by gkatzioura on 7/25/16.
*/
public class HazelCastJavaExample {
public static void main(String args[]) {
Config config = new Config();
GroupConfig groupConfig = new GroupConfig();
groupConfig.setName("ec2-group");
groupConfig.setPassword("ec2-password");
config.setGroupConfig(groupConfig);
JoinConfig joinConfig = config.getNetworkConfig().getJoin();
joinConfig.getTcpIpConfig().setEnabled(false);
joinConfig.getMulticastConfig().setEnabled(false);
AwsConfig awsConfig = joinConfig.getAwsConfig();
awsConfig.setIamRole("my-ec2-role");
awsConfig.setEnabled(true);
awsConfig.setRegion("eu-west-1");
Hazelcast.newHazelcastInstance(config);
}
}
After uploading your Hazelcast apps to EC2 and running them, you can see the following log:
Jul 26, 2016 6:34:50 PM com.hazelcast.cluster.ClusterService
INFO: [172.31.33.104]:5701 [dev] [3.5.4]
Members [2] {
Member [172.31.33.104]:5701 this
Member [172.31.41.154]:5701
}
I have added a Gradle file for some quick testing, with either the XML or Java configurations:
group 'com.gkatzioura'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.5
repositories {
mavenCentral()
}
apply plugin: 'idea'
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile group: 'com.hazelcast', name:'hazelcast-cloud', version:'3.5.4'
}
task javaConfJar(type: Jar) {
manifest {
attributes 'Main-Class': 'com.gkatzioura.hazelcastec2.HazelCastJavaExample'
}
baseName = project.name + '-jconf'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
task javaXMLJar(type: Jar) {
manifest {
attributes 'Main-Class': 'com.gkatzioura.hazelcastec2.HazelCastXMLExample'
}
baseName = project.name + '-xmlconf'
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
You can find the source code on GitHub.
Published at DZone with permission of Emmanouil Gkatziouras, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments