Hazelcast Compact Serialization: A Comprehensive Guide

Hazelcast Compact Serialization: A Comprehensive Guide

Overview

Hazelcast, a leading in-memory data grid, offers various serialization mechanisms to boost performance and efficiency in distributed systems. Among these, Hazelcast Compact Serialization is a standout feature designed to minimize memory footprint and reduce network bandwidth consumption. As systems scale, efficient serialization becomes critical, and Hazelcast’s compact format offers a modern and optimized solution.

In this article, we explore Hazelcast’s compact serialization, detailing how it works, its advantages, and best practices for implementation.

What is Hazelcast Compact Serialization?

Serialization in Hazelcast is the process of converting an object into a byte stream for transmission or storage. Hazelcast Compact Serialization is a novel mechanism that emphasizes compactness and performance, making it more efficient than traditional Java serialization or even Hazelcast’s default serialization methods like IdentifiedDataSerializable and Portable.

Compact serialization differs in its ability to:

  • Reduce Payload Size: By minimizing the amount of metadata stored along with data.
  • Enhance Performance: Lower overhead during serialization and deserialization operations.
  • Support Schema Evolution: Manage backward and forward compatibility when object structures change over time.

Also know about Serialization and Deserialization process

Understanding Hazelcast Serialization and Deserialization: Why It Matters

Key Features of Hazelcast Compact Serialization

1. Schema-Free Serialization

Unlike Portable Serialization, which requires a predefined schema, compact serialization eliminates this requirement, allowing objects to be serialized without registering their schema upfront. This makes the process simpler and more dynamic, especially in systems where frequent changes to object structures are expected.

2. Efficient Handling of Primitive Types

Compact serialization natively supports primitive types like int, long, boolean, and float, ensuring that these types are serialized with minimal overhead. This leads to faster encoding and decoding processes, making it ideal for high-performance applications.

3. Backward and Forward Compatibility

With Compact Serialization, Hazelcast introduces schema evolution. This feature allows a system to handle changes in object structures seamlessly. If new fields are added or some are removed from a serialized object, the system can still read and process older versions, ensuring robustness during system upgrades.

4. Space Optimization

Compact serialization dramatically reduces the size of the serialized object. This space-saving approach is particularly beneficial for large-scale, distributed systems where bandwidth and storage efficiency are paramount.

Benefits of Using Hazelcast Compact Serialization

1. Improved Performance in Distributed Systems

Serialization is a crucial factor in determining the performance of distributed systems. Traditional serialization mechanisms in Java are notorious for their inefficiency and overhead. Compact serialization, however, provides a leaner and faster approach, translating directly to reduced latency in data transfer between nodes in a Hazelcast cluster.

2. Lower Network Bandwidth

Hazelcast Compact serialization significantly cuts down on the amount of data transferred between Hazelcast nodes or between clients and servers. By eliminating unnecessary metadata and optimizing the encoding of objects, compact serialization reduces the network bandwidth required for communication, making the system more scalable.

3. Simplified Object Evolution

In many distributed systems, objects evolve over time as new features are added or old ones are removed. Compact serialization’s support for schema evolution makes it easier to manage these changes without breaking compatibility or requiring heavy rewrites of serialization logic. This ensures smoother deployments and fewer runtime errors when upgrading or modifying the application.

4. Compatibility with Multiple Platforms

Hazelcast compact serialization is designed with cross-platform compatibility in mind. It allows Java objects to be serialized and then deserialized by clients written in other languages such as C++ or .NET, making it ideal for polyglot environments.

How to Implement Hazelcast Compact Serialization

Implementing compact serialization in Hazelcast is a straightforward process. Below are the steps to enable it and leverage its benefits in your application:

1. Create Compact Serializer

To enable Hazelcast compact serialization, we need to define a compact serializer for the class. Here is an example for a class Student:

