結論先講

中小型應用用 PostgreSQL + Redis 就夠了。 Redis 做快取和 KV 存取、PG 做關聯式資料和 JSON。只有在搜尋量很大(加 Elasticsearch)或事件流很多(加 Kafka)的時候才需要額外的服務。每多一個服務就多一份維護成本和資料同步的複雜度。

這一步怎麼來的:DB 測完知道 PG 通用、MySQL 寫入強。但真實系統不會只有一個 DB——什麼時候該加 Redis 做 cache?什麼時候該加 Elasticsearch 做搜尋?加了到底快多少?


為什麼測儲存層

DB 不是唯一的資料儲存方案。Redis 做快取、Elasticsearch 做搜尋、MongoDB 做文件、Kafka 做事件流——每個都有人說「很快」,但到底快多少?什麼場景該加什麼?

下一篇 會講 Redis cache 在讀多場景提升 6.5 倍——但前提是你知道 Redis 適合什麼、不適合什麼。這篇先把各種儲存方案的效能攤開來比。


測試怎麼做的

固定 Express-TS 後端(4 CPU / 4 GB),統一 API 介面,只換儲存後端。6 項測試:

測試比較什麼
Document DBPG JSONB vs MongoDB
KV StoreRedis vs Memcached
SearchElasticsearch vs PG FTS
Message QueueKafka vs RabbitMQ vs Redis Pub/Sub
File StorageLocal fs vs MinIO (S3)
Cross CRUD同一筆 JSON 存到 5 種後端

排名:誰最快

儲存Max RPS場景
Redis (KV)5,346純 SET + GET
MongoDB2,273Document CRUD
PG JSONB2,182Document CRUD
Elasticsearch1,800*全文搜尋

*ES 的強項是搜尋速度,不是原始 CRUD RPS

Redis:KV 場景的絕對王者

Redis 做純 KV 存取(SET key value / GET key)每秒 5,346 個請求,比 RDBMS 快 2.4 倍。

為什麼這麼快:

  • 記憶體資料庫: 所有資料在 RAM,不需要磁碟 I/O
  • 單線程 event loop: 沒有鎖競爭(和 Node.js 類似)
  • 簡單的資料結構: KV 操作就是 hash table lookup,O(1)

但 Redis 不適合:

  • 大於 RAM 的資料集(Redis 7 的 Redis on Flash 有改善但不夠成熟)
  • 需要複雜查詢的場景(沒有 SQL)
  • 需要持久化保證的場景(預設是 async 寫盤,可能丟最後幾秒的資料)

MongoDB vs PG JSONB:只差 4%

操作MongoDBPG JSONB
JSON CRUD2,2732,182
差距基準-4%

DB 層測試 中,MongoDB 的 CRUD 比 PG ORM 快 8.6 倍。但那個比較不公平——PG 用 ORM(Sequelize),MongoDB 用 native driver。

Storage 層的測試用統一 API 介面,PG 直接用 JSONB 原生操作(不經 ORM),結果只差 4%。

結論:如果你只是要「在資料庫存 JSON」,PG JSONB 就夠了。 不需要額外維護一個 MongoDB。MongoDB 的優勢在「不需要 schema」和「原生 document 操作語法」,不在純速度。

Elasticsearch:搜尋的專業工具

查詢ESPG FTSPG LIKE
全文搜尋慢 2.6 倍

ES 比 PG 的 LIKE '%keyword%' 快 2.6 倍。但 PG 的 Full Text Search(tsvector + tsquery)也不差——如果你的搜尋需求不是很複雜,PG FTS 可能就夠了。

ES 值得加的場景:

  • 搜尋是核心功能(電商搜尋、內容搜尋)
  • 需要 faceted search(按分類/價格/品牌篩選)
  • 需要 aggregation(統計分析)
  • 資料量 > 1000 萬筆

Message Queue:Kafka vs RabbitMQ vs Redis Pub/Sub

Queue特性適合
Kafka高吞吐、持久化、可重播事件流、日誌收集、大資料
RabbitMQ靈活路由、acknowledgment任務佇列、微服務通訊
Redis Pub/Sub最簡單、最快、不持久化即時通知、簡單廣播

選哪個

  • 不確定 → RabbitMQ: 功能最完整、文件最多、社群最大
  • 需要事件重播 → Kafka: 消費者可以「倒帶」重新讀取過去的事件
  • 只是想廣播通知 → Redis Pub/Sub: 你已經有 Redis 了,不用額外裝東西
  • 注意: Redis Pub/Sub 沒有持久化——發出去的訊息如果沒有人在聽,就丟了

File Storage:Local vs MinIO (S3)

方式小檔高頻大檔批次
Local fs快(受磁碟速度限制)
MinIO (S3 API)較慢(HTTP overhead)中等

Local fs 在單機場景下永遠比 MinIO 快——因為少了 HTTP roundtrip。但 Local fs 無法跨機器共享、無法做 CDN、無法做版本控制。

建議

  • 開發/測試: Local fs
  • 生產單機: Local fs + 定期備份到 S3
  • 生產多機: MinIO 或雲端 S3(必須,不然檔案只在一台機器上)

跨儲存 CRUD 統一比較

同一筆 JSON 存到 5 種後端的 CRUD 速度:

儲存RPS適合場景
Redis最快KV、快取、session
MongoDB文件、不固定 schema
PG JSONB快(差 4%)文件 + 關聯式混合
Elasticsearch搜尋、聚合統計
Local File最慢大檔儲存

不要一開始就全裝

很多架構文章會畫出「PG + Redis + MongoDB + ES + Kafka + RabbitMQ」的完美架構圖。但每多一個服務:

  • 多一份部署腳本
  • 多一份監控和告警
  • 多一份資料同步邏輯(PG 的資料要同步到 ES 才能搜尋)
  • 多一個可能壞掉的節點

漸進式增加

  1. 起步:PG(一個 DB 搞定)
  2. 讀取變慢:加 Redis 做 cache(下一篇 會講 cache-aside 的 6.5 倍提升)
  3. 搜尋需求出現:加 ES
  4. 非同步任務:加 Queue(Redis 的 BullMQ 或 RabbitMQ)
  5. 事件流/日誌:加 Kafka

下一篇

Infra 的免費午餐:不改程式碼效能翻倍 — Redis cache +6.5 倍、nginx keepalive +7%、multi-worker +93%。三個配置層面的改動,加起來比從 Django 換成 Go 的效果還大。


本系列文章

完整 68 篇目錄見 系列首頁

← 上一篇:連線池與 MongoDB:連接的學問 → 下一篇:Infra 的免費午餐:不改程式碼效能翻倍