
- Hazelcast 教程
- Hazelcast - 首頁
- Hazelcast - 簡介
- Hazelcast - 設定
- Hazelcast - 第一個應用程式
- Hazelcast - 配置
- 設定多節點例項
- Hazelcast - 資料結構
- Hazelcast - 客戶端
- Hazelcast - 序列化
- Hazelcast 高階特性
- Hazelcast - Spring 整合
- Hazelcast - 監控
- Map Reduce & 聚合
- Hazelcast - 集合監聽器
- 常見問題 & 效能技巧
- Hazelcast 有用資源
- Hazelcast - 快速指南
- Hazelcast - 有用資源
- Hazelcast - 討論
Hazelcast - 序列化
Hazelcast 理想應用於資料/查詢分佈在多臺機器的環境中。這需要將我們的 Java 物件序列化為可在網路上傳輸的位元組陣列。
Hazelcast 支援多種型別的序列化。但是,讓我們來看一些常用的序列化方式,即 Java 序列化和 Java Externalizable。
Java 序列化
示例
首先讓我們來看 Java 序列化。假設我們定義一個實現了 Serializable 介面的 Employee 類。
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 map 中。
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 序列化。還要注意,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 Externalizable
如果在上面的例子中,我們在執行鍵的序列化/反序列化時不關心部門的值怎麼辦?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 會對我們的鍵進行兩次序列化:
一次在儲存鍵時,
第二次是在 map 中搜索給定鍵時。如前所述,這是因為 Hazelcast 使用序列化位元組陣列進行鍵比較。
總的來說,如果我們想要更好地控制要序列化的屬性以及如何處理它們,與 Serializable 相比,使用 Externalizable 的好處更多。