首先我们先来看main函数的启动:
func main() {
// specify the options
options := utils.DefaultDBOptions
options.DirPath = utils.ExecDir() + "/data"
// open a database
db, err := core.OpenDB(options)
if err != nil {
panic(err)
}
defer func() {
_ = db.Close()
}()
startTime := time.Now().UnixMilli()
for i := 0; i < 1_000_000; i++ {
//put a key
err = db.Put([]byte("name"+strconv.Itoa(i)), []byte("mgfacedb"+strconv.Itoa(i)), nil)
if err != nil {
panic(err)
}
}
endTime := time.Now().UnixMilli()
fmt.Println(endTime-startTime, "ms")
//get a key
val, err := db.Get([]byte("name111999"))
if err != nil {
panic(err)
}
println(string(val))
}
我们逐行进行解析:
options := utils.DefaultDBOptions
该行代码是对kv数据库设置一些默认参数,就像mysql的my.cnf文件一样,是用来给它做的配置,内容如下:
var DefaultDBOptions = DBOptions{
DirPath: TempDBDir(),
SegmentFileExt: WalFileExt,
MemTableSize: 8 * MB,
SegmentSize: 8 * MB,
BlockCacheSize: 16 * MB,
IsSync: true,
BytesPerSync: 0,
}
func TempDBDir() string {
dir, _ := os.MkdirTemp("", "mgfacedb_temp")
return dir
}
主要是有一下参数可配置:
options.DirPath = utils.ExecDir() + "/data"
该行代码组要是修改存放segment文件目录
db, err := core.OpenDB(options)
打开数据库,获取db的引用
err = db.Put([]byte("name"+strconv.Itoa(i)), []byte("mgfacedb"+strconv.Itoa(i)), nil)
批量插入值,代码示例是插入100万条值
val, err := db.Get([]byte("name111999"))
获取值判断是否存在。
从大方向看,就是给KV数据库配置参数,打开数据库,开始写入数据,然后插入数据。但是里面的细节会非常多。
首先该系统采用的是LSM数据结构来组织数据的,所以我们需要知道它在内核是怎么样子的?
可以看出来,LSM的数据结构是先把所有的数据写到memtable,然后memtable写满之后,就把写满的memtable变成immutable memtable,再新增一个memtable,immutable memtable会异步的把它存储到磁盘变成log文件,也就是我们上面的segment文件。对比我们上面的参数和第一篇是不是可以衔接上,接下来我们会开始研究内核是如何实现的。
All comments