Project1 StandaloneKV
在这个项目中,我们将会在列族的支持下建立一个独立的 key/value 存储 gRPC 服务。Standalone 意味着只有一个节点,而不是一个分布式系统。列族(CF, Column family)是一个类似 key 命名空间的术语,即同一个 key 在不同列族中的值是不同的。你可以简单地将多个 CF 视为独立的小型数据库。CF 在 Project4 中被用来支持事务模型。
该服务支持四个基本操作:Put/Delete/Get/Scan,它维护了一个简单的 key/value Pairs 的数据库,其中 key and value 都是字符串。
- Put:替换数据库中指定 CF 的某个 key 的 value。
- Delete:删除指定 CF 的 key 的 value。
- Get:获取指定 CF 的某个 key 的当前值。
- Scan:获取指定 CF 的一系列 key 的 current value。
该项目可以分为2个步骤,包括:
- 实现一个独立的存储引擎。
- 实现原始的 key/value 服务处理程序。
代码
gRPC 服务在 kv/main.go 中被初始化,它包含一个 tinykv.Server,它提供了名为 TinyKv 的 gRPC 服务 。它由 proto/proto/tinykvpb.proto 中的 protocol-buffer 定义,rpc 请求和响应的细节被定义在 proto/proto/kvrpcpb.proto 中。
一般来说,不需要改变 proto 文件,因为所有必要的字段都已经被定义了。但如果仍然需要改变,可以修改 proto 文件并运行 make proto 来更新 proto/pkg/xxx/xxx.pb.go 中生成的 go 相关代码。
此外,Server 依赖于一个 Storage,这是一个需要为独立存储引擎实现的接口,位于 kv/storage/standalone_storage/standalone_storage.go 中。一旦 StandaloneStorage 中实现了接口 Storage,就可以用它实现Server 的原始 key/value 服务。
实现独立的存储引擎
第一个任务是实现 badger key/value 的 API。gRPC 服务依赖于一个在 kv/storage/storage.go 中定义的 Storage。在这种情况下,独立的存储引擎只是由两个方法提供的 badger key/value API。
type Storage interface {
// 省略其他的代码
Write(ctx *kvrpcpb.Context, batch []Modify) error
Reader(ctx *kvrpcpb.Context) (StorageReader, error)
}
Write 应该提供一种方式,将一系列的修改应用到内部状态,内部状态是一个 badger 的实例。
Reader 应该返回一个 StorageReader,支持 key/value 的单点读取和快照扫描的操作。
现在不需要考虑 kvrpcpb.Context,它在后面的项目中使用。
提示:
- 使用 badger.Txn 来实现 Reader 函数,因为 badger 提供的事务处理程序可以提供 keys 和 values 的一致快照。
- Badger 没有给出对 CF 的支持。engine_util 包(kv/util/engine_util)通过给 keys 添加前缀来模拟 CF。例如,一个属于特定 CF 的 key 被存储为 $ { cf } _ $ { key } 。它封装了 badger 以提供对 CF 的操作,还提供了许多有用的辅助函数。所以应该通过 engine_util 提供的方法进行所有读写操作。阅读 util/engine_util/doc.go 可以了解更多。
- TinyKV使用了 badger 原始版本的分支,并进行了一些修正,所以应该使用 github.com/Connor1996/badger 而不是 github.com/dgraph-io/badger。
- 不要忘记为 badger.Txn 调用 Discard(),并在销毁前关闭所有迭代器。
实现服务处理程序
这个项目的最后一步是用实现的存储引擎来构建原始的 key/value 服务处理程序,包括 RawGet / RawScan / RawPut / RawDelete。处理程序已经定义好了,只需要在 kv/server/raw_api.go 中补充实现。一旦完成,记得运行 make project1 以通过测试用例。
本文档指导如何构建一个基于列族的独立key/value存储gRPC服务——StandaloneKV。项目包括实现存储引擎和服务处理程序,支持Put、Delete、Get和Scan操作。存储引擎使用badger,并通过engine_util模拟列族支持。服务处理程序在kv/server/raw_api.go中实现。
8万+

被折叠的 条评论
为什么被折叠?



