宏虹分享 | Redis vs. MongoDB:選擇合適的 NoSQL 數據庫

Redis(Remote Dictionary Server,遠端字典伺服器)和 MongoDB 是兩類知名的 NoSQL數據庫,其以非結構化的方式存儲數據。與傳統關聯式數據庫使用表格、行和列來組織數據不同,NoSQL數據庫採用了不同的數據存儲模型。

Redis是一種開源的記憶體中數據庫,以鍵值對的形式存儲數據,其將數據存儲在 RAM 中,以實現高效的讀寫性能,同時也提供磁片持久存儲作為補充功能。MongoDB是另一種開源的文檔數據庫,透過序列化的 JSON 格式來存儲數據,MongoDB會將數據存儲在外部存儲中。

儘管 Redis和 MongoDB 都是廣受歡迎的 NoSQL數據庫,並且在現代軟體發展中得到了廣泛的應用和驗證,但兩者在設計理念、應用場景等方面存在顯著差異。對於剛接觸 NoSQL 數據庫的讀者來說,這些差異可能會帶來困惑。

本文旨在為讀者提供關於這兩種數據庫的詳細資訊,説明大家更好地理解兩者的區別,進一步根據自身開發團隊的需求和業務應用場景,更有效地選擇最合適的數據庫解決方案。

數據模型

所謂數據模型,指的就是我們向數據庫中存儲數據時,這些數據究竟以何種形式進行組織、存儲。瞭解了數據模型,進而能窺探出數據庫的設計思想,從而指導我們如何正確地去使用。例如 SQL 數據庫在存儲時,會將數據組織為表格的形式,同時表格還會附帶若干屬性約束,這就是典型的關係數據模型,如下圖所示。

圖一、關係數據模型

Redis

Redis 將數據存儲在RAM中,RAM帶來的優勢就在於數據可以被快速存取,並能提供極低的延遲。不過由於 RAM 的特性,這種存儲方式也限制了可以存儲的數據量,無論是 HDD 還是 SSD,硬碟的單位存儲價格始終遠低於 RAM。而為了實現數據持久性,Redis 提供了兩種機制:快照(Snapshot)和僅追加檔(AOF)日誌記錄,這兩種方法可以將數據集保存在磁片上,規避 RAM 易失性的缺陷。

此外,Redis 使用鍵值對的形式存儲數據,每個數據條目都有一個唯一的鍵(Key)。它支援多種數據類型,常用的包括有序集合(Sorted Set)、雜湊(Hash)、無序集合(Set)、清單(List)與字串(String)。鍵值對的大小被限制為不超過 512MB,不過通常我們在使用中會盡可能地避免使用較大的鍵值對。

它還支援 Pub-Sub 或者流模式,這使其不僅僅是一個鍵值緩存系統。該功能允許在系統中實現訊息佇列等功能,額外的 Redis Model 支援也提供了緩存之外的拓展選項。

下圖展示了 Redis 的數據模型。

圖二、Redis 數據模型

MongoDB

MongoDB 是一種文檔存儲數據庫,與傳統的 SQL 驅動的關聯式數據庫有顯著不同。在關聯式數據庫中,如上文所言,數據通常被簡化為具有索引的 CSV 檔形式,每個檔代表一個表;而在文檔存儲中,數據則被簡化為具有索引的 JSON 檔,每個檔對應一個文檔,多個文檔組合成一個集合。

另外,JSON 檔的結構與 XML 和 YAML 檔類似,也類似於 Python 中的字典。因此,可以按照這種層次結構來組織和涉及數據。在 MongoDB 中,文檔由已命名的鍵組成,而這些鍵可以包含其他文檔、陣列或標量值。舉例而言,一個文檔中可能包含一個鍵 Address.Street,其值為 123 Main St。你可以透過在索引中查找 Address.Street 等於某個值的文檔集合來進行搜索。

圖三、JSON檔

同時,MongoDB 還允許文檔包含陣列,例如 Orders 陣列,其中可以包含多個訂單資訊。可以針對 Orders 陣列的內容進行複雜的查詢操作,比如查找包含某個特定值子集的文檔。舉例來說,如果 Orders 包含 [“A1001”, “B2002”],查詢 Orders includes “A1001” 會返回這個文檔;而查詢 Orders includes any of [“B2002”, “C3003”] 則會返回包含這些訂單中任一項的文檔。

文檔的嵌套層次越深,其靈活性和數據組織的能力越強。例如,Address 可以包含一個子文檔 Geo,其中有 Latitude 和 Longitude 資訊。如果業務的數據高度結構化,文檔存儲模型往往比關聯式數據庫更具優勢。

