实现分布式 kv—1 Standalone KV

简介: TinyKV 是 PingCAP 的一个开源课程:https://github.com/tidb-incubator/tinykv,旨在实现一个简易的分布式 kv,其中很多代码框架它已经提供了,我们只需要填充具体的逻辑即可。

TinyKV 是 PingCAP 的一个开源课程:https://github.com/tidb-incubator/tinykv,旨在实现一个简易的分布式 kv,其中很多代码框架它已经提供了,我们只需要填充具体的逻辑即可。


这个课程分为了 4 个 Project:

  • Standlone KV
  • Raft KV
  • Multi Raft KV
  • Transaction

分别需要实现单机版 kv、基于 raft 一致性算法的 kv、具有分布式事务的 kv,除了第一个 standalone kv 没有什么难度之外,其他的几个 Project 都非常的有挑战,涉及到手写 raft 算法以及分布式事务。


当然这个课程也是入门分布式存储领域是挺好的学习资源,因此记录一下自己的学习历程。


第一个 Project 是集成 Badger,实现一个简易的单机版 kv。

Badger 是一个很优秀的开源的单机版 kv 存储引擎,基于 LSM Tree 实现,读写性能都很好,需要简单熟悉下 Badger 的用法,可以参考下官方示例:https://github.com/dgraph-io/badger


在 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) == 0 {
    resp.NotFound = true
  }
  resp.Value = val
  return
}

这里的几个接口完成之后,一个完整的 Standalone KV 就完成了。

相关文章
|
存储 SQL 缓存
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案(3)
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案
207 0
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案(3)
|
存储 Java 数据管理
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案(2)
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案
185 0
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案(2)
|
7月前
|
NoSQL 大数据 分布式数据库
【云计算与大数据技术】分布式数据库NoSQL中KV、列式、图、文档数据库的讲解(图文解释 超详细)
【云计算与大数据技术】分布式数据库NoSQL中KV、列式、图、文档数据库的讲解(图文解释 超详细)
226 0
|
存储 缓存 NoSQL
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案(1)
顶会论文解读|DEPART:分布式KV存储系统的副本解耦方案
219 0
|
存储 SQL 缓存
【Paper Reading】DEPART:分布式KV存储系统的副本解耦方案
基于LSM-tree的键值存储系统是 NewSQL/NoSQL产品中最常用的底层存储方案,对其进行研究具有重要意义与应用价值。论文针对 分布式键值系统首次提出了副本解耦的思想,在多副本容错机制下能够实现副本数据的高效管理,从而显著提升系统性能。并且论文提出的技术可以应用到Cassandra、TiKV、ScyllaDB等系统中。本次分享将和大家一起讨论基于副本解耦的分布式键值系统的设计实现方案,并探讨未来的推广应用。
25532 1
【Paper Reading】DEPART:分布式KV存储系统的副本解耦方案
|
算法
实现分布式 kv—2 raft leader 选举
raft 是一个分布式一致性算法,主要保证的是在分布式系统中,各个节点的数据一致性。raft 算法比较复杂,因为它所解决的分布式一致性问题本来就是一个比较棘手的问题,raft 算法的实现主要可以拆解为三个部分: • 领导选举 • 日志复制 • 安全性
135 2
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
19天前
|
存储 NoSQL Java
使用lock4j-redis-template-spring-boot-starter实现redis分布式锁
通过使用 `lock4j-redis-template-spring-boot-starter`,我们可以轻松实现 Redis 分布式锁,从而解决分布式系统中多个实例并发访问共享资源的问题。合理配置和使用分布式锁,可以有效提高系统的稳定性和数据的一致性。希望本文对你在实际项目中使用 Redis 分布式锁有所帮助。
53 5
|
23天前
|
NoSQL Java 数据处理
基于Redis海量数据场景分布式ID架构实践
【11月更文挑战第30天】在现代分布式系统中,生成全局唯一的ID是一个常见且重要的需求。在微服务架构中,各个服务可能需要生成唯一标识符,如用户ID、订单ID等。传统的自增ID已经无法满足在集群环境下保持唯一性的要求,而分布式ID解决方案能够确保即使在多个实例间也能生成全局唯一的标识符。本文将深入探讨如何利用Redis实现分布式ID生成,并通过Java语言展示多个示例,同时分析每个实践方案的优缺点。
42 8