何時是採用 Redis 的正確時機?

作者 쉬었음.com

當您非常頻繁地讀取相同資料、需要快速且原子化地處理短生命週期的共享狀態,並且能明確控制部分資料的暫時遺失或新鮮度延遲時,Redis 最為合適。常見範例包括高頻查詢 API 的快取、登入工作階段、速率限制、排行榜、暫時性權杖,以及即時事件處理。反之,若所有資料都必須永久保存,且複雜關聯式查詢、稽核軌跡和強一致性是核心需求,Redis 通常不適合作為主要資料庫的首選。

關鍵不在於僅將 Redis 視為「快速資料庫」。Redis 是以記憶體為核心的資料儲存系統,提供多種資料結構,包括字串、雜湊、集合、有序集合與 Streams,並可對其進行原子操作。因此,是否採用 Redis 的決策,不應從平均回應時間是否緩慢開始,而應先回答三個問題:哪些狀態必須保留多久、多少請求會同時變更它,以及發生故障時哪些資料可以遺失? Redis 可扮演快取、文件與向量資料、串流及訊息傳遞等多種角色,但每種角色都需要不同的設計。Redis Open Source 소개 (redis.io)

截至 2026 年 9 月 11 日,在評估是否採用 Redis 時,比起問「Redis 能不能做到這件事?」,更精確的問題是:「Redis 要解決的瓶頸,是否能透過以記憶體為基礎的共享狀態與資料結構操作來處理?」

首先要回答的問題:沒有 Redis 時,實際發生了什麼問題?

Redis 並不是能讓每個應用程式問題都變快的元件。採用它的最佳理由,是存在可觀察到的瓶頸或功能需求,而且該需求直接符合 Redis 的特性。

若以下模式反覆出現,Redis 可能是候選方案:

  • 相同的產品資訊、公開使用者個人檔案、設定值或 API 回應,會在短時間內被重複讀取數百或數千次。
  • 多個應用程式執行個體必須讀取及更新生命週期有限的資料,例如登入狀態、密碼重設權杖或暫時的購物車狀態。
  • 有許多必須避免競態條件的小型操作,例如「每分鐘 100 個請求」、「庫存至少還有一件時才保留」,或「按讚數恰好加一」。
  • 您需要快速處理用於排名、優先順序、最近活動或去重的集合、分數或計數器。
  • 在針對非同步工作或事件消費導入獨立的大型訊息代理之前,您需要運作一個要求保留、重新處理及消費者群組的中等規模流程。

反之,若資料庫緩慢的原因是低效率 SQL、缺少索引、回應內容過大、遠端服務呼叫,或應用程式層級的 N+1 查詢,Redis 可能只是在遮掩症狀,而非排除根因。例如,若產品搜尋因不合理的 JOIN 與全表掃描而花費 800 ms,對快取命中率低的新搜尋詞而言,問題依舊存在。此時應先改善查詢與索引。

讓 Redis 適合您的五項條件是什麼?

最實際的判斷方式,是查看以下五項條件中是否有多項同時成立。尤其在前三項適用時,Redis 很可能會展現明確效益。

1. 讀取重複使用率高嗎,而且來源查詢成本高嗎?

Redis 能有效降低對具有相同或相似鍵之資料的重複讀取負載。例如,最熱門 1,000 項產品的顯示資訊,如價格與庫存狀態、頻繁呼叫的匯率 API 回應,以及權限很少變更的公開個人檔案,未必需要每次請求都從來源資料庫取得。

在 cache-aside 模式中,應用程式會先查詢 Redis。若值存在,就直接回傳該值;只有快取未命中時,才讀取來源資料庫並將結果存入 Redis。由於此方法只快取實際被請求的資料,因此可讓您將記憶體集中在活躍工作集,而非整個資料集。Redis 文件建議,當您需要以低延遲提供重複讀取,並降低來源資料庫過載時,使用 cache-aside。Redis 캐시 어사이드(Cache-Aside) 사용 사례 (redis.io)

