Deploying a Cluster on Microsoft Azure
Deploy Hazelcast clusters on Azure and allow them to discover each other automatically.
Before you Begin
Hazelcast uses Azure Instance Metadata Service to get an access token as well as other environment details. To use this service, Hazelcast requires Azure managed identities with the correct READ
roles.
Discovering Members Automatically
To make it easier to set up clusters on Microsoft Azure, Hazelcast allows members to discover each other automatically, using discovery strategies.
Enable the Hazelcast Azure discovery service:
<hazelcast>
<network>
<join>
<multicast enabled="false"/>
<azure enabled="true">
<tag>TAG-NAME=HZLCAST001</tag>
<hz-port>5701-5703</hz-port>
</azure>
</join>
</network>
</hazelcast>
hazelcast:
network:
join:
multicast:
enabled: false
azure:
enabled: true
tag: TAG-NAME=HZLCAST001
hz-port: 5701-5703
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
config.getNetworkConfig().getJoin().getAzureConfig().setEnabled(true);
.setProperty("tag", "TAG-NAME=HZLCAST001")
.setProperty("hz-port", "5701-5703");
The following properties are optional:
-
tag
- The key-value pair of the tag on the Azure network interfaces (NIC). The format should be askey=value
. If this setting is configured, Hazelcast will search for instances over only the resources that have this tag entry in their network interfaces. If not configured, Hazelcast will search for instances over all available resources. -
hz-port
- The port range where Hazelcast is expected to be running. The format should be as5701
or5701-5703
. The default value is5701-5703
.
The other necessary information such as subscription ID and resource group name will be retrieved from the Azure Instance Metadata Service. This allows Hazelcast to run without keeping any secret or password in the code or configuration.
If you don’t setup the correct access roles on Azure environment, then you will see an exception similar below:
WARNING: Cannot discover nodes, returning empty list
com.hazelcast.azure.RestClientException: Failure in executing REST call
at com.hazelcast.azure.RestClient.call(RestClient.java:106)
at com.hazelcast.azure.RestClient.get(RestClient.java:69)
at com.hazelcast.azure.AzureMetadataApi.callGet(AzureMetadataApi.java:107)
at com.hazelcast.azure.AzureMetadataApi.accessToken(AzureMetadataApi.java:96)
at com.hazelcast.azure.AzureClient.fetchAccessToken(AzureClient.java:131)
at com.hazelcast.azure.AzureClient.getAddresses(AzureClient.java:118)
at com.hazelcast.azure.AzureDiscoveryStrategy.discoverNodes(AzureDiscoveryStrategy.java:136)
at com.hazelcast.spi.discovery.impl.DefaultDiscoveryService.discoverNodes(DefaultDiscoveryService.java:71)
at com.hazelcast.internal.cluster.impl.DiscoveryJoiner.getPossibleAddresses(DiscoveryJoiner.java:69)
at com.hazelcast.internal.cluster.impl.DiscoveryJoiner.getPossibleAddressesForInitialJoin(DiscoveryJoiner.java:58)
at com.hazelcast.internal.cluster.impl.TcpIpJoiner.joinViaPossibleMembers(TcpIpJoiner.java:136)
at com.hazelcast.internal.cluster.impl.TcpIpJoiner.doJoin(TcpIpJoiner.java:96)
at com.hazelcast.internal.cluster.impl.AbstractJoiner.join(AbstractJoiner.java:137)
at com.hazelcast.instance.impl.Node.join(Node.java:796)
at com.hazelcast.instance.impl.Node.start(Node.java:451)
at com.hazelcast.instance.impl.HazelcastInstanceImpl.<init>(HazelcastInstanceImpl.java:122)
at com.hazelcast.instance.impl.HazelcastInstanceFactory.constructHazelcastInstance(HazelcastInstanceFactory.java:241)
at com.hazelcast.instance.impl.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:220)
at com.hazelcast.instance.impl.HazelcastInstanceFactory.newHazelcastInstance(HazelcastInstanceFactory.java:158)
at com.hazelcast.core.Hazelcast.newHazelcastInstance(Hazelcast.java:91)
at com.hazelcast.core.server.HazelcastMemberStarter.main(HazelcastMemberStarter.java:46)
Caused by: com.hazelcast.azure.RestClientException: Failure executing: GET at: http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com. Message: {"error":"invalid_request","error_description":"Identity not found"},
at com.hazelcast.azure.RestClient.call(RestClient.java:101)
... 20 more
Discovering Members from Hazelcast Clients
If you have Hazelcast clients running outside an Azure VM, the Azure Instance Metadata service unavailable. In this case, Hazelcast client instances should be configured with the following properties:
You will need to setup Microsoft Entra Service Principal credentials for your Azure Subscription to be able to use these properties. |
-
instance-metadata-available
- This property should be configured asfalse
in order to be able to use the following properties. It istrue
by default. -
client-id
- The Microsoft Entra Service Principal client ID. -
client-secret
- The Microsoft Entra Service Principal client secret. -
tenant-id
- The Microsoft Entra tenant ID. -
subscription-id
- The Azure subscription ID. -
resource-group
- The name of Azure resource group which the Hazelcast instance is running in. -
scale-set
- (Optional) The name of Azure VM scale set. If this setting is configured, the plugin will search for instances over the resources only within this scale set. -
use-public-ip
- Enables the discovery joiner to use public IPs. It should be set totrue
in client instances running outside the Azure environment.
<hazelcast-client>
<network>
<azure enabled="true">
<instance-metadata-available>false</instance-metadata-available>
<client-id>CLIENT_ID</client-id>
<client-secret>CLIENT_SECRET</client-secret>
<tenant-id>TENANT_ID</tenant-id>
<subscription-id>SUB_ID</subscription-id>
<resource-group>RESOURCE-GROUP-NAME</resource-group>
<scale-set>SCALE-SET-NAME</scale-set>
<use-public-ip>true</use-public-ip>
</azure>
</network>
</hazelcast-client>
hazelcast-client:
network:
azure:
enabled: true
instance-metadata-available: false
client-id: CLIENT_ID
tenant-id: TENANT_ID
client-secret: CLIENT_SECRET
subscription-id: SUB_ID
resource-group: RESOURCE-GROUP-NAME
scale-set: SCALE-SET-NAME
use-public-ip: true
clientConfig.getNetworkConfig().getAzureConfig()
.setEnabled(true)
.setProperty("instance-metadata-available", "false")
.setProperty("client-id", "CLIENT_ID")
.setProperty("tenant-id", "TENANT_ID")
.setProperty("client-secret", "CLIENT_SECRET")
.setProperty("subscription-id", "SUB_ID")
.setProperty("resource-group", "RESOURCE-GROUP-NAME")
.setProperty("scale-set", "SCALE-SET-NAME")
.setProperty("use-public-ip", "true");
Configuration for WAN Replication Target Cluster Discovery
Hazelcast allows you to configure WAN replication to work with the clusters in Azure and determine the endpoint IP addresses at runtime. If one Hazelcast cluster is running outside Azure and another is running inside Azure, then you should configure your WAN batch publisher as below:
You will need to setup Microsoft Entra Service Principal credentials for your Azure Subscription to be able to use these properties. |
-
instance-metadata-available
- This property should be configured asfalse
in order to be able to use the following properties. It istrue
by default. -
client-id
- The Microsoft Entra Service Principal client ID. -
client-secret
- The Microsoft Entra Service Principal client secret. -
tenant-id
- The Microsoft Entra tenant ID. -
subscription-id
- The Azure subscription ID. -
resource-group
- The name of Azure resource group which the Hazelcast instance is running in. -
scale-set
- (Optional) The name of Azure VM scale set. If this setting is configured, the plugin will search for instances over the resources only within this scale set. -
use-public-ip
- Enables the discovery joiner to use public IPs. It should be set totrue
in client instances running outside the Azure environment.
<hazelcast>
<wan-replication name="my-wan-cluster-batch">
<batch-publisher>
...
<azure enabled="true">
<instance-metadata-available>false</instance-metadata-available>
<client-id>CLIENT_ID</client-id>
<client-secret>CLIENT_SECRET</client-secret>
<tenant-id>TENANT_ID</tenant-id>
<subscription-id>SUB_ID</subscription-id>
<resource-group>RESOURCE-GROUP-NAME</resource-group>
<scale-set>SCALE-SET-NAME</scale-set>
</azure>
</batch-publisher>
</wan-replication>
</hazelcast>
hazelcast:
wan-replication:
name: my-wan-cluster-batch
batch-publisher:
...
azure:
enabled: true
instance-metadata-available: false
client-id: CLIENT_ID
tenant-id: TENANT_ID
client-secret: CLIENT_SECRET
subscription-id: SUB_ID
resource-group: RESOURCE-GROUP-NAME
scale-set: SCALE-SET-NAME
WanBatchPublisherConfig batchPublisherConfig = new WanBatchPublisherConfig()
.getAzureConfig()
.setEnabled(true)
.setProperty("instance-metadata-available", "false")
.setProperty("client-id", "CLIENT_ID")
.setProperty("tenant-id", "TENANT_ID")
.setProperty("client-secret", "CLIENT_SECRET")
.setProperty("subscription-id", "SUB_ID")
.setProperty("resource-group", "RESOURCE-GROUP-NAME")
.setProperty("scale-set", "SCALE-SET-NAME")
.setProperty("use-public-ip", "true");
Azure App Services Support
Azure App Services is a platform as a service (PaaS) which allows publishing applications running on multiple frameworks and written in different programming languages. If you would like to use Hazelcast in your App Service applications, you can connect a Hazelcast client to a Hazelcast cluster running in Azure environment.
Azure App Services are unaware of the underlying VMs' network interfaces so it is not available to communicate among App Services using TCP/IP. Because of this reason, it is not possible to deploy a Hazelcast cluster on Azure App Services.
Preventing Data Loss
By default, Hazelcast distributes partition replicas (backups) randomly and equally among cluster members. However, this is not safe in terms of high availability when a partition and its replicas are stored on the same rack, using the same network, or power source. To deal with that, Hazelcast offers logical partition grouping, so that a partition itself and its backups would not be stored within the same group. This way Hazelcast guarantees that a possible failure affecting more than one member at a time will not cause data loss. For more details about partition groups, see Partition Group Configuration.
In addition to built-in grouping option ZONE_AWARE
, you can customize the formation of
these groups based on the network interfaces of members. For more details about custom groups, see
Custom Partition Groups.
Multi-Zone Deployments
If ZONE_AWARE
partition group is enabled, the backups of a partition are always stored in a different availability
zone. Note that if a cluster is deployed to an Azure region that does not support availability zones, then the fault
domains of instances are used when forming partition groups. That is, the members on fault domain (FD) 0 form a single
group, and those on FD 1 form another group, and so on.
When using the ZONE_AWARE partition grouping, a cluster spanning multiple availability zones (or fault
domains if the region does not support zones) should have an equal number of members in each zone (or fault domain).
Otherwise, it will result in uneven partition distribution among the members.*
|
Automated Deployment
You can also use the Azure Hazelcast Template to automatically deploy a Hazelcast cluster.