Common Pitfalls & Performance Tips

Hazelcast – Common Pitfalls & Performance Tips ”; Previous Next Hazelcast Queue on single machine Hazelcast queues are stored on a single member (along with a backup on different machines). This effectively means the queue can hold as many items which can be accommodated on a single machine. So, the queue capacity does not scale by adding more members. Loading more data than what a machine can handle in a queue can cause the machine to crash. Using Map”s set method instead of put If we use IMap”s put(key, newValue), Hazelcast returns the oldValue. This means, extra computation and time is spent in deserialization. This also includes more data sent from the network. Instead, if we are not interested in the oldValue, we can use set(key, value) which returns void. Let’s see how to store and inject references to Hazelcast structures. The following code creates a map of the name “stock” and adds Mango at one place and Apple at another. //initialize hazelcast instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); // create a map IMap<String, String> hzStockTemp = hazelcast.getMap(“stock”); hzStock.put(“Mango”, “4”); IMap<String, String> hzStockTemp2 = hazelcast.getMap(“stock”); hzStock.put(“Apple”, “3”); However, the problem here is that we are using getMap(“stock”) twice. Although this call seems harmless in a single node environment, it creates slowness in a clustered environment. The function call getMap() involves network round trips to other members of the cluster. So, it is recommended that we store the reference to the map locally and use the referencing while operating on the map. For example − // create a map IMap<String, String> hzStock = hazelcast.getMap(“stock”); hzStock.put(“Mango”, “4”); hzStock.put(“Apple”, “3”); Hazelcast uses serialized data for object comparison As we have seen in the earlier examples, it is very critical to note that Hazelcast does not use deserialize objects while comparing keys. So, it does not have access to the code written in our equals/hashCode method. According to Hazelcast, keys are equal if the value to all the attributes of two Java objects is the same. Use monitoring In a large-scale distributed system, monitoring plays a very important role. Using REST API and JMX for monitoring is very important for taking proactive measures instead of being reactive. Homogeneous cluster Hazelcast assumes all the machines are equal, i.e., all the machines have same resources. But if our cluster contains a less powerful machine, for example, less memory, lesser CPU power, etc., then it can create slowness if the computation happens on that machine. Worst, the weaker machine can run out of resources causing cascading failures. So, it is necessary that Hazelcast members have equal resource power. Print Page Previous Next Advertisements ”;

Hazelcast – Quick Guide