當重複使用率低時,結果就不同。若每次請求都查詢完全不同的鍵,Redis 會增加網路往返、序列化和記憶體成本,卻幾乎無法減少來源讀取。在採用前,請不要只看平均回應時間,而應檢視下列指標:

  • 熱門鍵或 API 路由占總流量的比例
  • 相同鍵重複讀取之間的間隔
  • 來源查詢的 P95 與 P99 延遲,以及資料庫 CPU 與連線集區使用率
  • 預期快取命中率,以及快取未命中時的來源負載
  • 值的變更頻率與可接受的新鮮度延遲

2. 資料是否具有自然的到期時間?

Redis 可輕鬆為每個鍵設定 TTL(Time To Live,存活時間),因此特別適合「此資料在一定時間後可以消失」的商業規則。範例包括登入工作階段、一次性驗證碼、電子郵件驗證連結、請求去重鍵、預約流程中的暫時鎖定,以及短期推薦結果。

例如,發出密碼重設權杖時,您可以在 password-reset:{token} 儲存使用者 ID,並設定 15 分鐘 TTL。時間一過,權杖就會自動失效。這可能比透過獨立批次工作清理過期資料列的設計更簡單,而且到期本身會成為安全政策的一部分。

但是,僅僅存在 TTL 並不代表設計安全。TTL 管理的是「某件事何時消失」;它不保證消失後業務仍能正常運作。例如,若 Redis 中的購物車狀態遺失,使用者或許可以重新加入商品,但已完成的付款紀錄絕不能消失。這項差異決定 Redis 應是輔助儲存,還是事實來源系統。

3. 您是否需要以原子方式更新小型共享狀態?

當多台伺服器同時讀取及修改同一個值時,只靠應用程式程式碼很難維持正確性。Redis 的資料結構與原子命令能簡化這些問題。

例如,API 速率限制需要計算每位使用者的請求數,並在超過限制後封鎖請求。當多台 Web 伺服器同時處理請求時,傳統的讀取、遞增、寫入流程可能產生競態條件。在 Redis 中,計數器、到期時間與指令碼可結合成單一一致的操作。Redis 官方使用案例也將權杖桶速率限制與以 TTL 為基礎的工作階段儲存列為代表性模式。Redis 사용 사례 목록 (redis.io)

另一個例子是暫時保留數量有限的優惠券。「檢查剩餘數量 → 減一 → 記錄每位使用者的保留」這些步驟之間不得被中斷。Redis 交易會執行一連串命令,而不讓其他用戶端命令穿插其中,並提供 MULTIEXECWATCH。這不代表它能取代每一種關聯式資料庫約束、複雜回復或長時間交易。Redis 트랜잭션 문서 (redis.io)

4. 問題的形狀是否直接符合某種 Redis 資料結構?

Redis 更接近資料結構伺服器,而非單純的鍵值快取。您的資料形狀與所需操作越吻合,應用程式中需要撰寫的複雜查詢、排序及並行控制程式碼就越少。

業務需求適合的資料結構或功能Redis 適合的原因
查詢結果的暫時儲存String、Hash、JSON、TTL以鍵為基礎的重複讀取與個別到期時間很明確。
登入與驗證狀態Hash 或 String、TTL多個執行個體共享狀態,且需要自動到期。
按讚數、瀏覽數及配額Counter、Bitmap、Hash遞增、遞減與位元操作可原子化處理。
即時排名與優先順序Sorted Set依分數排序及範圍查詢符合核心需求。
標籤、權限群組與去重Set需要成員資格判斷與聯集、交集等集合操作。
事件紀錄與消費者處理Streams需要順序、保留期限、消費者群組與重新處理。
近似彙總HyperLogLog 與 Bloom filter 等機率型資料結構可接受以部分準確度換取記憶體效率。

例如,與其在每次請求時都對關聯式資料表進行彙總及排序以取得「前 100 名分數與我的排名」,您可以在分數變更時更新有序集合,並從中查詢範圍與排名。此設計運用了 Redis 的強項。反之,若客戶、訂單、產品及稅務規則必須跨多張資料表 JOIN,並在複雜條件下接受稽核,關聯式模型的優勢可能比資料結構適配性更重要。Redis 提供字串、雜湊、集合、有序集合、Streams、時間序列和向量集合等多種類型,每一種類型在效能、記憶體與功能上都有不同取捨。Redis 데이터 타입 비교 (redis.io)

