Talent Plan TinyKV Project1 StandaloneKV
2021/12/6 23:20:25
本文主要是介绍Talent Plan TinyKV Project1 StandaloneKV,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
6.824做完了,代码写的乱糟糟,想着重写一遍,整理下思路,后来发现了tinykv,相比于6.824还多了个事务,就准备把tinykv也做一下。
文档翻译
在本项目中,实现一个单机的、支持Column Family的KV存储服务。Column Family表示Key的命名空间,不同Column Family间可以有相同的Key存在。
服务提供Put/Delete/Get/Scan四种基本操作。
本项目可以拆解为两步去实现:
- 实现单机的存储引擎。
- 实现原生的服务接口。
tinykvpb.proto和kvrpcpb.proto定义了rpc接口和请求响应消息,kv/main.go中注册了RPC服务。
proto文件由protocol-buffer生成,不需要修改。
Server底层由Storage抽象类支持,需要为StandAloneStorage实现Storage的所有接口。
type Storage interface { // Other stuffs Write(ctx *kvrpcpb.Context, batch []Modify) error Reader(ctx *kvrpcpb.Context) (StorageReader, error) } 复制代码
Storage底层由badger(类似LevelDB或RocksDB的存储引擎)支持,StandAloneStorage即badger的简单封装。
目前不需要考虑kvrpcpb.Context的涵义。
一些提示。
- 使用badger.Txn来实现Reader()函数,即badger提供的事务支持。
- badger不支持Column Family,engine_util提供了一系列函数,利用前缀来实现Column Family,使用它们来实现Write()函数。
- 使用Connor1996/badger而不是dgraph-io/badger。
- 使用Discard()关闭badger.Txn,这之前需要关闭所有迭代器。
最后就是基于Storage实现RawGet/RawScan/RawPut/RawDelete,完成后通过make project1进行测试。
StandAloneStorage
engine_util封装了badger的接口,StandAloneStorage就是要在engine_util的基础上再封装一层。因此StandAloneStorage结构也很简单。
type StandAloneStorage struct { engine *engine_util.Engines } 复制代码
StandAloneStorage为抽象类Storage的具体实现,因此需要实现Write和Reader两个函数,函数签名如下。
func (s *StandAloneStorage) Write(ctx *kvrpcpb.Context, batch []storage.Modify) error func (s *StandAloneStorage) Reader(ctx *kvrpcpb.Context) (storage.StorageReader, error) 复制代码
Project1中,还用不到kvrpcpb.Context,storage.Modify对应Put或Delete两个写操作,storage.StorageReader同样是一个抽象类。
Reader
type StorageReader interface { GetCF(cf string, key []byte) ([]byte, error) IterCF(cf string) engine_util.DBIterator Close() } 复制代码
可以看到StorageReader的两个函数,屏蔽了事务,简化了接口。实现StorageReader需要用到engine_util提供的GetCFFromTxn和NewCFIterator两个函数。
func GetCFFromTxn(txn *badger.Txn, cf string, key []byte) (val []byte, err error) func NewCFIterator(cf string, txn *badger.Txn) *BadgerIterator 复制代码
获取badger.Txn的函数engine_util并未给出,需要直接调用badger.DB.NewTransaction函数。
func (db *DB) NewTransaction(update bool) *Txn 复制代码
update为真表示Put/Delete两个写操作,为假表示Get/Scan两个读操作。
Write
type Modify struct { Data interface{} } type Put struct { Key []byte Value []byte Cf string } type Delete struct { Key []byte Cf string } 复制代码
Modify表示一个Put/Delete操作,Write中通过断言确定是Put还是Delete,进而调用engine_util提供的PutCF和DeleteCF两个函数。
func PutCF(engine *badger.DB, cf string, key []byte, val []byte) error func DeleteCF(engine *badger.DB, cf string, key []byte) error 复制代码
其实这两个函数内部实现依旧是用了事务的,相比于Reader,Write对事务的屏蔽并没有让我们自己实现。
Server
StandAloneStorage是Storage的实现,Server还要在他之上,后续还会有RaftStorage,这样Server底层的存储引擎就是可以更换的,分别对应单机的和分布式的存储服务。
type Server struct { storage storage.Storage } 复制代码
Project1要求我们为Server实现原生的服务接口,这部分在raw_api.go中,需要实现的函数的签名如下。
func (server *Server) RawGet(_ context.Context, req *kvrpcpb.RawGetRequest) (*kvrpcpb.RawGetResponse, error) func (server *Server) RawPut(_ context.Context, req *kvrpcpb.RawPutRequest) (*kvrpcpb.RawPutResponse, error) func (server *Server) RawDelete(_ context.Context, req *kvrpcpb.RawDeleteRequest) (*kvrpcpb.RawDeleteResponse, error) func (server *Server) RawScan(_ context.Context, req *kvrpcpb.RawScanRequest) (*kvrpcpb.RawScanResponse, error) 复制代码
实现这四个接口,需要调用之前实现的Write、Reader.GetCF、Reader.IterCF这三个函数,一个可能不太理解的是Scan函数,因为badgerDB内部是有序存储的,所以可以根据一个Key,向后获取N个Key,RawScanRequest.Limit就是N的涵义。
engine_util封装了DBIterator,提供了Item、Valid、Next、Seek用于实现RawScan函数。
Column Family
可能你还没理解CF是什么,其实本质就是字符串而已,用作Key的前缀,起到命名空间的作用。
const ( CfDefault string = "default" CfWrite string = "write" CfLock string = "lock" ) func KeyWithCF(cf string, key []byte) []byte { return append([]byte(cf+"_"), key...) } 复制代码
例如默认的CF为"default",那么该CF下的名为"apple"的Key,实际存储为"default_apple"这个字符串。
这篇关于Talent Plan TinyKV Project1 StandaloneKV的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-29Elasticsearch慢查询日志配置
- 2024-05-29揭秘华为如此多成功项目的产品关键——Charter模板
- 2024-05-29海外IDC业务拓展的7大挑战
- 2024-05-29InLine Chat功能优化对标Github Copilot,CodeGeeX带来更高效、更直观的编程体验!
- 2024-05-29CodeGeeX 智能编程助手 6 项功能升级,在Visual Studio插件市场霸榜2周!
- 2024-05-29AutoMQ 生态集成 Apache Doris
- 2024-05-292024年IDC行业的深度挖掘:机遇、挑战与未来展望
- 2024-05-29五款扩展组件齐发 —— Volcano、Keda、Crane-scheduler 等,邀你体验
- 2024-05-29AutoMQ 对象存储数据高效组织的秘密: Compaction
- 2024-05-29活动预告|来 GIAC 大会听大数据降本利器:AutoMQ 基于云原生重新设计的 Kafka