距离上一次gkvdb的1.81版本更新有近3个月的时间了,在这3个月期间gkvdb发生了一些比较大的变化,主要在于性能优化以及高可用设计方面,这些改进使得gkvdb成长得更加成熟稳定。本次版本更新的细节如下: v1.85 1、修正文件碎片管理问题引发的数据遍历问题(#issue IGVJA); 2、增加TODO计划,底层数据文件操作高可用优化功能待完善; v2.00 1、提前完成两项TODO计划(完善底层数据库文件操作高可用设计、文件碎片管理器的性能优化及测试); 2、调整数据表随机遍历接口为完整的数据库文件遍历,遍历过程中可识别数据完整性,返回数据完整的集合; 3、对底层数据库文件操作采用增量修改方式(以“数据新增”替换“数据修改”),以保证数据库在任何异常情况下数据的完整性,保证数据库的高可用; 4、调整binlog数据同步限制策略:将数据长度调整为大小限制,默认为当binlog队列大小(非文件大小)超过20MB时,强制执行阻塞同步; 5、binlog同步机制从间隔同步调整为采用channel队列实时同步,提高数据同步效率; 6、binlog底层频繁的多表同步操作调整为使用grpool协程池实现,提升操作性能; 7、完成gkvdb v2.0基准测试; 8、修复了几个功能性BUG; gkvdb是Go语言开发的基于DRH(Deep-Re-Hash)深度哈希分区算法的高性能高可用Key-Value嵌入式事务数据库。 特点 基于纯Go语言实现,具有优异的跨平台性; 数据库文件采用DRH算法设计,提升对随机数据的操作性能; 良好的IO复用设计,提升对底层数据库文件的操作性能; 良好的高可用设计,保证在任何异常情况下数据的完整性; 提供的基本操作接口:Set()、Get()、Remove(); 提供的事务操作接口:Begin()、Commit()、Rollback(); 提供的多表操作接口:Table()、SetTo()、GetFrom()、RemoveFrom(); 支持原子操作、批量操作、事务操作、多表操作、多表事务、随机遍历等特性; 限制 (默认)表名最长 255B; (默认)键名最长 255B; (默认)键值最长 16MB; (默认)单表数据 1TB; 支持随机遍历,不支持范围遍历; 嵌入式数据库,没有内置C/S架构; 安装 go get -u gitee.com/johng/gf go get -u gitee.com/johng/gkvdb 使用 1、基本用法 import "gitee.com/johng/gkvdb/gkvdb" // 创建数据库,指定数据库存放目录 // gkvdb支持多表,默认数据表名称为default db, err := gkvdb.New("/tmp/gkvdb") if err != nil { fmt.Println(err) } key := []byte("name") value := []byte("john") // 插入数据 if err := db.Set(key, value); err != nil { fmt.Println(err) } // 查询数据 fmt.Println(db.Get(key)) // 删除数据 if err := db.Remove(key); err != nil { fmt.Println(err) } // 关闭数据库链接,让GC自动回收数据库相关资源 db.Close() 2、事务操作 // 开启事务 tx := db.Begin() // 事务写入 tx.Set(key, value) // 事务查询 fmt.Println(tx.Get(key)) // 事务提交 tx.Commit() // 事务删除 tx.Remove(key) // 事务回滚 tx.Rollback() 3、批量操作 // 批量操作需要使用事务来实现 tx := db.Begin() // 批量写入 for i := 0; i < 100; i++ { key := []byte("k_" + strconv.Itoa(i)) value := []byte("v_" + strconv.Itoa(i)) tx.Set(key, value) } tx.Commit() // 批量删除 for i := 0; i < 100; i++ { key := []byte("k_" + strconv.Itoa(i)) tx.Remove(key) } tx.Commit() 4、多表操作 // 创建user表 name := "user" tu, err := db.Table(name) if err != nil { fmt.Println(err) } // user表写入数据 tu.Set([]byte("user_0"), []byte("name_0")) // user表查询数据 fmt.Println(tu.Get([]byte("user_0"))) // user表删除数据 tu.Remove([]byte("user_0")) // 通过db对象操作user表写入数据 db.SetTo([]byte("user_1"), []byte("name_1"), name) // 通过db对象操作user表查询数据 fmt.Println(db.GetFrom([]byte("user_1"), name)) // 通过db对象操作user表删除数据 db.RemoveFrom([]byte("user_1"), name) // 手动关闭表,释放表资源 // 一般不用手动关闭,在数据库关闭时会自动关闭所有的表 tu.Close() 5、多表事务 // 两张表 name1 := "user1" name2 := "user2" // 创建事务对象 tx := db.Begin() // 事务操作user表写入数据 tx.SetTo([]byte("user_1"), []byte("name_1"), name1) tx.SetTo([]byte("user_2"), []byte("name_2"), name2) // 事务操作user表查询数据 fmt.Println("tx get1:", tx.GetFrom([]byte("user_1"), name1)) fmt.Println("tx get2:", tx.GetFrom([]byte("user_2"), name2)) tx.Commit() fmt.Println("db get1:", db.GetFrom([]byte("user_1"), name1)) fmt.Println("db get2:", db.GetFrom([]byte("user_2"), name2)) // 事务操作user表删除数据 tx.RemoveFrom([]byte("user_1"), name1) tx.RemoveFrom([]byte("user_2"), name2) fmt.Println("tx removed1:",tx.GetFrom([]byte("user_1"), name1)) fmt.Println("tx removed2:",tx.GetFrom([]byte("user_2"), name2)) // 删除操作将被回滚 tx.Rollback() // 重新查询 fmt.Println("tx get1:", tx.GetFrom([]byte("user_1"), name1)) fmt.Println("tx get2:", tx.GetFrom([]byte("user_2"), name2)) fmt.Println("db get1:", db.GetFrom([]byte("user_1"), name1)) fmt.Println("db get2:", db.GetFrom([]byte("user_2"), name2)) 6、随机遍历 // ======默认default表的遍历===== // 随机获取10条数据 fmt.Println(db.Items(10)) // 获取所有的键值对数据 fmt.Println(db.Items(-1)) // 获取所有的键键名 fmt.Println(db.Keys(-1)) // 获取所有的键键值 fmt.Println(db.Values(-1)) // ======指定表的遍历===== t1, err := db.Table("user1") if err != nil { fmt.Println(err) } t2, err := db.Table("user2") if err != nil { fmt.Println(err) } for i := 0; i < 10; i++ { key := []byte("k_" + strconv.Itoa(i)) value := []byte("v_" + strconv.Itoa(i)) t1.Set(key, value) } for i := 10; i < 20; i++ { key := []byte("k_" + strconv.Itoa(i)) value := []byte("v_" + strconv.Itoa(i)) t2.Set(key, value) } fmt.Println(t1.Items(-1)) fmt.Println(t2.Items(-1)) 性能 john@workstation:~/gkvdb/gkvdb_test/benchmark_test$ go test *.go -bench=".*" goos: linux goarch: amd64 BenchmarkSet-8 300000 5130 ns/op BenchmarkGet-8 1000000 9628 ns/op BenchmarkRemove-8 500000 4053 ns/op PASS ok command-line-arguments 13.964s gkvdb v2.0发布,Go语言Key-Value嵌入式事务数据库下载地址