5. 您能說明故障時可能遺失什麼,以及如何復原嗎?

這是區分能採用 Redis 的組織與尚未準備好的組織之間最重要的問題。Redis 支援多種儲存策略,包括 RDB 快照、AOF(Append Only File,只附加檔案)、兩者的組合,以及不持久化。但啟用持久化不代表每次寫入在所有故障情境下都不會遺失。復原點與復原時間會因快照間隔、AOF 設定、複寫延遲、故障切換方法及維運程序而異。Redis 영속성(RDB 및 AOF) (redis.io)

在採用前,您應能完成下列句子:

「若 Redis 重新啟動或進行故障切換,部分最近的狀態可能會消失。此時,此服務將從來源重新計算什麼、要求使用者重試什麼,以及絕不僅依 Redis 完成什麼。」

若您能具體寫下這段說明,Redis 很可能適合您。若不能,請先定義資料所有權邊界。

何時採用快取最合適?

採用 Redis 最典型的時機是:來源資料庫上的讀取負載限制了服務的可擴展性,但回應中的部分資料在短時間內稍微過期是可接受的

以線上商店的產品詳情頁為例。產品名稱、描述、圖片 URL 與平均評分每秒可能被讀取數千次,而更新頻率相對較低。在此情況下,您可以將產品資料快取至 Redis 數分鐘,並在產品更新成功後刪除相關快取鍵。下一次讀取會從來源取得目前值,再重新填入快取。

此模式的重點是,快取是來源的副本。寫入順序通常設計如下:

  1. 將變更提交至來源資料庫。
  2. 刪除相關 Redis 鍵,或以新值更新該鍵。
  3. 下一次讀取造成快取未命中時,讀取來源並重新填入快取。

若僅依賴 TTL 而省略失效處理,更新後直到 TTL 到期前,都可能回傳過期值。反之,若每次寫入時都無條件更新快取,則必須另外處理更新失敗、順序顛倒及多個鍵的一致性問題。Redis cache-aside 文件說明,應使用 TTL 限制過期值的最長存活時間,並在寫入時使用 DEL 明確使快取失效。(redis.io)

為什麼快取雪崩應成為採用決策的一部分?

當一個熱門鍵同時對許多請求到期時,所有請求都可能湧向來源資料庫,這稱為快取雪崩。換言之,Redis 在試圖解決問題時,可能反而在到期的當下對來源造成更大壓力。

若您需要下列一項或多項措施,Redis 快取就需要比單純 GETSET 更進階的設計:

  • 為到期時間加入隨機變動,避免鍵同時消失。
  • 僅允許一個請求從來源重新計算,其他請求則短暫等待或使用舊值。
  • 執行預先重新整理值的程序。
  • 另外限制特定熱門鍵的重新計算成本。

因此,僅有高讀取流量還不夠。只有在判斷來源是否能承受並行快取未命中後,Redis 快取才會帶來維運效益。

為什麼 Redis 適合工作階段、權杖及速率限制?

這三個領域都具有「生命週期短」、「跨多台伺服器共享」及「快速驗證或更新」的特性。若將工作階段儲存在應用程式伺服器記憶體中,當存在多台伺服器時,登入狀態可能因請求由哪台伺服器接收而不同。使用 Redis 作為集中式共享工作階段儲存,可減少此問題。

不過,採用工作階段儲存也有其界線:

  • Redis 中斷時,使用者能否重新登入?
  • 工作階段遺失是否可能導致付款問題、權限提升或法律爭議?
  • 是否已部署網路隔離、ACL、TLS 與密鑰管理,以防止工作階段遭竊?
  • 是否依使用者或租戶分隔鍵空間,並將權限降至最低?

