转载

Hazelcast 序列化

Hazelcast 非常适用于数据/查询分布在机器之间的环境。这需要将数据从我们的 Java 对象序列化为可以通过网络传输的字节数组。
Hazelcast 支持各种类型的序列化。但是,让我们看看一些常用的,即 Java Serialization 和 Java Externalizable。

Java 序列化

示例

首先让我们看看 Java 序列化。假设我们定义了一个 Employee 类,并实现了 Serializable 接口。
public class Employee implements Serializable{
   private static final long serialVersionUID = 1L;
   private String name;
   private String department;
   public Employee(String name, String department) {
      super();
      this.name = name;
      this.department = department;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getDepartment() {
      return department;
   }
   public void setDepartment(String department) {
      this.department = department;
   }
   @Override
   public String toString() {
      return "Employee [name=" + name + ", department=" + department + "]";
   }
}
现在让我们编写代码将 Employee 对象添加到 Hazelcast 地图。
public class EmployeeExample {
   public static void main(String... args){
      //initialize hazelcast server/instance
      HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
      //create a set to track employees
      Map<Employee, String> employeeOwners=hazelcast.getMap("employeeVehicleMap");
      Employee emp1 = new Employee("John Smith", "Computer Science");
      // add employee to set
      System.out.println("Serializing key-value and add to map");
      employeeOwners.put(emp1, "Honda");
      // check if emp1 is present in the set
      System.out.println("Serializing key for searching and Deserializing
      value got out of map");
      System.out.println(employeeOwners.get(emp1));
      // perform a graceful shutdown
      hazelcast.shutdown();
   }
}

输出

它将产生以下输出-
Serializing key-value and add to map
Serializing key for searching and Deserializing value got out of map
Honda
这里一个非常重要的方面是,只需实现一个 Serializable 接口,我们就可以让 Hazelcast 使用 Java Serialization。另请注意,Hazelcast 存储键和值的序列化数据,而不是像 HashMap 那样将其存储在内存中。因此,Hazelcast 完成了繁重的序列化和反序列化工作。

示例

然而,这里有一个陷阱。在上述情况下,如果员工所在的部门发生变化怎么办?这个人还是一样。
public class EmployeeExampleFailing {
   public static void main(String... args){
      //initialize hazelcast server/instance
      HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
      //create a set to track employees
      Map<Employee, String> employeeOwners=hazelcast.getMap("employeeVehicleMap");
      Employee emp1 = new Employee("John Smith", "Computer Science");
      // add employee to map
      System.out.println("Serializing key-value and add to map");
      employeeOwners.put(emp1, "Honda");
      Employee empDeptChange = new Employee("John Smith", "Electronics");
      // check if emp1 is present in the set
      System.out.println("Checking if employee with John Smith is present");
      System.out.println(employeeOwners.containsKey(empDeptChange));
      Employee empSameDept = new Employee("John Smith", "Computer Science");
      System.out.println("Checking if employee with John Smith is present");
      System.out.println(employeeOwners.containsKey(empSameDept));
      // perform a graceful shutdown
      hazelcast.shutdown();
   }
}

输出

它将产生以下输出-
Serializing key-value and add to map
Checking if employee with name John Smith is present
false
Checking if employee with name John Smith is present
true
这是因为 Hazelcast 在比较时不会反序列化密钥,即 Employee。它直接比较序列化密钥的字节码。因此,对所有属性具有相同值的对象将被同等对待。但如果这些属性的值发生变化,例如上述场景中的部门,则这两个键将被视为唯一。

Java 可外部化

如果在上面的示例中,我们在执行键的序列化/反序列化时不关心部门的值会怎样。 Hazelcast 还支持 Java Externalizable,这让我们可以控制用于序列化和反序列化的标签。

示例

让我们相应地修改我们的 Employee 类-
public class EmplyoeeExternalizable implements Externalizable {
   private static final long serialVersionUID = 1L;
   private String name;
   private String department;
   public EmplyoeeExternalizable(String name, String department) {
      super();
      this.name = name;
      this.department = department;
   }
   @Override
   public void readExternal(ObjectInput in) throws IOException,
   ClassNotFoundException {
      System.out.println("Deserializaing....");
      this.name = in.readUTF();
   }
   @Override
   public void writeExternal(ObjectOutput out) throws IOException {
      System.out.println("Serializing....");
      out.writeUTF(name);
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getDepartment() {
      return department;
   }
   public void setDepartment(String department) {
      this.department = department;
   }
   @Override
   public String toString() {
      return "Employee [name=" + name + ", department=" + department + "]";
   }
}
因此,从代码中可以看出,我们添加了负责序列化/反序列化的 readExternal/writeExternal 方法。鉴于我们在序列化/反序列化时对部门不感兴趣,我们在 readExternal/writeExternal 方法中排除了那些。

示例

现在,如果我们执行以下代码-
public class EmployeeExamplePassing {
   public static void main(String... args){
      //initialize hazelcast server/instance
      HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance();
      //create a set to track employees
      Map<EmplyoeeExternalizable, String> employeeOwners=hazelcast.getMap("employeeVehicleMap");
      EmplyoeeExternalizable emp1 = new EmplyoeeExternalizable("John Smith", "Computer Science");
      // add employee to map
      employeeOwners.put(emp1, "Honda");
      EmplyoeeExternalizable empDeptChange = new EmplyoeeExternalizable("John Smith", "Electronics");
      // check if emp1 is present in the set
      System.out.println("Checking if employee with John Smith is present");
      System.out.println(employeeOwners.containsKey(empDeptChange));
      EmplyoeeExternalizable empSameDept = new EmplyoeeExternalizable("John Smith", "Computer Science");
      System.out.println("Checking if employee with John Smith is present");
      System.out.println(employeeOwners.containsKey(empSameDept));
      // perform a graceful shutdown
      hazelcast.shutdown();
   }
}

输出

我们得到的输出是-
Serializing....
Checking if employee with John Smith is present
Serializing....
true
Checking if employee with John Smith is present
Serializing....
true
如输出所示,使用 Externalizable 接口,我们可以仅向 Hazelcast 提供员工姓名的序列化数据。
另请注意,Hazelcast 将我们的密钥序列化了两次-
  • 一旦存储密钥,
  • 第二个用于在地图中搜索给定的键。如前所述,这是因为 Hazelcast 使用序列化字节数组进行键比较。
总的来说,如果我们想更好地控制要序列化哪些属性以及如何处理它们,则使用 E​​xternalizable 与 Serializable 相比有更多好处。
正文到此结束
Loading...