呼,終於來到這 30 天手寫 Redis Clone 的最後一站了。 最後一天,就把系統監控指令(INFO 與 MONITOR)補起來,再用官方工具壓測一下,看...
Redis 如果不設密碼就放上公網,大概不用多久就會被掃到,接著可能被拿去挖礦或塞奇怪的東西。所以密碼驗證(AUTH)這層不能省。 另外,為了方便運維查看現在有...
從節點全量同步跑通後,今天接著處理主從複製的第二段:增量複製流傳播(Replication Stream Propagation)。 主要工作是讓主節點能處理...
昨天先把 SYNC 流程摸熟,今天開始寫從節點的背景同步 goroutine。目標是讓它可以自己連上主節點、送出 SYNC、讀取 RDB 快照,再把本機資料恢復...
單機跑久了總會遇到機器掛掉的時候,就算有 AOF 跟 RDB,重開機還是有一段時間不能服務。加上單機讀寫效能總是有天花板。 為了解決這些問題,Redis 提供了...
昨天弄好了 LRU,但 LRU 其實有個坑:如果一個 Key 過去一年被讀了一百萬次,但剛好這幾分鐘沒被讀;另一個沒什麼價值的 Key 剛好被寫入又讀了一次。L...
記憶體很貴,如果一直狂寫資料都不清理,遲早會遇到 OOM 爆掉。 為了避免這慘況,Redis 有套記憶體淘汰機制(Eviction Policy)。當記憶體快滿...
昨天先把 RDB 的資料模型定下來,今天就直接在 code/db/rdb.go 補 SaveRDB 和 LoadRDB,順便把 Server 啟動時的資料恢復流...
前幾天我弄好了 AOF 追加日誌。AOF 雖然資料安全,但缺點就是檔案有夠大,資料一多,重啟時 replay 指令會跑到讓人想睡覺。 所以 Redis 還有另一...
AOF 持久化是追加模式,也就是說系統跑越久,AOF 檔案就會越大。如果同一個 Key 被改了一萬次,AOF 就老老實實記下一萬條指令。 但實際上,歷史紀錄不重...
昨天雖然寫了 os.File.Write,但作業系統很聰明,會先把資料快取在 Page Cache 裡,不會馬上寫進磁碟。如果這時候當機,資料照樣不見。 今天來...
記憶體資料庫最怕的就是突然停電,辛辛苦苦存的資料瞬間灰飛煙滅。為了解決這問題,Redis 提供了 AOF (Append-Only File) 日誌與 RDB...
如果要一次塞幾萬筆資料給 Redis,一問一答的網路來回延遲絕對會讓你等到睡著。 Redis 為了解這個問題提供了 Pipeline (管道)。今天就來看之前寫...
Pub/Sub (發布/訂閱) 拿來做聊天室或事件廣播很方便,發送者不用管有誰在聽,只要往頻道一丟,訂閱的客戶端就全都會收到。 今天來實作一個thread-sa...
在寫 SQL 時大家都聽過 ACID,但在 Redis 裡,事務(Transaction)其實就是把多個命令打包,然後一次性、按順序跑完不被打斷。 今天來實作這...
String 指令跑通後,今天換把 List、Hash、Set 和 ZSet 這四個比較麻煩的結構接到 code/command/commands.go。 因為...
昨天把 Command Dispatcher 接起來後,今天就來補真正會被呼叫的 command handler。先從 PING、ECHO 這種基礎命令,以及...
前面我在 resp 模組寫了 RESP 解析器,db 模組也建好了記憶體 KV 引擎,但這兩個現在還是各過各的。 今天要在 command 模組裡補上Comma...
終於來到記憶體儲存引擎這一段的尾聲了。今天要碰 Redis 裡很有代表性的資料結構:Sorted Set (有序集合,簡稱 ZSet)。 ZSet 每個成員(M...
Redis 的 Set (集合) 是一個無序且**成員唯一(Unique)**的字串容器。平常開發拿來存標籤(Tags)、IP 白名單或共同好友很方便。 今天來...
Redis 的 Hash 很適合存物件資料,不用每次都把整包 JSON 存進去;只改某個欄位時,直接動那個 field 就好。它其實就是 field 到 val...
Redis 的 List 很常拿來做 Message Queue,或是處理需要從頭尾推資料的場景。它本質上是一串二進位安全字串。 今天來做 List,先補最常用...
用過 Redis 的人都知道 EXPIRE 很好用,時間一到資料就不見了。這在快取、驗證碼與臨時鎖等場景中是很重要的特性。 今天就來把 TTL 和惰性刪除(La...
引擎骨架弄好後,今天直接來實作最基本的 String 操作:SET、GET、DEL 和 EXISTS。 基礎命令的設計與實作 我在 code/db/db.go...
網路和 Parser 搞定後,今天終於要進到重頭戲:記憶體資料庫引擎。 今天先把 Thread-safe 的記憶體儲存引擎做出來,讓後面的命令有地方可以真的讀寫...
昨天把單行解析補完後,今天換處理 RESP 裡比較容易寫錯的兩個型別:Bulk Strings (二進位安全字串) 與 Arrays (陣列)。這兩個一個要處理...
昨天把 Parser 的骨架搭好了,今天就直接來寫解析邏輯吧。 我先挑比較軟的柿子吃,從 RESP 裡三種單行資料型態開始:Simple Strings (簡單...
要自己刻 Redis,第一步當然是要讓 Server 聽得懂 Client 在講什麼。Redis 客戶端與伺服器之間進行通訊時,使用的是一種名為 RESP (R...
寫資料庫引擎之前,網路層得先站穩。Redis 之所以快,底層事件模型佔了很大一部分;我雖然不用在 Go 裡手刻 epoll,但還是得先做出一個可以同時處理多個...
為什麼要自己寫一個 Redis? Redis 很多人都用過,拿來做快取、工作佇列、分散式鎖都很順手。但我一直覺得只停在「會用」有點可惜,尤其是它背後的網路 I/...