Go 如何編寫簡單的內存鍵值數據庫

圖片

從 Postgres 到 Redis,再到 Prometheus,我們都使用並從事過各種數據庫的開發。我花了很多時間來閱讀其中一些數據庫的源代碼,對於那些像我一樣好奇的少數人來說,他們有興趣學習如何編寫一個數據庫。本書旨在記錄這一過程。

GitHub-arriqaaq/flashdb:

FlashDB is an embeddable, in-memory key/value database in Go (with Redis like commands)

01

內存數據庫

傳統數據庫的數據主要保存在機械硬盤或者固態硬盤, 內存數據庫則主要將數據保存在內存中,並通過消除對磁盤的訪問來實現最小的響應時間。兩者的不同主要體現在內存數據庫是將數據保存在主存或者 RAM 中,而傳統的數據庫則是通過驅動磁盤來獲取數據。

內存數據庫相比傳統數據庫更不穩定,由於所有的數據都存儲與管理在主存中,當計算機斷電或 RAM 崩潰時,數據將會丟失。

內存數據庫可以通過將每個操作存儲在日誌中或採取快照的方式在磁盤上持久化數據

02

目標

我們的目標是用 Go 編寫一個簡單、快速、嵌入式和可持久化的鍵 / 值數據庫,並且實現以下功能:

03

開始

我們要建立的是一個非常簡單的 KV(鍵 / 值)存儲,以便讓每個人都能輕鬆理解和實現。在 Go 中,有相當多的嵌入式鍵 / 值存儲可用,以下是一些例子:

讀起來容易做起來難。雖然我們可以通過閱讀龐大的代碼庫來了解其內部結構,但這對很多人來說依舊是一個障礙。我們的初衷是爲任何想學習關於如何編寫一個簡單的 ACID 數據庫的新手提供橋樑。

NutsDB 是我在 2-3 年前讀到的第一批簡單易懂的代碼之一。因此,我們選擇由易於理解的組合庫組成的 FlashDB。

04

架構

FlashDB 的架構很簡單並且支持各種 Redis 命令。Redis 本質上不是一個普通的鍵值存儲,而是一個數據結構服務器,支持不同種類的值。事實上,Redis 使用以下數據結構實現了各種類型。

圖片

05

字符串

Redis 字符串類型是能與 Redis 鍵關聯的最簡單的值類型。由於 Redis 鍵是字符串,當我們把字符串類型也作爲一個值時,實際上是把一個字符串映射到另一個字符串。這是用**可變基數樹(ART)**實現的,這樣可以很容易進行掃描。

 (https://github.com/arriqaaq/skiplist)

06

哈希

用哈希表示對象很方便,而實際上哈希中可放入的字段數量並沒有實際限制(除了可用的內存),所以你可以在應用程序中以許多不同的方式使用哈希。這是用一個非常簡單的 HashMap 數據結構實現的。

07

集合

Redis 集合是無序的字符串集合。我們可以對集合進行一些操作,比如檢測某個元素是否已經存在,查找多個集合之間的交集、並集或差集等。這也是用一個簡單的 HashMap 數據結構實現的。

(https://github.com/arriqaaq/set)

08

有序集合

有序集合是一種數據類型,類似於集合與哈希的混合體。和集合一樣,有序集合也是由唯一的、不重複的字符串元素組成的。所以從某種意義上說,有序集合也是一個集合。

雖然集合內的元素並不是有序的,但有序集合中的每個元素都與一個浮點值相關,稱爲分數(該類型類似於哈希,因爲每個元素都被映射到一個值)。

這是對用於字符串的跳錶結構稍加修改實現的。

09

持久化

雖然已經有了很多持久化機制,但我選擇了一個簡單的 append-only 日誌設計方式,因爲它比較容易實現和理解。

AOF(僅可寫入的文件) 記錄了服務器收到的每一個寫操作,這些操作將在服務器啓動時再重放,重建原始數據集。命令的記錄格式與 API 協議本身相同,以只寫入的方式進行。當日志過大時,FlashDB 能夠在後臺分片處理日誌。這是基於 wal 實現的。

總結

綜上,FlashDB 僅依靠上述五個簡單的庫就完成了,具有事務與 ACID 支持,易於理解。但我希望這對任何有興趣學習如何編寫數據庫的人來說都是一個有用的教程。

GitHub - arriqaaq/flashdb: 

FlashDB is an embeddable, in-memory key/value database in Go (with Redis like commands)

講座

最近在 Golang meetup 上分享了這個項目,這是幻燈片的內容:

https://www.canva.com/design/DAE8sGRyC2o/ZCuCaezQ6dYA0Oq24QxjUQ/view?utm_content=DAE8sGRyC2o&utm_campaign=designshare&utm_medium=link&utm_source=publishsharelink

原文地址:

https://aly.arriqaaq.com/building-a-database-in-go

原文作者:Farhan Aly

本文永久鏈接:https://github.com/gocn/translator/blob/master/2022/w17_Writing_a_simple_in-memory_key-value_Database_in_Go.md

譯者:張宇

校對:小超人

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/cRiv7yp9fNyvP5r8HAaEBQ