GitHub - k-si/CaskDB: K-V database based on Bitcask, but has some magic changes
跪求star OTZ
Bitcask模型Bitcask是一个kv存储的模型,它采用日志追加写的模式来记录数据。该模型包含两部分:内存部分和磁盘部分。我们都知道内存的读写速度是非常快的,痛点就是内存的易失性,所以我们必须将数据持久化到磁盘文件中。
如何在磁盘中高效的读写呢?首先想要高效就必须了解磁盘读取数据的方式,传统的机械硬盘中,机械臂移动到目标磁道,然后磁盘旋转,读取该盘面上的数据,数据通过数据总线进入内存。如果要读取的数据是随机散布在硬盘中,需要消耗大量磁臂和磁盘移动时间,所以磁盘的顺序读取速度远远大于随机读取速度。
基于以上,bitcask模型在内存中维护一个map,记录key值和其value值所在文件和文件中的位置等信息,外部读取时,通过内存一次性找到硬盘上的数据。在写入数据时,将数据规整为一条entry,(entry包含keysize、valuesize、key值、value值等)追加写入到文件中。之后更新内存中的map。
当硬盘存储文件过大时,将创建新文件继续追加写,之前的文件将被锁起来,只读不写。为了防止log过多,必须定时合并所有的文件,将数据更新到新的log中。
更多细节,可以google下bitcask论文或其他博文。
介绍CaskDB是基于Bitcask模型实现的kvdb引擎,支持String,List、Hash、Set、ZSet五种类型数据的持久化存储。它的优势如下:
- 日志结构模型,写入速度快
- 多样数据类型支持
- 键值分离存储,对内存依赖较小
- 性能稳定可预测(只需一次内存和一次磁盘访问)
如果你的内存有限,且性能要求不那么高,可以考虑试试CaskDB。
使用方式package main
import (
"github.com/k-si/CaskDB"
"log"
)
func main() {
db, err := CaskDB.Open(CaskDB.DefaultConfig())
if err != nil {
log.Fatal(err)
}
defer db.Close()
// do something...
}
基准测试
测试函数详见:CaskDB/db_str_test.go
1,000,000次读写go test -bench=BenchmarkDB_Set -benchtime=1000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Set-8 1000000 1025 ns/op 520 B/op 10 allocs/op PASS ok github.com/k-si/CaskDB 1.165s go test -bench=BenchmarkDB_Get -benchtime=1000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Get-8 1000000 358.6 ns/op 71 B/op 2 allocs/op PASS ok github.com/k-si/CaskDB 1.516s5,000,000次读写
go test -bench=BenchmarkDB_Set -benchtime=5000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Set-8 5000000 1039 ns/op 520 B/op 11 allocs/op PASS ok github.com/k-si/CaskDB 5.647s go test -bench=BenchmarkDB_Get -benchtime=5000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Get-8 5000000 399.5 ns/op 71 B/op 2 allocs/op PASS ok github.com/k-si/CaskDB 7.457s10,000,000次读写
go test -bench=BenchmarkDB_Set -benchtime=10000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Set-8 10000000 1058 ns/op 520 B/op 11 allocs/op PASS ok github.com/k-si/CaskDB 11.234s go test -bench=BenchmarkDB_Get -benchtime=10000000x -benchmem -run=none goos: darwin goarch: arm64 pkg: github.com/k-si/CaskDB BenchmarkDB_Get-8 10000000 404.1 ns/op 71 B/op 2 allocs/op PASS ok github.com/k-si/CaskDB 15.463s其他
CaskDB支持的数据类型和命令操作如下:
-
String
- Set
- MSet
- SetNx
- MSetNx
- Get
- MGet
- GetSet
- Remove
- SLen
-
Hash
- HSet
- HSetNx
- HGet
- HGetAll
- HDel
- HLen
- HExist
-
List
- LPush
- LRPush
- LPop
- LRPop
- LInsert
- LRInsert
- LSet
- LRem
- LLen
- LIndex
- LRange
- LExist
-
Set
- SAdd
- SRem
- SMove
- SUnion
- SDiff
- SScan
- SCard
- SIsMember
-
ZSet
- ZAdd
- ZRem
- ZScoreRange
- ZScore
- ZCard
- ZIsMember
- ZTop



