RedisTemplate 中序列化方式辨析

在Spring Data Redis中,RedisTemplate 是操作Redis的核心類,它提供了豐富的API來與Redis進行交互。由于Redis是一個鍵值存儲系統,它存儲的是字節序列,因此在使用RedisTemplate時,需要指定鍵(Key)和值(Value)的序列化方式。不同的序列化方式適用于不同的場景。下面將詳細介紹幾種序列化方法。

序列化如下對象

User 類

public class User implements Serializable {String name;String ID;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", ID='" + ID + '\'' +'}';}public User(String name, String ID) {this.name = name;this.ID = ID;}public User() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getID() {return ID;}public void setID(String ID) {this.ID = ID;}
}

JdkSerializationRedisSerializer

JdkSerializationRedisSerializer 是使用JDK自帶的序列化機制(ObjectOutputStream 和 ObjectInputStream)來序列化和反序列化POJO對象。這種序列化方式會將對象轉換成字節序列,并存儲在Redis中。這是RedisTemplate中默認的序列化策略之一(但通常不是推薦用于生產環境的默認策略,因為JDK序列化通常效率較低且生成的字節序列較大)。最大的缺點就是:要求序列化的對象要求繼承Serializable類,這是DTO無法容忍的一個要求。

優點:
  • 與其他兩個比幾乎沒有優點,超級不推薦!
缺點:
  • 二進制形式存儲,不利于查看!94 bytes
  • 序列化生成的字節序列較大,導致網絡傳輸和存儲成本較高。
  • 序列化速度慢。
  • 序列化的字節序列是私有的,不便于跨語言或跨平臺共享。
代碼示例
@Testpublic void test4(){User user = new User("李白","123456");//        GenericToStringSerializer<Object> genericToStringSerializer = new GenericToStringSerializer<>(Object.class);
//        redisTemplate.setKeySerializer(genericToStringSerializer);
//        JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
//        redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.java());// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test4",user);User user2 = (User)redisTemplate.opsForValue().get("test4");logger.info(user2.toString());// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");}

在這里插入圖片描述

StringRedisSerializer

StringRedisSerializer 是最簡單的序列化器,它直接將字符串(或任何可以轉換為字符串的數據)作為字節序列存儲,不需要進行任何特殊的序列化操作。它適用于鍵或值為字符串的場景。

優點:
  • 效率高,不需要額外的序列化/反序列化開銷。
  • 易于理解和維護。
缺點:
  • 只能用于字符串數據。

Jackson2JsonRedisSerializer

Jackson2JsonRedisSerializer 是基于Jackson庫實現的JSON序列化器,它可以將Java對象序列化成JSON格式的字符串,并存儲在Redis中。Jackson是一個流行的JSON處理庫,提供了豐富的API來序列化和反序列化Java對象。

優點:
  • User 對象不需要實現 Serializable接口。
  • 生成的JSON格式易于閱讀和調試。
  • 序列化后的數據相對較小,傳輸和存儲效率較高,64 bytes。
  • 支持復雜的Java對象,包括嵌套對象和集合。
@Test
public void test3(){User user = new User("李白","123456");redisTemplate.setKeySerializer(RedisSerializer.string());
//        Jackson2JsonRedisSerializer<User> userJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(User.class);
//        redisTemplate.setValueSerializer(userJackson2JsonRedisSerializer);redisTemplate.setValueSerializer(RedisSerializer.json());// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test3",user);User user2 = (User)redisTemplate.opsForValue().get("test3");logger.info(user2.toString());// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");
}

在這里插入圖片描述

GenericFastJsonRedisSerializer

GenericFastJsonRedisSerializer 是基于Fastjson庫實現的JSON序列化器,與JacksonJsonRedisSerializer類似,但它使用的是Fastjson庫。Fastjson是另一個流行的JSON處理庫,以其高性能著稱。

優點:
  • 序列化性能高。
  • 支持復雜的Java對象。
  • 生成的JSON格式易于閱讀和調試。
缺點:
  • 可能存在安全漏洞(歷史版本中曾發現過安全問題,使用時需注意版本),據測試,FastJson性能不能完全超過Json庫,建議生產中別用!。
    @Testpublic void test5(){User user = new User("杜甫","123456");redisTemplate.setKeySerializer(RedisSerializer.string());GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test5",user);User user2 = (User)redisTemplate.opsForValue().get("test5");logger.info(user2.toString());// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");}

