项目作者: gqcn

项目描述 :
[mirror] Go语言开发的基于DRH(Deep-Re-Hash)深度哈希分区算法的高性能高可用Key-Value嵌入式事务数据库。基于纯Go语言实现,具有优异的跨平台性,良好的高可用及文件IO复用设计,高效的底层数据库文件操作性能,支持原子操作、批量操作、事务操作、多表操作、多表事务、随机遍历等特性。
高级语言: Go
项目地址: git://github.com/gqcn/gkvdb.git


gkvdb

Go语言开发的基于DRH(Deep-Re-Hash)深度哈希分区算法的高性能高可用Key-Value嵌入式事务数据库。
gkvdb是开源的,免费的,基于MIT协议进行分发,开源项目地址(gitee与github仓库保持实时同步):
Gitee( https://gitee.com/johng/gkvdb ),Github( https://github.com/johng-cn/gkvdb )。

特点

  1. 基于纯Go语言实现,具有优异的跨平台性;
  2. 数据库文件采用DRH算法设计,提升对随机数据的操作性能;
  3. 良好的IO复用设计,提升对底层数据库文件的操作性能;
  4. 良好的高可用设计,保证在任何异常情况下数据的完整性;
  5. 提供的基本操作接口:Set()、Get()、Remove();
  6. 提供的事务操作接口:Begin()、Commit()、Rollback();
  7. 提供的多表操作接口:Table()、SetTo()、GetFrom()、RemoveFrom();
  8. 支持原子操作、批量操作、事务操作、多表操作、多表事务、随机遍历等特性;

限制

  1. (默认)表名最长 255B;
  2. (默认)键名最长 255B;
  3. (默认)键值最长 16MB;
  4. (默认)单表数据 1TB;
  5. 支持随机遍历,不支持范围遍历;
  6. 嵌入式数据库,没有内置C/S架构;

文档

  1. https://godoc.org/github.com/johng-cn/gkvdb/gkvdb
  2. gkvdb的介绍及设计

安装

  1. go get -u gitee.com/johng/gf
  2. go get -u gitee.com/johng/gkvdb

使用

1、基本用法

  1. import "gitee.com/johng/gkvdb/gkvdb"
  2. // 创建数据库,指定数据库存放目录
  3. // gkvdb支持多表,默认数据表名称为default
  4. db, err := gkvdb.New("/tmp/gkvdb")
  5. if err != nil {
  6. fmt.Println(err)
  7. }
  8. key := []byte("name")
  9. value := []byte("john")
  10. // 插入数据
  11. if err := db.Set(key, value); err != nil {
  12. fmt.Println(err)
  13. }
  14. // 查询数据
  15. fmt.Println(db.Get(key))
  16. // 删除数据
  17. if err := db.Remove(key); err != nil {
  18. fmt.Println(err)
  19. }
  20. // 关闭数据库链接,让GC自动回收数据库相关资源
  21. db.Close()

2、事务操作

  1. // 开启事务
  2. tx := db.Begin()
  3. // 事务写入
  4. tx.Set(key, value)
  5. // 事务查询
  6. fmt.Println(tx.Get(key))
  7. // 事务提交
  8. tx.Commit()
  9. // 事务删除
  10. tx.Remove(key)
  11. // 事务回滚
  12. tx.Rollback()

3、批量操作

  1. // 批量操作需要使用事务来实现
  2. tx := db.Begin()
  3. // 批量写入
  4. for i := 0; i < 100; i++ {
  5. key := []byte("k_" + strconv.Itoa(i))
  6. value := []byte("v_" + strconv.Itoa(i))
  7. tx.Set(key, value)
  8. }
  9. tx.Commit()
  10. // 批量删除
  11. for i := 0; i < 100; i++ {
  12. key := []byte("k_" + strconv.Itoa(i))
  13. tx.Remove(key)
  14. }
  15. tx.Commit()

4、多表操作

  1. // 创建user表
  2. name := "user"
  3. tu, err := db.Table(name)
  4. if err != nil {
  5. fmt.Println(err)
  6. }
  7. // user表写入数据
  8. tu.Set([]byte("user_0"), []byte("name_0"))
  9. // user表查询数据
  10. fmt.Println(tu.Get([]byte("user_0")))
  11. // user表删除数据
  12. tu.Remove([]byte("user_0"))
  13. // 通过db对象操作user表写入数据
  14. db.SetTo([]byte("user_1"), []byte("name_1"), name)
  15. // 通过db对象操作user表查询数据
  16. fmt.Println(db.GetFrom([]byte("user_1"), name))
  17. // 通过db对象操作user表删除数据
  18. db.RemoveFrom([]byte("user_1"), name)
  19. // 手动关闭表,释放表资源
  20. // 一般不用手动关闭,在数据库关闭时会自动关闭所有的表
  21. tu.Close()

5、多表事务

  1. // 两张表
  2. name1 := "user1"
  3. name2 := "user2"
  4. // 创建事务对象
  5. tx := db.Begin()
  6. // 事务操作user表写入数据
  7. tx.SetTo([]byte("user_1"), []byte("name_1"), name1)
  8. tx.SetTo([]byte("user_2"), []byte("name_2"), name2)
  9. // 事务操作user表查询数据
  10. fmt.Println("tx get1:", tx.GetFrom([]byte("user_1"), name1))
  11. fmt.Println("tx get2:", tx.GetFrom([]byte("user_2"), name2))
  12. tx.Commit()
  13. fmt.Println("db get1:", db.GetFrom([]byte("user_1"), name1))
  14. fmt.Println("db get2:", db.GetFrom([]byte("user_2"), name2))
  15. // 事务操作user表删除数据
  16. tx.RemoveFrom([]byte("user_1"), name1)
  17. tx.RemoveFrom([]byte("user_2"), name2)
  18. fmt.Println("tx removed1:",tx.GetFrom([]byte("user_1"), name1))
  19. fmt.Println("tx removed2:",tx.GetFrom([]byte("user_2"), name2))
  20. // 删除操作将被回滚
  21. tx.Rollback()
  22. // 重新查询
  23. fmt.Println("tx get1:", tx.GetFrom([]byte("user_1"), name1))
  24. fmt.Println("tx get2:", tx.GetFrom([]byte("user_2"), name2))
  25. fmt.Println("db get1:", db.GetFrom([]byte("user_1"), name1))
  26. fmt.Println("db get2:", db.GetFrom([]byte("user_2"), name2))

6、随机遍历

  1. // ======默认default表的遍历=====
  2. // 随机获取10条数据
  3. fmt.Println(db.Items(10))
  4. // 获取所有的键值对数据
  5. fmt.Println(db.Items(-1))
  6. // 获取所有的键键名
  7. fmt.Println(db.Keys(-1))
  8. // 获取所有的键键值
  9. fmt.Println(db.Values(-1))
  10. // ======指定表的遍历=====
  11. t1, err := db.Table("user1")
  12. if err != nil {
  13. fmt.Println(err)
  14. }
  15. t2, err := db.Table("user2")
  16. if err != nil {
  17. fmt.Println(err)
  18. }
  19. for i := 0; i < 10; i++ {
  20. key := []byte("k_" + strconv.Itoa(i))
  21. value := []byte("v_" + strconv.Itoa(i))
  22. t1.Set(key, value)
  23. }
  24. for i := 10; i < 20; i++ {
  25. key := []byte("k_" + strconv.Itoa(i))
  26. value := []byte("v_" + strconv.Itoa(i))
  27. t2.Set(key, value)
  28. }
  29. fmt.Println(t1.Items(-1))
  30. fmt.Println(t2.Items(-1))

性能

  1. john@workstation:~/gkvdb/gkvdb_test/benchmark_test$ go test *.go -bench=".*"
  2. goos: linux
  3. goarch: amd64
  4. BenchmarkSet-8 300000 5130 ns/op
  5. BenchmarkGet-8 1000000 9628 ns/op
  6. BenchmarkRemove-8 500000 4053 ns/op
  7. PASS
  8. ok command-line-arguments 13.964s

计划

v2.10

  1. 1. 改进binlog文件结构设计(增加checksum字段),binlog写入流程增加checksum检查;
  2. 2. 再次梳理碎片管理器设计,看有无进一步性能提升空间;
  3. 3. 再次梳理文件指针池设计,看有无进一步性能提升空间;

v2.50

  1. 1. 底层数据库文件结构中无需增加checksum字段,也无需增加checksum检查;
  2. 2. 但是在数据同步线程中需要增加数据的checksum检查(数据写入后再读取校验判断,保证严格的数据正确性);
  3. 3. 底层数据文件设计考虑是否增加多文件支持(文件采用分区?),以便于多线程并发同步数据,提高数据同步及文件写入性能;

v3.00

  1. 1. 增加LRU热点缓存特性;
  2. 2. 增加自动过期KV特性支持;

贡献

gkvdb是开源的、免费的软件,这意味着任何人都可以为其开发和进步贡献力量。
gkvdb的项目源代码目前同时托管在 Gitee 和 Github 平台上,您可以选择您喜欢的平台来 fork 项目和合并你的贡献,两个平台的仓库将会保持即时的同步。
我们非常欢迎有更多的朋友加入到gkvdb的开发中来,您为gkvdb所做出的任何贡献都将会被记录到gkvdb的史册中。