Redis 的設計前提是受信任用戶端在受信任環境中存取,並建議不要將執行個體直接暴露於網際網路。自 Redis 6 起,ACL 可依使用者限制命令與鍵的存取;TLS 則可用於用戶端連線、複寫及叢集匯流排。Redis 보안 모델과 ACL·TLS (redis.io)

Redis 也適用於速率限制,但您必須定義限制的意義。例如,登入失敗次數限制是一項安全控制,因此您需要制定政策:Redis 中斷時要放寬限制,還是反過來封鎖所有請求。這不只是技術問題,也是服務風險承受度的問題。

何時可以針對工作佇列與即時訊息選擇 Redis?

Redis 也可用於佇列與訊息傳遞,但在此領域中,傳遞保證與重新處理需求比「即時」一詞更重要。

Pub/Sub 可簡單地將事件立即廣播給已連線的訂閱者。但它的傳遞模型是至多一次。若訂閱者因網路中斷或處理錯誤而遺漏訊息,該訊息不會再次傳遞,且可能遺失。因此,它適合用於 UI 重新整理通知,或只對目前線上使用者重要的訊號。Redis Pub/Sub 문서 (redis.io)

相較之下,Redis Streams 支援附加、依序讀取、保留期限、消費者群組及確認機制。若您需要找出並重新處理工作者在終止前尚未確認的工作,或多個消費者群組都必須讀取同一事件,Streams 更適合。Redis 文件將 Streams 描述為具備排序功能的只附加日誌,並說明消費者群組可管理至少一次傳遞。Redis Streams 문서 (redis.io)

不過,Streams 的存在不代表 Redis 可以取代所有規模與重要性的事件平台。若您需要長期保留、極高吞吐量、複雜的重新處理政策、接近恰好一次處理的業務結果,或眾多系統之間獨立的資料契約,請同時評估專用日誌或訊息代理與持久化資料庫。尤其是對於付款核准、會計分錄及訂單確認等工作,重複處理與遺失都至關重要,設計必須包含冪等鍵、來源紀錄及補償程序,而不僅是訊息傳遞方法。

在將 Redis 作為主要資料庫前,應區分什麼?

由於 Redis 支援持久化與複寫,它可作為某些服務的主要儲存系統。但「它能儲存資料」與「它適合對資料承擔最終責任」是不同的判斷。

下列需求越強,您越應謹慎看待僅以 Redis 作為事實來源系統:

需求為何僅使用 Redis 可能不利較安全的預設方向
長期且不遺失的保留記憶體成本、持久化設定及故障復原程序會成為直接責任。使用以耐久性為重的資料庫作為來源,並將 Redis 作為輔助層。
複雜 JOIN 與任意條件搜尋關係與查詢可能必須在應用程式中組裝。搭配關聯式或以搜尋為導向的儲存系統。
稽核、法規與修正歷程必須追蹤變更內容、時間與方式。維護具有明確變更歷程與備份政策的來源儲存。
多筆紀錄的不變條件跨多個實體的約束與回復很複雜。先評估交易模型符合需求的儲存系統。
遠大於 RAM 的資料集將所有資料保留在記憶體中的成本與容量規劃會變得困難。只將熱門資料移至 Redis,其餘保留於來源。

Redis 複寫採用主從模型,可用於擴充讀取及提高可用性。但具備複寫設定,不會自動解決故障期間的資料安全問題。Redis 文件也警告,若資料安全性很重要,將複寫與停用持久化的主節點結合使用的設定有風險。Redis 복제와 장애 조치 고려사항 (redis.io)

實務上,以下原則較安全:將訂單、付款、合約與權限的最終事實記錄於耐久來源中,並使用 Redis 處理能支援快速讀取或圍繞這些事實進行短期協調的狀態。 例如,在來源交易中完成實際庫存扣減,同時讓 Redis 在搶購高峰期間處理暫時保留、准入佇列與讀取快取。

流量增加後,能再加入 Redis Cluster 嗎?

不一定。Redis Cluster 是橫向擴展的重要選項,但它會影響鍵設計與多鍵操作。在 Redis Open Source Cluster 中,當一個命令、交易或 Lua 指令碼同時使用多個鍵時,這些鍵必須位於相同雜湊槽。可藉由使用相同的雜湊標籤,將相關鍵放進同一個槽。例如,user:{42}:profileuser:{42}:limits 共用相同標籤。Redis Cluster 확장 및 다중 키 연산 제약 (redis.io)