下圖展示了 MongoDB 的數據模型。

圖四、MongoDB 數據模型

什麼情況下使用Redis

以開發團隊以及應用需求為導向

如果您的應用需要頻繁的查詢操作,Redis 中的數據通常存儲在各種專門的數據結構中,為了優化性能,開發人員需要為每種類型的物件選擇特定的數據結構。因此,選擇 Redis 可能會帶來一些額外的開發與適配工作。而在 MongoDB 中,由於其數據結構更加一致(JSON),類似的查詢可能在實現層面上更加簡單。不過事有兩面,儘管在 Redis 中的查詢或許需要處理多種數據結構,但這種些微複雜性帶來的好處是回應速度的提升。Redis 的高性能可以彌補在查詢處理上的額外工作量。

對於開發人員而言,尤其是那些擁有傳統數據庫和 SQL 背景的開發人員對 MongoDB 的接受程度或許會更好。雖然兩者都是 NoSQL 數據庫,但MongoDB 提供了一種更直觀、更符合 SQL 習慣的方式來管理和查詢數據。相較之下,Redis 雖然使用上完全稱不上複雜,但以鍵值對為設計思考的存儲模式,可能需要花費更多時間和精力去學習,Redis 也提供了更高的靈活性。

“就個人而言,我傾向於選擇 Redis 來滿足大多數需求,其高性能和靈活性使其在許多應用場景中相當有效。不過最終的選擇,應該基於具體的應用需求和開發團隊的技能組合。”

艾體寶高級工程師Eero

Redis

對於需要快速查詢的臨時數據存儲,非常建議使用 Redis。Redis 能夠提供對頻繁存取的數據的快速回應,因此非常適合用作緩存或會話存儲等場景。此外,Redis 內置了對發佈-訂閱(Pub/Sub)訊息傳遞模式的支援(新發佈的 Redis Stream 還在此基礎上進一步做了改),其在即時應用程式或事件驅動架構中表現出眾。同時,他還提供其它高級數據結構例如有序集合和清單,用於實現速率限制、任務佇列與作業調度系統。最後,Redis 還能高效地對數據進行計數和匯總,也非常適用於跟蹤排行榜數據或其他統計數據。

MongoDB

相比之下,MongoDB 適用於存儲複雜的應用程式數據,尤其是大規模的數據集。其提供了更傳統的數據庫結構,同時支援無模式的存儲,賦予了開發者相較於關聯式數據庫更大的靈活性。MongoDB 能夠有效地處理大量的寫入和讀取操作,常見的用例如內容管理系統或大規模的使用者數據管理。

兩者不能一起使用嗎?

許多應用程式中,同時使用 Redis 和 MongoDB 是一種行之有效的策略。Redis 的高性能與 MongoDB 的長期存儲能力相得益彰,得以顯著優化數據庫的整體性能,提高系統的可擴展性,並為應用程式提供更多的靈活性。例如,Redis 的高速記憶體存儲使其能夠迅速捕獲和處理即時數據流,非常適用於需要即時回應的場景。處理後的數據或結果,可以存儲在 MongoDB 中,進行存檔或用於更複雜的分析。該策略一方面能提高系統的回應速度,另一方面還能為數據的持久性和可擴展性提供額外的保障。

圖五、Redis vs MongoDB

另一個常見的應用場景是跨 Redis MongoDB 的混合數據模型。您可以利用 Redis 的鍵值存儲來快速存取頻繁使用的中繼數據,同時使用 MongoDB 處理更複雜的數據結構。如此,職責分明,Redis 提供低延遲的讀取和寫入操作,而 MongoDB 則處理複雜的查詢和數據持久化。透過結合兩種數據庫的優點,進而構建一個既高效又靈活的系統,滿足多種應用需求。

圖六、Redis 和 MongoDB 的混合數據模型

差異總結

產品推薦

Redis
  • 具有線性可擴展性、高可用性、持久性、備份和恢復、地理分佈、分層內存存取、多租戶、安全性等8大核心功能
  • 擁有 RediSearch、RedisJSON等7大【Redis企業版特有模組】
  • 應用場景:企業緩存| 會話管理| 重複數據刪除| 排行榜| 欺詐識別| 實時庫存
redis
  • 和全球統一數據 : 基於 CRDT 的主動-主動部署、無縫衝突解決
  • 在遷移到雲或跨雲時保持數據一致
  • 個位數秒自動故障轉移時間、純記憶體複製、內置數據持久性、定期備份和自動集群恢復
  • 現代應用程式的現代數據模型 : 通過單一數據平台漸低複雜性