Hazelcast – Quick Guide ”; Previous Next Hazelcast – Introduction Distributed In-memory Data Grid A data grid is a superset to distributed cache. Distributed cache is typically used only for storing and retrieving key-value pairs which are spread across caching servers. However, a data grid, apart from supporting storage of key-value pairs, also supports other features, for example, It supports other data structures like locks, semaphores, sets, list, and queues. It provides a way to query the stored data by rich querying languages, for example, SQL. It provides a distributed execution engine which helps to operate on the data in parallel. Benefits of Hazelcast Support multiple data structures − Hazelcast supports the usage of multiple data structures along with Map. Some of the examples are Lock, Semaphore, Queue, List, etc. Fast R/W access − Given that all the data is in-memory, Hazelcast offers very high-speed data read/write access. High availability − Hazelcast supports the distribution of data across machines along with additional support for backup. This means that the data is not stored on a single machine. So, even if a machine goes down, which occurs frequently in a distributed environment, the data is not lost. High Performance − Hazelcast provides constructs which can be used to distribute the workload/computation/query among multiple worker machines. This means a computation/query uses resources from multiple machines which reduces the execution time drastically. Easy to use − Hazelcast implements and extends a lot of java.util.concurrent constructs which make it very easy to use and integrate with the code. Configuration to start using Hazelcast on a machine just involves adding the Hazelcast jar to our classpath. Hazelcast vs Other Caches & Key-Value stores Comparing Hazelcast with other caches like Ehcache, Guava, and Caffeine may not be very useful. It is because, unlike other caches, Hazelcast is a distributed cache, that is, it spreads the data across machines/JVM. Although Hazelcast can work very well on single JVM as well, however, it is more useful is a distributed environment. Similarly comparing it with Databases like MongoDB is also of not much use. This is because, Hazelcast mostly stores data in memory (although it also supports writing to disk). So, it offers high R/W speed with the limitation that data needs to be stored in memory. Hazelcast also supports caching/storing complex data types and provides an interface to query them, unlike other data stores. A comparison, however, can be made with Redis which also offers similar features. Hazelcast vs Redis In terms of features, both Redis and Hazelcast are very similar. However, following are the points where Hazelcast scores over Redis − Built for Distributed Environment from ground-up − Unlike Redis, which started as single machine cache, Hazelcast, from the very beginning, has been built for distributed environment. Simple cluster scale in/out − Maintaining a cluster where nodes are added or removed is very simple in case of Hazelcast, for example, adding a node is a matter of launching the node with the required configuration. Removing a node requires simple shutting down of the node. Hazelcast automatically handles partitioning of data, etc. Having the same setup for Redis and performing the above operation requires more precaution and manual efforts. Less resources needs to support failover − Redis follows master-slave approach. For failover, Redis requires additional resources to setup Redis Sentinel. These Sentinel nodes are responsible to elevate a slave to master if the original master node goes down. In Hazelcast, all nodes are treated equal, failure of a node is detected by other nodes. So, the case of a node going down is handled pretty transparently and that too without any additional set of monitoring servers. Simple Distributed Compute − Hazelcast, with its EntryProcessor, provides a simple interface to send the code to the data for parallel processing. This reduces data transfer over the wire. Redis also supports this, however, achieving this requires one to be aware of Lua scripting which adds additional learning curve. Hazelcast – Setup Hazelcast requires Java 1.6 or above. Hazelcast can also be used with .NET, C++, or other JVM based languages like Scala and Clojure. However, for this tutorial, we are going to use Java 8. Before we move on, following is the project setup that we will use for this tutorial. hazelcast/ ├── com.example.demo/ │ ├── SingleInstanceHazelcastExample.java │ ├── MultiInstanceHazelcastExample.java │ ├── Server.java │ └── …. ├── pom.xml ├── target/ ├── hazelcast.xml ├── hazelcast-multicast.xml ├── … For now, we can just create the package, i.e., com.example.demo inside the hazelcast directory. Then, just cd to that directory. We will look at other files in the upcoming sections. Installing Hazelcast Installing Hazelcast simply involves adding a JAR file to your build file. POM file or build.gradle based on whether you are using Maven or Gradle respectively. If you are using Gradle, adding the following to build.gradle file would be enough − dependencies { compile “com.hazelcast:hazelcast:3.12.12” } POM for the tutorial We will use the following POM for our tutorial − <?xml version=”1.0″ encoding=”UTF-8″?> <project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”> <modelVersion>1.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Hazelcast</description> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast</artifactId> <version>3.12.12</version> </dependency> </dependencies> <!– Below build plugin is not needed for Hazelcast, it is being used only to created a shaded JAR so that –> <!– using the output i.e. the JAR becomes simple for testing snippets in the tutorial–> <build> <plugins> <plugin> <!– Create a shaded JAR and specify the entry point class–> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> Hazelcast – First Application Hazelcast can be run in isolation (single node) or multiple nodes can be run to form a cluster. Let us first try starting a single instance. Single Instance Example Now, let us try creating and using a single instance of Hazelcast cluster. For that, we will create SingleInstanceHazelcastExample.java file. package com.example.demo; import java.util.Map; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public class SingleInstanceHazelcastExample { public static void main(String… args){ //initialize hazelcast server/instance HazelcastInstance hazelcast

Hazelcast – Discussion

Discuss Hazelcast ”; Previous Next Hazelcast is a distributed IMDG, i.e. in-memory data grid, which is used widely across industries by companies like Nissan, JPMorgan, Tmobile, to name a few. It offers various rich features including distributed cache to store key-value pairs, constructs to create and use distributed data structure, and a way to distribute your computation and queries among nodes in a cluster. Hazelcast is a very useful tool in developing applications that require high scalability, performance, and availability. Print Page Previous Next Advertisements ”;

Hazelcast – Collection Listener

Hazelcast – Collection Listener ”; Previous Next Hazelcast supports addition of listeners when a given collection, for example, queue, set, list, etc. is updated. Typical events include entry added and entry removed. Let”s see how to implement a set listener via an example. So, let”s say we want to implement a listener which tracks the number of elements in a set. Example So, let’s first implement the Producer − public class SetTimedProducer{ public static void main(String… args) throws IOException, InterruptedException { //initialize hazelcast instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); Thread.sleep(5000); // create a set ISet<String> hzFruits = hazelcast.getSet(“fruits”); hzFruits.add(“Mango”); Thread.sleep(2000); hzFruits.add(“Apple”); Thread.sleep(2000); hzFruits.add(“Banana”); System.exit(0); } } Now let”s implement the listener − package com.example.demo; import java.io.IOException; import com.hazelcast.core.ISet; import com.hazelcast.core.ItemEvent; import com.hazelcast.core.ItemListener; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public class SetListener{ public static void main(String… args) throws IOException, InterruptedException { //initialize hazelcast instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); // create a set ISet<String> hzFruits = hazelcast.getSet(“fruits”); ItemListener<String> listener = new FruitListener<String>(); hzFruits.addItemListener(listener, true); System.exit(0); } private static class FruitListener<String> implements ItemListener<String> { private int count = 0; @Override public void itemAdded(ItemEvent<String> item) { System.out.println(“item added” + item); count ++; System.out.println(“Total elements” + count); } @Override public void itemRemoved(ItemEvent<String> item) { count –; } } } We will first run the producer − java -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.SetTimedProducer And then, we run the listeners and let it run indefinitely − java -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.SetListener Output The output from the Listener is as follows − item added: ItemEvent{ event=ADDED, item=Mango, member=Member [localhost]:5701-c28a60b7-3259-44bf-8793-54063d244394 this} Total elements: 1 item added: ItemEvent{ event=ADDED, item=Apple, member=Member [localhost]:5701-c28a60b7-3259-44bf-8793-54063d244394 this} Total elements: 2 item added: ItemEvent{ event=ADDED, item=Banana, member=Member [localhost]:5701-c28a60b7-3259-44bf-8793-54063d244394 this} Total elements: 3 The call with hzFruits.addItemListener(listener, true) tells Hazelcast to provide member information. If set to false, we will just be notified that an entry was added/removed. This helps in avoiding the need to serialize and deserialize the entry to make it accessible to the listener. Print Page Previous Next Advertisements ”;

Hazelcast – Client

Hazelcast – Client ”; Previous Next Hazelcast clients are the lightweight clients to Hazelcast members. Hazelcast members are responsible to store data and the partitions. They act like the server in the traditional client-server model. Hazelcast clients are created only for accessing data stored with Hazelcast members of the cluster. They are not responsible to store data and do not take any ownership to store data. The clients have their own life cycle and do not affect the Hazelcast member instances. Let”s first create Server.java and run it. import java.util.Map; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public class Server { public static void main(String… args){ //initialize hazelcast server/instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); //create a simple map Map<String, String> vehicleOwners = hazelcast.getMap(“vehicleOwnerMap”); // add key-value to map vehicleOwners.put(“John”, “Honda-9235″); // do not shutdown, let the server run //hazelcast.shutdown(); } } Now, run the above class. java -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.Server For setting up a client, we also need to add client jar. <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-client</artifactId> <version>3.12.12</version> </dependency> Let”s now create Client.java. Note that similar to Hazelcast members, clients can also be configured programmatically or via XML configuration (i.e., via -Dhazelcast.client.config or hazelcast-client.xml). Example Let’s use the default configuration which means our client would be able to connect to local instances. import java.util.Map; import com.hazelcast.client.HazelcastClient; import com.hazelcast.core.HazelcastInstance; public class Client { public static void main(String… args){ //initialize hazelcast client HazelcastInstance hzClient = HazelcastClient.newHazelcastClient(); //read from map Map<String, String> vehicleOwners = hzClient.getMap(“vehicleOwnerMap”); System.out.println(vehicleOwners.get(“John”)); System.out.println(“Member of cluster: ” + hzClient.getCluster().getMembers()); // perform shutdown hzClient.getLifecycleService().shutdown(); } } Now, run the above class. java -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.Client Output It will produce the following output − Honda-9235 Member of cluster: [Member [localhost]:5701 – a47ec375-3105-42cd-96c7-fc5eb382e1b0] As seen from the output − The cluster only contains 1 member which is from Server.java. The client is able to access the map which is stored inside the server. Load Balancing Hazelcast Client supports load balancing using various algorithms. Load balancing ensures that the load is shared across members and no single member of the cluster is overloaded. The default load balancing mechanism is set to round-robin. The same can be changed by using the loadBalancer tag in the config. We can specify the type of load balancer using the load-balancer tag in the configuration. Here is a sample for choosing a strategy that randomly picks up a node. <hazelcast-client xmlns=”http://www.hazelcast.com/schema/client-config” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://www.hazelcast.com/schema/client-config http://www.hazelcast.com/schema/client-config/hazelcastclient-config-4.2.xsd”> <load-balancer type=”random”/> </hazelcast-client> Failover In a distributed environment, members can fail arbitrarily. For supporting failover, it is recommended that address to multiple members is provided. If the client gets access to any one member, that is sufficient for it to get addressed to other members. The parameters addressList can be specified in the client configuration. For example, if we use the following configuration − <hazelcast-client xmlns=”http://www.hazelcast.com/schema/client-config” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://www.hazelcast.com/schema/client-config http://www.hazelcast.com/schema/client-config/hazelcastclient-config-4.2.xsd”> <address-list>machine1, machine2</address-list> </hazelcast-client> Even if, say, machine1 goes down, clients can use machine2 to get access to other members of the cluster. Print Page Previous Next Advertisements ”;

Hazelcast – Useful Resources

Hazelcast – Useful Resources ”; Previous Next The following resources contain additional information on Hazelcast. Please use them to get more in-depth knowledge on this. Useful Links on Hazelcast Hazelcast − Office website of Hazelcast Hazelcast @ Wikipedia− Hazelcast, its history and various other terms has been explained in simple language. Useful Books on Hazelcast To enlist your site on this page, please drop an email to [email protected] Print Page Previous Next Advertisements ”;

Map Reduce & Aggregations

Hazelcast – Map Reduce & Aggregations ”; Previous Next MapReduce is a computation model which is useful for data processing when you have lots of data and you need multiple machines, i.e., a distributed environment to calculate data. It involves ”map”ing of data into key-value pairs and then ”reducing”, i.e., grouping these keys and performing operation on the value. Given the fact that Hazelcast is designed keeping a distributed environment in mind, implementing Map-Reduce Frameworks comes naturally to it. Let’s see how to do it with an example. For example, let”s suppose we have data about a car (brand & car number) and the owner of that car. Honda-9235, John Hyundai-235, Alice Honda-935, Bob Mercedes-235, Janice Honda-925, Catnis Hyundai-1925, Jane And now, we have to figure out the number of cars for each brand, i.e., Hyundai, Honda, etc. Example Let”s try to find that out using MapReduce − package com.example.demo; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.atomic.AtomicInteger; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.ICompletableFuture; import com.hazelcast.core.IMap; import com.hazelcast.mapreduce.Context; import com.hazelcast.mapreduce.Job; import com.hazelcast.mapreduce.JobTracker; import com.hazelcast.mapreduce.KeyValueSource; import com.hazelcast.mapreduce.Mapper; import com.hazelcast.mapreduce.Reducer; import com.hazelcast.mapreduce.ReducerFactory; public class MapReduce { public static void main(String[] args) throws ExecutionException, InterruptedException { try { // create two Hazelcast instances HazelcastInstance hzMember = Hazelcast.newHazelcastInstance(); Hazelcast.newHazelcastInstance(); IMap<String, String> vehicleOwnerMap=hzMember.getMap(“vehicleOwnerMap”); vehicleOwnerMap.put(“Honda-9235”, “John”); vehicleOwnerMap.putc”Hyundai-235″, “Alice”); vehicleOwnerMap.put(“Honda-935”, “Bob”); vehicleOwnerMap.put(“Mercedes-235”, “Janice”); vehicleOwnerMap.put(“Honda-925”, “Catnis”); vehicleOwnerMap.put(“Hyundai-1925”, “Jane”); KeyValueSource<String, String> kvs=KeyValueSource.fromMap(vehicleOwnerMap); JobTracker tracker = hzMember.getJobTracker(“vehicleBrandJob”); Job<String, String> job = tracker.newJob(kvs); ICompletableFuture<Map<String, Integer>> myMapReduceFuture = job.mapper(new BrandMapper()) .reducer(new BrandReducerFactory()).submit(); Map<String, Integer&g; result = myMapReduceFuture.get(); System.out.println(“Final output: ” + result); } finally { Hazelcast.shutdownAll(); } } private static class BrandMapper implements Mapper<String, String, String, Integer> { @Override public void map(String key, String value, Context<String, Integer> context) { context.emit(key.split(“-“, 0)[0], 1); } } private static class BrandReducerFactory implements ReducerFactory<String, Integer, Integer> { @Override public Reducer<Integer, Integer> newReducer(String key) { return new BrandReducer(); } } private static class BrandReducer extends Reducer<Integer, Integer> { private AtomicInteger count = new AtomicInteger(0); @Override public void reduce(Integer value) { count.addAndGet(value); } @Override public Integer finalizeReduce() { return count.get(); } } } Let’s try to understand this code − We create Hazelcast members. In the example, we have a single member, but there can well be multiple members. We create a map using dummy data and create a Key-Value store out of it. We create a Map-Reduce job and ask it to use the Key-Value store as the data. We then submit the job to cluster and wait for completion. The mapper creates a key, i.e., extracts brand information from the original key and sets the value to 1 and then emits that information as K-V to the reducer. The reducer simply sums the value, grouping the data, based on key, i.e., brand name. Output The output of the code − Final output: {Mercedes=1, Hyundai=2, Honda=3} Print Page Previous Next Advertisements ”;

Hazelcast – First Application

Hazelcast – First Application ”; Previous Next Hazelcast can be run in isolation (single node) or multiple nodes can be run to form a cluster. Let us first try starting a single instance. Single Instance Example Now, let us try creating and using a single instance of Hazelcast cluster. For that, we will create SingleInstanceHazelcastExample.java file. package com.example.demo; import java.util.Map; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public class SingleInstanceHazelcastExample { public static void main(String… args){ //initialize hazelcast server/instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); System.out.println(“Hello world”); // perform a graceful shutdown hazelcast.shutdown(); } } Now let’s compile the code and execute it − mvn clean install java -cp target/demo-0.0.1-SNAPSHOT.jar com.example.demo.SingleInstanceHazelcastExample Output If you execute above code, the output would be − Hello World However, more importantly, you will also notice log lines from Hazelcast which signifies that Hazelcast has started. Since we are running this code only once, i.e., a single JVM, we would only have one member in our cluster. Jan 30, 2021 10:26:51 AM com.hazelcast.config.XmlConfigLocator INFO: Loading ”hazelcast-default.xml” from classpath. Jan 30, 2021 10:26:51 AM com.hazelcast.instance.AddressPicker INFO: [LOCAL] [dev] [3.12.12] Prefer IPv4 stack is true. Jan 30, 2021 10:26:52 AM com.hazelcast.instance.AddressPicker INFO: [LOCAL] [dev] [3.12.12] Picked [localhost]:5701, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5701], bind any local is true Jan 30, 2021 10:26:52 AM com.hazelcast.system … Members {size:1, ver:1} [ Member [localhost]:5701 – 9b764311-9f74-40e5-8a0a-85193bce227b this ] Jan 30, 2021 10:26:56 AM com.hazelcast.core.LifecycleService INFO: [localhost]:5701 [dev] [3.12.12] [localhost]:5701 is STARTED … You will also notice log lines from Hazelcast at the end which signifies Hazelcast was shutdown: INFO: [localhost]:5701 [dev] [3.12.12] Hazelcast Shutdown is completed in 784 ms. Jan 30, 2021 10:26:57 AM com.hazelcast.core.LifecycleService INFO: [localhost]:5701 [dev] [3.12.12] [localhost]:5701 is SHUTDOWN Cluster: Multi Instance Now, let”s create MultiInstanceHazelcastExample.java file (as below) which would be used for multi-instance cluster. package com.example.demo; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; public class MultiInstanceHazelcastExample { public static void main(String… args) throws InterruptedException{ //initialize hazelcast server/instance HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance(); //print the socket address of this member and also the size of the cluster System.out.println(String.format(“[%s]: No. of hazelcast members: %s”, hazelcast.getCluster().getLocalMember().getSocketAddress(), hazelcast.getCluster().getMembers().size())); // wait for the member to join Thread.sleep(30000); //perform a graceful shutdown hazelcast.shutdown(); } } Let’s execute the following command on two different shells − java -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.MultiInstanceHazelcastExample You would notice on the 1st shell that a Hazelcast instance has been started and a member has been assigned. Note the last line of output which says that there is a single member using port 5701. Jan 30, 2021 12:20:21 PM com.hazelcast.internal.cluster.ClusterService INFO: [localhost]:5701 [dev] [3.12.12] Members {size:1, ver:1} [ Member [localhost]:5701 – b0d5607b-47ab-47a2-b0eb-6c17c031fc2f this ] Jan 30, 2021 12:20:21 PM com.hazelcast.core.LifecycleService INFO: [localhost]:5701 [dev] [3.12.12] [localhost]:5701 is STARTED [/localhost:5701]: No. of hazelcast members: 1 You would notice on the 2nd shell that a Hazelcast instance has joined the 1st instance. Note the last line of the output which says that there are now two members using port 5702. INFO: [localhost]:5702 [dev] [3.12.12] Members {size:2, ver:2} [ Member [localhost]:5701 – b0d5607b-47ab-47a2-b0eb-6c17c031fc2f Member [localhost]:5702 – 037b5fd9-1a1e-46f2-ae59-14c7b9724ec6 this ] Jan 30, 2021 12:20:46 PM com.hazelcast.core.LifecycleService INFO: [localhost]:5702 [dev] [3.12.12] [localhost]:5702 is STARTED [/localhost:5702]: No. of hazelcast members: 2 Print Page Previous Next Advertisements ”;

Hazelcast – Introduction

Hazelcast – Introduction ”; Previous Next Distributed In-memory Data Grid A data grid is a superset to distributed cache. Distributed cache is typically used only for storing and retrieving key-value pairs which are spread across caching servers. However, a data grid, apart from supporting storage of key-value pairs, also supports other features, for example, It supports other data structures like locks, semaphores, sets, list, and queues. It provides a way to query the stored data by rich querying languages, for example, SQL. It provides a distributed execution engine which helps to operate on the data in parallel. Benefits of Hazelcast Support multiple data structures − Hazelcast supports the usage of multiple data structures along with Map. Some of the examples are Lock, Semaphore, Queue, List, etc. Fast R/W access − Given that all the data is in-memory, Hazelcast offers very high-speed data read/write access. High availability − Hazelcast supports the distribution of data across machines along with additional support for backup. This means that the data is not stored on a single machine. So, even if a machine goes down, which occurs frequently in a distributed environment, the data is not lost. High Performance − Hazelcast provides constructs which can be used to distribute the workload/computation/query among multiple worker machines. This means a computation/query uses resources from multiple machines which reduces the execution time drastically. Easy to use − Hazelcast implements and extends a lot of java.util.concurrent constructs which make it very easy to use and integrate with the code. Configuration to start using Hazelcast on a machine just involves adding the Hazelcast jar to our classpath. Hazelcast vs Other Caches & Key-Value stores Comparing Hazelcast with other caches like Ehcache, Guava, and Caffeine may not be very useful. It is because, unlike other caches, Hazelcast is a distributed cache, that is, it spreads the data across machines/JVM. Although Hazelcast can work very well on single JVM as well, however, it is more useful is a distributed environment. Similarly comparing it with Databases like MongoDB is also of not much use. This is because, Hazelcast mostly stores data in memory (although it also supports writing to disk). So, it offers high R/W speed with the limitation that data needs to be stored in memory. Hazelcast also supports caching/storing complex data types and provides an interface to query them, unlike other data stores. A comparison, however, can be made with Redis which also offers similar features. Hazelcast vs Redis In terms of features, both Redis and Hazelcast are very similar. However, following are the points where Hazelcast scores over Redis − Built for Distributed Environment from ground-up − Unlike Redis, which started as single machine cache, Hazelcast, from the very beginning, has been built for distributed environment. Simple cluster scale in/out − Maintaining a cluster where nodes are added or removed is very simple in case of Hazelcast, for example, adding a node is a matter of launching the node with the required configuration. Removing a node requires simple shutting down of the node. Hazelcast automatically handles partitioning of data, etc. Having the same setup for Redis and performing the above operation requires more precaution and manual efforts. Less resources needs to support failover − Redis follows master-slave approach. For failover, Redis requires additional resources to setup Redis Sentinel. These Sentinel nodes are responsible to elevate a slave to master if the original master node goes down. In Hazelcast, all nodes are treated equal, failure of a node is detected by other nodes. So, the case of a node going down is handled pretty transparently and that too without any additional set of monitoring servers. Simple Distributed Compute − Hazelcast, with its EntryProcessor, provides a simple interface to send the code to the data for parallel processing. This reduces data transfer over the wire. Redis also supports this, however, achieving this requires one to be aware of Lua scripting which adds additional learning curve. Print Page Previous Next Advertisements ”;

Setting up multi-node instances

Hazelcast – Setting up multi node instances ”; Previous Next Given that Hazelcast is a distributed IMDG and typically is set up on multiple machines, it requires access to the internal/external network. The most important use-case being discovery of Hazelcast nodes within a cluster. Hazelcast requires the following ports − 1 inbound port to receive pings/data from other Hazelcast nodes/clients n number of outbound ports which are required to send ping/data to other members of the cluster. This node discovery happens in few ways − Multicast TCP/IP Amazon EC2 auto discovery Of this, we will look at Multicast and TCP/IP Multicast Multicast joining mechanism is enabled by default. https://en.wikipedia.org/wiki/Multicast is a way of communication form in which message is transmitted to all the nodes in a group. And this is what Hazelcast uses to discover other members of the cluster. All the examples that we have looked at earlier use multicast to discover members. Example Let’s now explicitly turn it on. Save the following in hazelcast-multicast.xml <hazelcast xsi:schemaLocation=”http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.12.12.xsd” xmlns=”http://www.hazelcast.com/schema/config” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”> <network> <join> <multicast enabled=”true” /> </join> </network> </hazelcast> And then, let us execute the following − java -Dhazelcast.config=hazelcast-multicast.xml -cp .targetdemo-0.0.1- SNAPSHOT.jar com.example.demo.XMLConfigLoadExample Output In the output, we notice the following lines from Hazelcast which effectively means that multicast joiner is used to discover the members. Jan 30, 2021 5:26:15 PM com.hazelcast.instance.Node INFO: [localhost]:5701 [dev] [3.12.12] Creating MulticastJoiner Multicast, by default, accepts communication from all the machines in the multicast group. This may be a security concern and that is why typically, on-premise, multicast communication is firewalled. So, while multicast is good for development work, in production, it is best to use TCP/IP based discovery. TCP/IP Due to the drawbacks stated for Multicast, TCP/IP is the preferred way for communication. In case of TCP/IP, a member can connect to only known/listed members. Example Let’s use TCP/IP for discovery mechanisms. Save the following in hazelcast-tcp.xml <hazelcast xsi:schemaLocation=”http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.12.12.xsd” xmlns=”http://www.hazelcast.com/schema/config” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”> <network> <join> <multicast enabled=”false” /> <tcp-ip enabled=”true”> <members>localhost</members> </tcp-ip> </join> </network> </hazelcast> And then, let’s execute the following command − java -Dhazelcast.config=hazelcast-tcp.xml -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.XMLConfigLoadExample Output The output is following − INFO: [localhost]:5701 [dev] [3.12.12] Creating TcpIpJoiner Jan 30, 2021 8:09:29 PM com.hazelcast.spi.impl.operationexecutor.impl.OperationExecutorImpl The above output shows that TCP/IP joiner was use to join two members. And if you execute following command on two different shells − java ”-Dhazelcast.config=hazelcast-tcp.xml” -cp .targetdemo-0.0.1-SNAPSHOT.jar com.example.demo.MultiInstanceHazelcastExample We see the following output − Members {size:2, ver:2} [ Member [localhost]:5701 – 62eedeae-2701-4df0-843c-7c3655e16b0f Member [localhost]:5702 – 859c1b46-06e6-495a-8565-7320f7738dd1 this ] The above output means that the nodes were able to join using TCP/IP and both are using localhost as the IP address. Note that we can specify more IPs or the machine names (which would be resolved by DNS) in the XML configuration file. <hazelcast xsi:schemaLocation=”http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.12.12.xsd” xmlns=”http://www.hazelcast.com/schema/config” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”> <network> <join> <multicast enabled=”false” /> <tcp-ip enabled=”true”> <members>machine1, machine2….</members> </tcp-ip> </join> </network> </hazelcast> Print Page Previous Next Advertisements ”;