在這里插入圖片描述

總結

  • 可讀性:JacksonJsonRedisSerializerGenericFastJsonRedisSerializer 皆可
  • 內存占用:GenericFastJsonRedisSerializer 59 bytes 小于 JacksonJsonRedisSerializer 60 bytes 小于 JdkSerializationRedisSerializer 94 bytes。
  • 耗時:JacksonJsonRedisSerializerGenericFastJsonRedisSerializer 差不多 且 都比 JdkSerializationRedisSerializer

生產環境中,無腦選擇JacksonJsonRedisSerializer即可!

總的來說,在選擇序列化器時,應根據具體的應用場景和需求來決定使用哪種序列化方式。對于大多數基于Spring Boot和Spring Data Redis的項目,推薦使用JacksonJsonRedisSerializer 來序列化和反序列化Java對象,因為它們提供了靈活性和高性能。

嵌套對象測試

    public Map<String, List<User>> getNestedObj(){ArrayList<User> users = new ArrayList<>();for (int i = 0; i < 100; i++) {users.add(new User(UUID.randomUUID().toString().substring(0,8),UUID.randomUUID().toString()));}HashMap<String, List<User>> nestedObj = new HashMap<>();nestedObj.put("one",users);return nestedObj;}

JdkSerializationRedisSerializer

    @Testpublic void test11(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.java());// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test11",nestedObj);// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 從redis獲取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test11");logger.info(nestedObj2.toString());}

在這里插入圖片描述

