iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

手刻 Redis:用 Go 從零打造高效能高併發的記憶體資料庫系列 第 1

Day 01:Redis Clone 專案規劃與 Go 開發環境初始化

  • 分享至 

  • xImage
  •  

為什麼要自己寫一個 Redis?

Redis 很多人都用過,拿來做快取、工作佇列、分散式鎖都很順手。但我一直覺得只停在「會用」有點可惜,尤其是它背後的網路 I/O、RESP 協定、記憶體管理和資料結構,其實都很值得拆開來看。

所以這 30 天我打算用 Go 語言 寫一個 Redis Clone。不是追求功能百分之百相容,而是把一個記憶體型 Key-Value 資料庫該有的骨架真的做出來。

選 Go 的原因很直接:

  1. 網路程式設計方便net 標準庫已經把很多底層細節包好了,我可以把心力放在 server 架構上。
  2. 併發模型夠直覺:Goroutine 和 Channel 很適合拿來練 TCP 連線處理。
  3. 靜態型別與編譯速度:改資料結構時比較不容易一路炸到執行期才發現。

30 天開發藍圖規劃

為了不要寫到一半迷路,我先把 30 天拆成五個階段。至少先有一張地圖,後面每天才知道自己在補哪一塊:

第一階段:網路與協定解析 (Day 1 - 5)
      │
      ▼
第二階段:記憶體資料庫引擎 (Day 6 - 12)
      │
      ▼
第三階段:命令處理器與事件迴圈 (Day 13 - 18)
      │
      ▼
第四階段:資料持久化 AOF/RDB (Day 19 - 24)
      │
      ▼
第五階段:進階特性與效能調優 (Day 25 - 30)
  • 第一階段:網路與協定解析 (Day 1 - 5)
    建構 TCP Socket 伺服器,支援 goroutine 處理連線與 Graceful Shutdown。實作 RESP (Redis Serialization Protocol) 協定解析器(Parser),支援二進位安全字串與陣列。
  • 第二階段:記憶體資料庫引擎 (Day 6 - 12)
    實作thread-safe 的 Key-Value 儲存引擎。支援 String、List、Set、Hash 與 Sorted Set(跳躍表 SkipList)等核心資料結構,並加入過期時間(TTL)與主動/被動淘汰機制。
  • 第三階段:命令處理器與事件迴圈 (Day 13 - 18)
    實作 Command Dispatcher,支援 GETSETDELEXISTSINCR 等常見命令。探討 Redis 的single-thread 事件迴圈模型,並在 Go 中設計合適的鎖競爭優化方案。
  • 第四階段:資料持久化 (Day 19 - 24)
    實作 AOF (Append-Only File) 日誌與 RDB 記憶體快照。支援 AOF 後台重寫(Background Rewrite)以避免阻塞 main thread。
  • 第五階段:進階特性與效能調優 (Day 25 - 30)
    支援 Publish/Subscribe(發布/訂閱模式)、簡單的事務(Transaction),並利用 Go pprof 進行 CPU 與記憶體效能調優,最終與官方 Redis 進行 benchmark 對比。

說實在,一開始想說不就是個 map,後來查資料才發現要處理的事還真多,光是把架構圖畫出來就覺得有硬仗要打。


Go 開發環境初始化

現在,就動手初始化專案吧。我把專案命名為 redis-clone

1. 建立專案目錄結構

我規劃的目錄結構如下,兼顧了職責分離與 Go 社群的專案設計規範:

redis-clone/
├── articles/            # 存放 30 天鐵人賽文章
├── code/                # 專案原始碼
│   ├── go.mod           # Go Module 定義檔
│   ├── main.go          # 程式主入口
│   ├── server/          # TCP 網路伺服器模組
│   │   └── server.go
│   └── resp/            # RESP 協定解析模組
│       ├── resp.go      # 資料結構定義
│       ├── parser.go    # 解析器實作
│       └── parser_test.go # 單元測試

2. 初始化 Go Module

code/ 資料夾下,執行 Go Module 初始化命令:

cd code
go mod init redis-clone

這會產生一個基礎的 go.mod 檔案:

module redis-clone

go 1.26.2

跑起來看看

今天的進度主要是建好專案骨架,還沒有可以直接執行的功能。我們先確認一下目前的目錄結構是不是正確:

$ tree code/
code/
├── db
│   └── database.go
├── go.mod
├── main.go
└── resp
    └── parser.go

(或者用 ls -R code/ 也可以看到建立的檔案)

如果有出現這些檔案,代表第一天的準備工作就完成了!

總結

第一天先把專案範圍和目錄骨架定下來。雖然還沒寫出可以跑的功能,但至少知道接下來 29 天要補哪些東西。

明天開始碰 TCP Server。連線管理和 Graceful Shutdown 聽起來很基本,但我猜真正寫起來應該不會太輕鬆,明天見!


下一篇
Day 02:實作高併發 TCP Socket 伺服器與 Graceful Shutdown
系列文
手刻 Redis:用 Go 從零打造高效能高併發的記憶體資料庫4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言