BufferedImageImageIO.write 輸出到 ByteArrayOutputStreamBASE64Encoder.encode() → StringSET key base64_stringBASE64Decoder.decode() → 字節數組 → 寫文件/返回前端public static String encodeImgageToBase64(URL imageUrl) { ... }
public static void decodeBase64ToImage(String base64, String path, String imgName) { ... }

| 優點 | 缺點 |
|---|---|
純文本,可直接嵌入 HTML/JSON (data:image/jpg;base64,...) | 體積膨脹 33%(Base64 編碼開銷) |
| 無需額外存儲服務,數據自包含 | Redis 內存佔用大,大圖片極易撐爆內存 |
| 跨系統傳輸無編碼困擾 | 獲取需完整解碼,不支持範圍讀取/流式傳輸 |
# 圖片存對象存儲 (S3/MinIO/OSS) 或 CDN SET img:1001 "https://cdn.example.com/images/1001.jpg" # 或本地路徑 SET img:1001 "/data/images/1001.jpg"
public class Person implements Serializable { ... }
// 序列化工具
public static byte[] serialize(Object obj) { ... }
public static Object unserialize(byte[] bytes) { ... }
// Redis 存取
jedis.set("person:100".getBytes(), serialize(new Person(100, "zhangsan")));
Person p = (Person) unserialize(jedis.get("person:100".getBytes()));

| 優點 | 缺點 |
|---|---|
| 完整保留對象圖、類型信息、方法行為 | Java 專有,跨語言不可用(Python/Go 無法反序列化) |
| 開發便利,直接操作對象 | 序列化版本演進困難(serialVersionUID、字段增減) |
| 支持任意複雜對象圖 | 二進制不可讀、調試困難、內存碎片化 |
# 讀取文件字節數組
byte[] imgBytes = Files.readAllBytes(Paths.get("/path/img.jpg"));
# 存儲
jedis.set("img:1001".getBytes(), imgBytes);
# 讀取
byte[] data = jedis.get("img:1001".getBytes());
GETRANGE 範圍讀取(大文件分片下載)。LFU/LRU 淘汰策略,配合 maxmemory 防止 OOM。| 場景 | 推薦方案 | 關鍵理由 |
|---|---|---|
| 小圖標/驗證碼/嵌入 HTML | Base64 字符串 | 前端直用、無額外請求 |
| 業務圖片/用戶頭像/文檔 | 對象存儲 + Redis 存 URL | CDN 加速、存儲解耦、成本優 |
| 緩存熱點圖片二進制(毫秒級訪問) | Redis 直接存字節數組 | 極致性能、支持範圍讀取 |
| 複雜對象緩存(Java 單體) | JSON 序列化 | 跨語言、可讀、版本友好 |
| 內部 RPC 傳遞對象 | Protobuf/Kryo/FST | 高性能、Schema 演進、跨語言 |
maxmemory-policy allkeys-lfu,自動保護熱點數據。「把對的數據放在對的存儲」是分布式系統設計的鐵律,Redis 作為高速緩存層,職責是「快」,而非「大而全」。