系統設計高頻率元件之 Redis

2024年5月24日

💎 加入 E+ 成長計畫 如果你喜歡我們的內容,歡迎加入 E+,獲得更多深入的軟體前後端內容

在系統設計中有許多「高頻率會用上」的要件。所謂的高頻率會用上,是指不論哪類系統,都會有使用這些要件的需求。

其中鍵值對資料庫是指由鍵值對 (key-value pair) 組成的存儲機制。這種資料庫在存資料時,會同時存一個獨特的 id,然後要取資料時,再根據這個 id 來取。

常見的鍵值對資料庫有 DynamoDB、MongoDB,或是 etcd、Zookeeper,以及 Redis 等等,上面這些都是鍵值對資料庫,但都有不同的特性。這篇會著重在 Redis 這類把資料存在記憶體的鍵值對資料庫。目前社群中相似解決方案有很多,先前 Redis 開源授權風波後,各大廠都有推出相對應的解決方案。不過由於 Redis 在過去被廣泛使用,以下都仍以 Redis 這個詞來代表相似類型的解決方案。

Redis 的基本介紹與特性

如上面提到,Redis 是一種鍵值對資料庫,是由鍵值對的方式來存資料,而 Redis 的每個鍵可以對應的資料結構很多元,基本上最常見的資料結構都有被支援。舉例來說,字串 (string)、列表 (lists)、集合 (Sets),甚至是 布隆過濾器 (Bloom Filters) 以及地理空間索引 (Geospatial Indexes)

因為是鍵值對的操作,所以可以簡單地用 SET 來為某個鍵設定對應的值,以及用 GET 來取得相對應鍵的值。舉例來說,我們可以這樣

SET explainThis 1
GET explainThis     # 拿到 1

當然除了上面做基本的存跟取之外,Redis 還提供許多方法可以直接用。有興趣的人可以參考相關文件 [連結],這邊就不展開。下面我們將會聚焦談幾個 Redis 常在系統設計會被用的地方。

做為鍵值對資料庫,Redis 的一大特性是把資料存在記憶體,這讓 Redis 的速度很快。同時,Redis 的可擴展性很好。Redis 主要透過一種叫 hash slot 的分片方式,把鍵分到集群中的不同節點,讓集群要添加節點變很容易,一個集群每秒處理百萬個讀取請求都很容易 (AWS 的 ElastiCache for Redis 先前號稱做到每個集群能一秒處理五百萬個讀取請求)。

在初步了解完 Redis 與其特性後,接著讓我們來談一些實際可以應用上 Redis 的地方。

Redis 作為快取 (caching)

上面提到,Redis 又快又能處理大量請求,基於這個特性,Redis 很常會被作為快取來用。服務先查看 Redis,如果有快取且沒過期,就直接用快取,就不用跟資料庫拿。如果沒有,就跟資料庫拿,然後再放到快取,並設定快取的存活時間 (TTL)

在上面的流程中,如果快取還沒有過期,直接跟 Redis 拿,會比跟資料庫拿快很多;而有 Redis 做為快取,除了能夠降低延遲外,也可以降低後端資料庫的壓力。如果在系統設計中遇到有低延遲要求的系統,Redis 可能是解決方案之一。

Redis 作為分布式鎖 (distributed locking)

除了快取外,Redis 也很常會被拿來當分布式鎖。在一個分散式系統中,如果要保持節點之間的一致性 (consistency),或是要確保同樣的操作不會被重複做,這時就可以用 Redis 來做為分布式鎖。

讓我們用搶票系統作為例子來進一步說明。一般來說,搶票系統對於一致性要求很高,例如,使用者 A 搶到的票,不能同時被其他使用者搶,不然會出現一張票賣兩個人,這就麻煩了。這時候就需要一個機制來避免這種重複的問題,而鎖 (lock) 是很常會用到的方法。

當提到鎖,你可能會想到用資料庫的悲觀鎖 (pessmistic lock),但在搶票系統的情境下,這不是好的做法。因為通常搶票系統要讓搶到票的人,保留時間來付款 (例如搶到後保留五分鐘,沒付款的話就釋放掉);而悲觀鎖適合短時間上鎖,要鎖五到十分鐘不適合用這種方式。

而分布式鎖在這種情況就會更適合,具體來說,可以用 Redis 搭配存活時間 (TTL) 來實現。 以搶票系統來說,當使用者 A 搶到票,會用票的 id 以及存活時間 (TTL) 拿到 Redis 的鎖。如果 A 有在鎖的存活時間內完成付款,則會更新到資料庫,確保其他人不會重複購票;假如時間到了沒付款,鎖就可以自動釋放,讓票能被其他人搶。

Redis 其他常見用途與追問的問題

除了上面提到的兩種用途外,Redis 也有許多其他在系統設計中常會用到的地方。除此之外,在系統設計中,當提到 Redis 時,經常會有不同的追問題,例如 Redis 做為快取如何擴展到全球多區域、Redis 存記憶體那該如何做到資料持久 (persistence)、Redis 是鍵值對那該如何處理熱鍵問題 (hot key)

上面這些我們都有在 E+ 的主題文中進一步討論。有興趣一讀的人,歡迎加入 E+ (詳細介紹見此)

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們