實現分佈式 kv—1 Standalone KV

TinyKV 是 PingCAP 的一個開源課程:https://github.com/tidb-incubator/tinykv。

旨在實現一個簡易的分佈式 kv,其中很多代碼框架它已經提供了,我們只需要填充具體的邏輯即可。
這個課程分爲了 4 個 Project:

分別需要實現單機版 kv、基於 raft(和 multi raft) 一致性算法的 kv、具有分佈式事務的 kv,除了第一個 standalone kv 沒有什麼難度之外,其他的幾個 Project 都非常的有挑戰,涉及到手寫 raft 算法以及分佈式事務。

當然這個課程也是入門和實踐分佈式存儲領域的挺好的學習資源,因此記錄一下自己的學習歷程。

今天這篇文章先來看看第一個 Project。

第一個 Project 是集成 Badger,實現一個簡易的單機版 kv。

Badger 是一個很優秀的開源的單機版 kv 存儲引擎,基於 LSM Tree 實現,讀寫性能都很好,因此需要簡單熟悉下 Badger 的用法,可以參考下官方示例:github.com/dgraph-io/bager。

在 TinyKV 中,存儲層是一個抽象接口,分別實現了 raft storage、mem storage、standalone storage,這裏我們只需要實現 standalone storage 就行了。

具體的實現,在 kv/storage/standalone_storage/standalone_storage.go 中,需要封裝一下 Badger,然後實現 storage 接口中定義的幾個方法。

這裏貼一下結構體的定義:

type StandAloneStorage struct {
  // Your Data Here (1).
  badgerDB *badger.DB
  options badger.Options
}

需要說明的是,在 Reader 方法中,需要返回一個 StorageReader 接口,這是一個抽象接口,具體邏輯需要我們自定義。

func (s *StandAloneStorage) Reader(ctx *kvrpcpb.Context) (storage.StorageReader, error) {
  // Your Code Here (1).
  txn := s.badgerDB.NewTransaction(false)
  reader := NewStandaloneReader(txn)
  return reader, nil
}

例如我定義了一個 StandaloneReader:

type StandaloneReader struct {
  txn *badger.Txn
}

func NewStandaloneReader(txn *badger.Txn) *StandaloneReader {
  return &StandaloneReader{
    txn: txn,
  }
}

這裏完成之後,還需要在 kv/server/raw_api.go 中完善相應的 gRPC 接口,直接解析傳過來的參數,然後調用 Storage 接口中的方法即可。這裏展示一個示例:

func (server *Server) RawGet(_ context.Context, req *kvrpcpb.RawGetRequest) (resp *kvrpcpb.RawGetResponse, err error) {
  // Your Code Here (1).
  resp = &kvrpcpb.RawGetResponse{}

  // get storage reader.
  var reader storage.StorageReader
  reader, err = server.storage.Reader(req.Context)
  if err != nil {
    return
  }
  defer reader.Close()

  val, err := reader.GetCF(req.Cf, req.Key)
  if len(val) =={
    resp.NotFound = true
  }
  resp.Value = val
  return
}

這裏的幾個接口完成之後,一個完整的 Standalone KV 就完成了。

你可以把 TinyKV 的代碼 clone 下來,然後自己跟着我的節奏做,一步一步堅持下去,相信能夠在分佈式存儲領域有個初步的認知。

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