package com.javatecharc.demo.model;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Student {
    private int id;
    private String name;
    private String department;

    public Student(int id, String name, String department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    //Generate Getter and Setter or use Lombok @Getter, @Setter
}

Next, we define a compact serializer StudentCompactSerializer for this class:

package com.javatecharc.demo.compact.serializer;

import com.hazelcast.nio.serialization.compact.CompactReader;
import com.hazelcast.nio.serialization.compact.CompactSerializer;
import com.hazelcast.nio.serialization.compact.CompactWriter;
import com.javatecharc.demo.model.Student;

public class StudentCompactSerializer implements CompactSerializer<Student> {
    @Override
    public Student read(CompactReader compactReader) {
        int id = (int) compactReader.readInt64("id");
        String name = compactReader.readString("name");
        String department = compactReader.readString("department");
        return new Student(id, name, department);
    }

    @Override
    public void write(CompactWriter writer, Student student) {
        writer.writeInt64("id", student.getId());
        writer.writeString("name", student.getName());
        writer.writeString("department", student.getDepartment());
    }

    @Override
    public String getTypeName() {
        return "Student";
    }

    @Override
    public Class<Student> getCompactClass() {
        return Student.class;
    }
}

2. Register the Serializer with Hazelcast

After defining the serializer, it needs to be registered with the Hazelcast configuration by Config programmatic or hazelcast.xml config. Here’s how to configure it:

Programmatic Configuration:

Register the class into Config object by using addClass(Student.class) or addSerializer(new StudentCompactSerializer())

Config config = new Config();
config.getSerializationConfig()
       .getCompactSerializationConfig()
       .addSerializer(new StudentCompactSerializer());
HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config);

Declarative Configuration:

Declare the StudentCompactSerializer class in to hazelcast.xml configuration.

<hazelcast>
    <serialization>
        <compact-serialization>
            <classes>
                <class>
                    com.javatecharc.demo.compact.serializer.StudentCompactSerializer
                </class>
            </classes>
        </compact-serialization>
    </serialization>
</hazelcast>

3. Using Compact Serialization in Maps

Now, when you store objects in Hazelcast’s distributed Map, the compact serialization will be applied automatically:

package com.javatecharc.demo.compact.serializer;

import com.hazelcast.config.Config;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.javatecharc.demo.model.Student;

public class HazelcastCompactSerializerExample {
    public static void main(String[] args) {
        Config config = new Config();
        config.getSerializationConfig().getCompactSerializationConfig()
                .addSerializer(new StudentCompactSerializer());
        HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(config);

        IMap<Integer, Student> studentMap = hazelcastInstance.getMap("students");

        studentMap.put(101, new Student(101, "Sachin", "Java Tech ARC"));

        Student student = studentMap.get(101);
        System.out.println(student.getName());

        hazelcastInstance.shutdown();
    }
}

In this example, when an Student object is stored in the map, it is serialized using the compact format, reducing the memory footprint and enhancing performance.

Best Practices for Compact Serialization

1. Use Compact Serialization for Large Datasets

If your Hazelcast cluster handles large datasets or frequently communicates between nodes, compact serialization can drastically reduce the overhead of transferring data. This can improve the system’s responsiveness, especially under high-load conditions.

2. Test Schema Evolution Carefully

While compact serialization supports schema evolution, it is important to test thoroughly when adding or removing fields from serialized objects. In particular, ensure that changes are backward-compatible and that the application can gracefully handle older object versions.

3. Optimize Primitive Data Handling

Where possible, prefer using primitive data types in your serialized objects. Compact serialization handles primitive types more efficiently, which leads to faster serialization/deserialization and smaller serialized objects.

Conclusion

Hazelcast’s Compact Serialization is a powerful tool for optimizing data transfer and storage in distributed systems. By offering a schema-free, compact, and efficient approach to serialization, it greatly enhances the performance of Hazelcast applications. Its support for schema evolution and compatibility with multiple platforms further solidifies its position as an essential feature for modern distributed environments.

The sample code available over the github.

Happy Coding! 😊

Leave a Comment

Your email address will not be published. Required fields are marked *

Index
Scroll to Top