Redis的Java客戶端
- Jedis
- 以 Redis 命令作為方法名稱,學習成本低,簡單實用。
- Jedis 是線程不安全的,并且頻繁的創建和銷毀連接會有性能損耗,因此推薦使用 Jedis 連接池代替Jedis的直連方式。
- lettuce
- Lettuce是基于Netty實現的,支持同步、異步和響應式編程方式,并且是線程安全的。支持Redis的哨兵模式、集群模式和管道模式。
- Redisson
- Redisson是一個基于Redis實現的分布式、可伸縮的Java數據結構集合。包含了諸如Map、Queue、Lock、Semaphore、AtomicLong等強大功能。
SpringDataRedis
- 定義:SpringData是Spring中數據操作的模塊,包含對各種數據庫的集成,其中對Redis的集成模塊就叫做SpringDataRedis。
- 特點:
- 提供了對不同 Redis 客戶端的整合(Lettuce和 Jedis)。
- 提供了 RedisTemplate 統一API來操作Redis。
- 支持Redis的發布訂閱模型。
- 支持Redis哨兵和Redis集群。
- 支持基于Lettuce的響應式編程。
- 支持基于JDK、JSON、字符串、Spring對象的數據序列化及反序列化。
- 支持基于Redis的JDKcollection實現。
RedisTemplate
- SpringDataRedis中提供了RedisTemplate工具類,其中封裝了各種對Redis的操作。并且將不同數據類型的操作API封裝到了不同的類型中:
序列化方式
- RedisTemplate 可以接收任意 Object 作為值寫入Redis,只不過寫入前會把 Obiect 序列化為字節形式,默認是采用JDK序列化,得到的結果如下,可讀性差,內存占用較大。
- 可以自己定義序列化方式:
- 為了在反序列化時知道對象的類型,JSON序列化器會將類的class類型寫入json結果中并存入Redis,會帶來額外的內存開銷。為了節省內存空間,我們并不會使用JSON序列化器來處理valuje,而是統一使用String序列化器,要求只能存儲String類型的key和value。當需要存儲java對象時,手動完成對象的序列化和反序列化。Spring默認提供了一個StringRedisTemplate類,它的key和value的序列化方式默認就是String方式,省去了我們自定義RedisTemplate的過程:
有狀態 & 無狀態
- 有狀態(Stateful)和無狀態(Stateless)是計算機領域中描述系統或協議是否依賴“狀態信息”的核心概念,尤其在 Web 開發和 API 設計中至關重要。以下是通俗易懂的解釋和對比:
有狀態
- 定義:服務器端會保存客戶端的狀態信息(如用戶身份、臨時數據),每個請求的處理需要依賴之前請求的上下文。
- 典型場景:用戶登錄、購物車、多步驟表單等需要跟蹤用戶行為的場景。
- 特點:
- 依賴服務器存儲:用戶的狀態信息(如登錄狀態、購物車數據)存儲在服務器內存、數據庫或緩存(如 Redis)中。
- 請求關聯性:客戶端每次請求需攜帶標識(如 Session ID),服務器需通過標識查找對應的狀態數據。
- 優點:
- 精準控制:服務端可隨時修改或銷毀狀態(如強制用戶退出)。
- 安全性高:敏感數據(如權限)不暴露給客戶端。
- 缺點:
- 擴展性差:集群部署時需同步狀態(如 Redis 共享 Session)。
- 資源占用:高并發時大量狀態存儲會增加服務器壓力。
無狀態
- 定義:服務器不保存客戶端的狀態信息,每個請求獨立且自包含(無需依賴之前的請求)。
- 典型場景:RESTful API、微服務通信、跨域接口等分布式場景。
- 特點:
- 客戶端攜帶完整信息:每次請求需附帶所有必要信息(如 JWT 令牌),服務器直接解析無需查詢存儲。
- 請求獨立性:服務器處理請求時不依賴歷史記錄。
- 優點:
- 擴展性強:無需共享狀態,天然支持分布式和橫向擴展。
- 性能高:省去了服務端查詢狀態的步驟。
- 缺點:
- 令牌管理復雜:無法直接撤銷令牌(需黑名單或短有效期)。
- 數據暴露風險:令牌內容可被解碼(需避免存儲敏感信息)。
通俗類比:去餐廳消費。
- 有狀態:你告訴服務員手機號(Session ID),服務員根據號碼查詢會員信息(服務端存儲的狀態,每次消費需報手機號)。
- 無狀態:你直接給服務員一張會員卡(JWT),卡里已包含身份信息、余額、有效期等信息(自包含狀態,服務員無需查系統,直接讀卡即可完成交易)。