但在每個鍵上使用相同標籤,會將資料與流量集中於一個槽,失去分散的優點。因此,叢集不只是增加伺服器,而是需要決定下列事項:

  • 哪些鍵必須在同一請求中一起操作?
  • 這些鍵的耦合程度是否足以合理化將其放在同一槽?
  • 多鍵操作能否改為單鍵模型?
  • 用戶端能否在重新分片及故障切換期間重試暫時性錯誤?
  • 從複本讀取略微過期的值是否可接受?

許多服務一開始使用單一執行個體就已足夠。但若特定使用者或訂單的多個鍵必須始終原子化處理,且您預期未來使用叢集,從一開始就設計鍵命名慣例,可降低遷移成本。

為什麼記憶體限制與淘汰政策是功能需求?

在 Redis 中,記憶體同時是成本與資料保留政策。達到 maxmemory 時,服務行為會依新寫入遭拒絕、淘汰最近最少使用的鍵,或只淘汰具有 TTL 的鍵而不同。換言之,淘汰政策不是維運人員日後可調整的效能選項;它是決定使用者可能遺失哪些資料的產品政策。

例如,舊的個人檔案快取項目可以遭淘汰,因為下一次請求可以從來源復原它。此時淘汰很自然。但若速率限制計數器意外遭淘汰,限制可能被繞過;若工作佇列資料遭淘汰,工作可能遺失。後兩種情況需要足夠的容量規劃、隔離的執行個體或資料庫,以及適當的拒絕或背壓政策。

Redis 提供以 LRU、LFU 與 TTL 為基礎的淘汰政策,可適用於所有鍵或僅適用於有到期時間的鍵,也提供不淘汰而改為拒絕新寫入的政策。若必要的值絕不能被淘汰,請不要只因它「不是快取」就決定「仍要放進 Redis」。相反地,應明確定義記憶體達限時該如何保護這些資料。Redis 데이터 제거 정책 (redis.io)

何時最好不要採用 Redis?

在下列情況中,即使 Redis 看似具有吸引力,也較適合降低其優先順序。

尚未量測來源查詢時

若僅憑「資料庫可能會很慢」的模糊預期就加入 Redis,您會新增快取鍵、TTL、失效處理及故障處理的複雜性。請先量測慢路徑、重複讀取比例及資料庫負載。

絕不能回傳過期值時

若價格、餘額、權限或庫存的瞬間新鮮度會改變法律或財務結果,您必須為使用快取值定義極為嚴格的條件。若無法容忍失效處理失敗或複寫延遲,可能需要直接讀取來源的路徑。

資料量大、存取冷門且必須長期保留時

在以 RAM 為核心的儲存系統中保留大量不常存取的歷史資料,可能不具經濟效益。通常只將目前熱門的資料保留在 Redis 中更合適。

尚未準備承擔維運責任時

雖然 Redis 本身容易安裝,但運作它是另一回事。您必須監控記憶體使用量、鍵成長率、到期與淘汰、連線數、複寫狀態、備份與復原、故障切換、安全性及命令權限。特別是,應避免暴露於公用網路,並設計包含網路邊界、ACL 與 TLS 的存取控制。(redis.io)

發行模式需要進行授權審查時

Redis Open Source 的授權依版本而異。根據 Redis 的授權資訊,Redis 8 及後續版本採用三重授權模式,提供 RSALv2、SSPLv1 或 AGPLv3;Redis 7.2 及更早版本則使用 BSD-3-Clause。若您將 Redis 作為產品的一部分發行,或將其作為受管理服務提供,尤其需要進行法律與開放原始碼合規審查。這是與技術適配性分開的採用條件。Redis 라이선스 개요 (redis.io)

在採用前,應進行什麼小型實驗?

在單一狹窄問題上驗證,而不是全面替換,Redis 更可能成功。最佳的初始實驗是讀取快取:其來源資料明確、故障時可從來源復原,且效果能以數字衡量。