JacksonJsonRedisSerializer

    @Testpublic void test12(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setValueSerializer(RedisSerializer.json());// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test12",nestedObj);// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 從redis獲取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test12");logger.info(nestedObj2.toString());}

在這里插入圖片描述

GenericFastJsonRedisSerializer

 @Testpublic void test13(){Map<String, List<User>> nestedObj = getNestedObj();redisTemplate.setKeySerializer(RedisSerializer.string());GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();redisTemplate.setValueSerializer(genericFastJsonRedisSerializer);// 記錄開始時間Instant start = Instant.now();redisTemplate.opsForValue().set("test13",nestedObj);// 記錄結束時間Instant end = Instant.now();// 計算運行時間long duration = Duration.between(start, end).toMillis();logger.info(duration+"ms");// 從redis獲取nestedObj并反序列化Map<String, List<User>> nestedObj2 = (Map<String, List<User>>)redisTemplate.opsForValue().get("test13");logger.info(nestedObj2.toString());}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45028.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45028.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45028.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

力扣題解( 等差數列劃分 II - 子序列)

446. 等差數列劃分 II - 子序列 給你一個整數數組 nums &#xff0c;返回 nums 中所有 等差子序列 的數目。 如果一個序列中 至少有三個元素 &#xff0c;并且任意兩個相鄰元素之差相同&#xff0c;則稱該序列為等差序列。 例如&#xff0c;[1, 3, 5, 7, 9]、[7, 7, 7, 7] 和…

Netgear WN604 downloadFile.php 信息泄露漏洞復現(CVE-2024-6646)

0x01 產品簡介 NETGEAR WN604是一款由NETGEAR(網件)公司生產的無線接入器(或無線路由器)提供Wi-Fi保護協議(WPA2-PSK, WPA-PSK),以及有線等效加密(WEP)64位、128位和152位支持,保障網絡安全。同時支持MAC地址認證、802.1x RADIUS以及EAP TLS、TTLS、PEAP等安全機制,…

Flat Ads:金融APP海外廣告投放素材的優化指南

在當今全球化的數字營銷環境中,金融APP的海外營銷推廣已成為眾多金融機構與開發者最為關注的環節之一。面對不同地域、文化及用戶習慣的挑戰,如何優化廣告素材,以吸引目標受眾的注意并促成有效轉化,成為了廣告主們亟待解決的問題。 作為領先的全球化營銷推廣平臺,Flat Ads憑借…

超簡易高效的 AI繪圖工具—與sd-webui一致界面,6G顯存最高提升75%出圖速率!(附安裝包)

大家好&#xff0c;我是靈魂畫師向陽 今天給大家分享一個基于Stable Diffusion WebUI 構建的AI繪圖工具—sd-webui-forge&#xff0c;該工具的目標在于簡化插件開發&#xff0c;優化資源管理&#xff0c;加速推理。 Forge承諾永遠不會對Stable Diffusion WebUI用戶界面添加不…

獲獎案例回顧|基于衛星遙感和無人機的水稻全流程風險減量項目

引言 在現代農業保險領域&#xff0c;技術創新是推動行業進步的關鍵。珈和科技與太平財險的合作&#xff0c;旨在利用先進的衛星遙感和無人機技術&#xff0c;解決傳統農業保險面臨的諸多挑戰&#xff0c;從而提升保險效率和服務質量。本次分享的項目案例獲得了《金融電子化》…

啟動yarn后,其他節點沒有NodeManager

寫在前面&#xff1a; 這個問題雖然折磨了我兩天&#xff0c;但是原因特別蠢&#xff0c;可能與各位不一定一樣&#xff0c;我是因為ResourceManager的節點的"/etc/hadoop/workers"文件沒有配置好&#xff08;沒有配hadoop102和hadoop104&#xff09;&#xff0c;但排…

數字圖像處理(實踐篇)四十八 PCA主成分分析降維與圖像重建

目錄 一 PCA 二 實踐 實踐① 實踐② 一 PCA 主成分分析(PCA)是一種常見的數據分析技術,它可以用于降維和特征提取。 PCA 的作用包括以下幾個方面: ①數據降維:PCA 可以將高維數據降維到低維空間中,從而方便后續的數據分析和可視化。可以將具有多個變量的數據集降維…

P1850換教室 題解(概率dp)

題目&#xff1a;https://www.luogu.com.cn/problem/P1850 思路&#xff1a; 概率dp,如果要求最小路徑期望&#xff0c;我們要確定的有選了幾節課&#xff0c;申請換了幾節課&#xff0c;最后一節是否申請換課&#xff08;下一次選課要知道上一次選課申請情況&#xff09;。 …

小白學webgl合集-三維數據源和格式

大多數地圖瓦片數據是二維的&#xff0c;三維效果通過渲染和樣式設置實現。主要的三維數據源和格式包括&#xff1a; 1. 3D Tiles (CesiumJS) 3D Tiles 是一種開放標準&#xff0c;用于流式傳輸和可視化大規模三維地理數據。它可以包含各種三維數據&#xff0c;如建筑物、點云…

循環結構(二)——while語句【互三互三】

文章目錄 &#x1f341;引言 &#x1f341;一、語句格式 &#x1f341;二、語句執行過程 &#x1f341;三、格式舉例 &#x1f341;四、例題 &#x1f449;【例1】 &#x1f48e;【示例代碼】 &#x1f449;【例2】 &#x1f680;【方法1】&#xff1a; &#x1f48e…

運維的操作紅線

1. 無工單、郵件的任何操作&#xff0c;嚴禁執行。 2. 工單標題和內容不一致或工單內容超出現場范圍禁止操作。 3. 操作前必須確定資產信息&#xff1a;機柜號、U位、資產號、sn 號、ip。 4. 機柜后門操作設備&#xff0c;必須多次執行第 3 條紅線。 5. 嚴禁操作、觸碰工單指定…

【Java伴學筆記】Day-02 變量|計算機的存儲方式|數據類型|標識符|鍵盤輸入流

一、變量 在Java中&#xff0c;變量用于存儲數據值&#xff0c;可以是數字、文本或其他類型的信息。Java中的變量必須聲明后才能使用&#xff0c;并且每個變量都有特定的類型。下面是一些基本的變量使用示例&#xff1a; 聲明一個整型變量并賦值&#xff1a; int myNumber; …

企業如何選擇渲染農場?渲染100邀請碼1a12

渲染農場能降低企業成本&#xff0c;幫助企業更好的服務客戶&#xff0c;那么如何選擇渲染農場呢&#xff1f;又有什么標準&#xff1f;這次我們就來看下。 1、渲染性能 渲染性能是衡量農場優劣的重要指標&#xff0c;性能越好農場越優質&#xff0c;性能主要包括渲染速度、穩…

一文快速接入銀行卡識別API

銀行卡識別API 能通過機器學習和圖像識別技術來解析銀行卡相關信息&#xff0c;根據用戶上傳卡片自動識別內容&#xff0c;返回該卡的卡號、所屬銀行及銀行類型等信息。可以在用戶需要輸入銀行卡等相關信息時使用該功能&#xff0c;幫助用戶快速輸入正確信息&#xff0c;簡化用…

VPX3U架構+GPU景嘉微:基于飛騰處理器的全國產化刀片式板卡

近期承接了客戶一個全國產的VPX3U的項目。搭載的飛騰FT2000系列處理器的VPX3U板卡。服務于某某部門。這款產品擁有全國產化及自主可控的硬件技術。以下是基于飛騰FT2000處理器的VPX3U主板的一些特點&#xff1a; ①飛騰FT2000系列處理器 處理器&#xff1a;板卡兼容飛騰FT2000…

【觸摸屏】【紅十字會學習系統】功能模塊:視頻 + AI拍照合成

項目背景 提升公眾急救能力&#xff1a;確保每個人都能在緊急情況下采取正確的急救措施&#xff0c;減少傷害&#xff0c;挽救生命。培養人道主義價值觀&#xff1a;通過教育和培訓&#xff0c;傳播紅十字精神&#xff0c;促進社會對弱勢群體的關注與支持。建立社區響應網絡&a…

java同步塊介紹

在多線程編程中,同步塊(synchronized block)用于保護代碼塊,使得同一時間只有一個線程能夠執行該代碼塊,從而避免并發問題。同步塊使用一個對象作為鎖,確保在同步塊內對共享資源的訪問是線程安全的。 1. 什么是同步塊? 同步塊是 Java 中的一種同步機制,用于保護代碼塊…

【Linux】進程間通信(IPC)——匿名管道

目錄 為什么要進行進程間通信&#xff1f; 匿名管道的具體實現 pipe創建內存級文件形成管道 pipe的簡單使用 匿名管道的四種情況和五種特性 四種情況 五種特性 PIPE_BUF 命令行管道 | 功能代碼&#xff1a;創建進程池 為什么要進行進程間通信&#xff1f; 1.數據傳輸&…

第五天安全筆記(持續更新)

第五天防御筆記 NAT種類&#xff1a; 靜態NAT動態NATNapt 特點&#xff1a; 一對多----easy ip 多對多的napt 服務器的映射關系: 1.源NAT----基于IP地址進行轉換&#xff0c;包括靜態NAT&#xff0c;動態NAT&#xff0c;以及NAPT 2.目標NAT---基于目標IP地址進行轉換&a…

[筆記.AI]AI Agent理解(LLM AI Agent)

前幾天看到一個圖&#xff0c;感覺能幫助理解 AI Agent 的基本思想和原理&#xff0c;特摘過來備忘。順道加上自己目前對相關部分的理解&#xff0c;不一定對&#xff0c;權當做個記錄。 另外&#xff0c;專門查了下圖的來源&#xff0c;應該是源自 Lilian Weng 的博客文章《…