Golang实现KV存储引擎实例探究

 更新时间:2024年01月24日 10:33:58   作者:绍纳 nullbody笔记  
这篇文章主要为大家介绍了Golang实现KV存储引擎实例探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

通过本项目可以学到什么?

WAL预写日志的实现

LSM Tree(Log-Structed-Merge Tree)

如何构架一个企业级的项目

KV数据的序列化和反序列化存储

  • Golang的基本语法

整个代码量1000多行,基本的大框架也好理解,容易出现错误的点在于代码细节的处理(特别是wal文件的读写部分)

简介

内存数据采用SkipList 存储

通过WAL (Write Ahead Log)保证内存数据durabilitycrash-safe能力

代码逻辑结构

  • 先通过easydb.Open打开数据库*DB对象;*DB内部基于WAL恢复内存数据openAllMemtables【就是读取segment文件,解析出一个个LogRecord保存到skiplist中】,同时将内存数据分成活跃内存和不可变内存【参考 LSM Tree结构】。每个内存对象*memtable内部除了定义skiplist记录内存数据,同时定义*wal对象记录磁盘,*wal对象中的磁盘文件按照指定的大小分段保存(这里类似kafka中日志数据文件分段原理)
  • 然后调用 db.Put方法,内部通过batch开启写事物(对db上锁),将数据批量保存batchpendingWrites中,然后在batch.Commit一次性全部保存到内存和预写日志中同时关闭写事物(对db解锁)
  • 调用db.Get方法,内部通过batch开启读事物(对db上锁),读取所有的内存对象中的数据(倒序)方式,也就是从最近的内存对象*memtable开始读,读取结束,提交事物(关闭读事物,对db解锁)

建议从下面 Open Get Put这几个函数开始看起

package main
import (
	"fmt"
	"github.com/gofish2020/easydb"
	"github.com/gofish2020/easydb/utils"
)
// this file shows how to use the basic operations of EasyDB
func main() {
	// specify the options
	options := easydb.DefaultOptions
	options.DirPath = utils.ExecDir() + "/data"
	// open a database
	db, err := easydb.Open(options)
	if err != nil {
		panic(err)
	}
	deferfunc() {
		_ = db.Close()
	}()
	// put a key
	err = db.Put([]byte("name"), []byte("easydb"), nil)
	if err != nil {
		panic(err)
	}
	// get a key
	val, err := db.Get([]byte("name"))
	if err != nil {
		panic(err)
	}
	println(string(val))
	// delete a key
	err = db.Delete([]byte("name"), nil)
	if err != nil {
		panic(err)
	}
	// get a key
	val, err = db.Get([]byte("name"))
	if err != nil {
		if err == easydb.ErrKeyNotFound {
			fmt.Println("key not exist")
			return
		}
		panic(err)
	}
	println(string(val))
}

WAL日志格式

WAL日志文件按照SegmentSize分成一个个的段文件;

每个段文件,按照32KB为一块存储区域,存储 多个 chunk实际数据

每个chunk由 7 字节header + 数据payload 组成;header头包括 4字节校验码,2字节数据长度 1字节数据类型;校验码校验的范围为:【length + type + payload】确保数据没有损坏

一个数据可能由多个chunk组成

当在block中保存了多个chunk后,block剩余的空间不够保存数据,多余的空间浪费掉,填充一些无效字节即可

Ps:本项目主要参考 LotusDB 实现

以上就是Golang实现KV存储引擎实例探究的详细内容,更多关于Golang KV存储引擎的资料请关注脚本之家其它相关文章!

相关文章

  • golang gorm的Callbacks事务回滚对象操作示例

    golang gorm的Callbacks事务回滚对象操作示例

    这篇文章主要为大家介绍了golang gorm的Callbacks事务回滚对象操作示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • 更换GORM默认SQLite驱动出现的问题解决分析

    更换GORM默认SQLite驱动出现的问题解决分析

    这篇文章主要为大家介绍了更换GORM默认SQLite驱动出现的问题解决分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2024-01-01
  • Golang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由字母数字和_(下划线)组成,并且只能以字母和_开头,更详细内容请看下面文章吧
    2021-10-10
  • Go语言中普通函数与方法的区别分析

    Go语言中普通函数与方法的区别分析

    这篇文章主要介绍了Go语言中普通函数与方法的区别,以实例形式对比分析了普通函数与方法使用时的区别与相关技巧,需要的朋友可以参考下
    2015-02-02
  • 深度剖析Golang中的数组,字符串和切片

    深度剖析Golang中的数组,字符串和切片

    Golang 是一种以简洁性、并发性和性能而著称的编程语言。其重要特性之一是能够处理数组、字符串和切片等数据类型。本篇文章将深入讨论这些数据类型,并探讨如何在代码中使用它们
    2023-04-04
  • Go语言defer语句的三种机制整理

    Go语言defer语句的三种机制整理

    在本篇文章里小编给大家分享的是一篇关于Go语言defer语句的三种机制整理,需要的朋友们学习下吧。
    2020-03-03
  • Golang 高效排序数据详情

    Golang 高效排序数据详情

    本文我们介绍了怎么使用 Golang 语言标准库 sort 包排序数据,需要注意的是,除了本文使用的类型之外,其它任意类型只要实现 sort.Interface 的三个方法,都可以调用 sort.Sort() 函数排序数据。
    2021-11-11
  • golang 数组去重,利用map的实现

    golang 数组去重,利用map的实现

    这篇文章主要介绍了golang 数组去重,利用map的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-04-04
  • Golang实现smtp邮件发送的示例代码

    Golang实现smtp邮件发送的示例代码

    这篇文章主要为大家详细介绍了Golang实现smtp邮件发送的相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Golang控制协程执行顺序方法详解

    Golang控制协程执行顺序方法详解

    这篇文章主要介绍了Golang控制协程执行顺序的方法,Golang的语法和运行时直接内置了对并发的支持。Golang里的并发指的是能让某个函数独立于其他函数运行的能力
    2022-11-11

最新评论