以下順序可讓決策更容易:

  1. 選擇一個目標。 具有明顯重複讀取的路由,例如熱門產品詳情、公開設定或讀取密集的 API 回應,都適合。
  2. 定義來源。 清楚說明 Redis 為空或不可用時,可從何處再次讀取正確值。
  3. 記錄鍵、TTL 與失效規則。 例如:product:{id}:view、五分鐘 TTL,以及產品更新成功後立即刪除。
  4. 定義故障期間的行為。 決定 Redis 逾時時是否回退至來源、是否在有限範圍內允許過期值,或直接使請求失敗。
  5. 加入雪崩保護。 考慮鎖定或 single-flight 策略,以防止熱門鍵被並行重新產生。
  6. 預先設定衡量標準。 同時追蹤快取命中率、來源 DB CPU 與查詢數、P95 與 P99 延遲、錯誤率、Redis 記憶體及淘汰次數。
  7. 依角色隔離資料。 不要在相同記憶體限制與淘汰政策下,混合快取與重要的工作階段或佇列資料,會比較安全。

若實驗產生高命中率卻未降低來源負載,請檢查鍵設計或回退路徑。反之,即使命中率稍低,只要阻擋最昂貴的來源查詢,也可能大幅改善 P99 延遲。最終的成功標準不是 Redis 的吞吐量本身,而是它能在多大程度上減少使用者請求路徑與來源系統中的瓶頸

結論:當您需要可控的暫時狀態層,而不只是「快速儲存盒」時,Redis 才適合

當重複讀取、短生命週期、原子狀態變更、以資料結構為中心的操作,或中等規模事件處理已成為服務中的實際瓶頸時,便是採用 Redis 的最佳時機。此時,Redis 可減少來源資料庫的工作量、簡化多台伺服器之間必須共享的狀態,並讓您以直接的資料結構解決排行榜、計數器、集合及串流問題。

不過,只有在一併設計失效處理、到期時間、記憶體限制、淘汰、複寫、故障復原及存取控制時,Redis 才能帶來價值。最安全的起點,是保留包含最終事實的來源系統,同時小規模驗證可重新產生的讀取快取,或具有自然 TTL 的一部分狀態。根據結果,您可決定是否將 Redis 的角色擴展至工作階段、速率限制、排行榜、佇列與 Streams,這種做法可避免不必要的複雜性。

常見問題

Redis 是否只能用作快取?

不是。Redis 也適合用於以 TTL 為基礎的工作階段、原子計數器與速率限制、排行榜、短期共享狀態,以及使用 Streams 進行中等規模的工作處理。不過,每種使用情境都必須個別評估可接受的資料遺失範圍與復原需求。

如果資料庫很慢,是否應該一律在前面加上 Redis?

不是。請先找出慢查詢、缺少索引、資料傳輸過多、N+1 查詢或連線飽和等原因。當重複讀取才是真正的瓶頸,而且可接受小幅且受控的資料新鮮度延遲時,Redis 快取特別有效。

使用 Redis 作為工作階段儲存是否安全?

取決於工作階段的特性。對於具有自然短生命週期及 TTL 的資料,例如可透過重新驗證復原的網站工作階段,Redis 的效果很好。但若 Redis 故障或到期會直接造成法律或財務損失,較安全的做法是使用持久化系統作為事實來源,並將 Redis 設計為輔助層。

應選擇 Pub/Sub 還是 Redis Streams?

若您需要立即通知已連線的訂閱者,且離線訂閱者遺漏訊息可以接受,Pub/Sub 較簡單。若需要訊息保留、重新處理、每個消費者的處理進度狀態或至少一次傳遞,請考慮 Streams。

使用 Redis Cluster 時,應預先設計什麼?

請先檢視鍵名與多鍵操作。在 Redis Open Source Cluster 中,於同一命令、交易或 Lua 指令碼中一起使用的鍵必須位於相同雜湊槽,因此可能需要使用雜湊標籤。無差別地使用雜湊標籤可能會損害鍵的分散效果。