Badger简单使用

badger 是 dgraph 开源的 LSMTree 的 KV 引擎,它相比 leveldb 有 KV 分离、事务、并发合并等增强,是 go 生态中比较生产级的存储引擎了。

要开始使用 Badger,请安装 Go 1.12 或更高版本。

go get github.com/dgraph-io/badger/v3

注意:Badger 不直接使用 CGO,但它依赖于https://github.com/DataDog/zstd进行压缩,并且需要 gcc/cgo。如果你想在没有 gcc/cgo 的情况下使用 badger,你可以运行 CGO_ENABLED=0 go get github.com/dgraph-io/badger/…它将下载不支持 ZSTD 压缩算法的 badger。

cd badger-/badger
go install

这会将 badger 命令行实用程序安装到您的 $GOBIN 路径中。

打开数据库

func Open(path string) (*badger.DB, error) {
    if _, err := os.Stat(path); os.IsNotExist(err) {
        os.MkdirAll(path, 0755)
    }
    opts := badger.DefaultOptions(path)
    opts.Dir = path
    opts.ValueDir = path
    opts.SyncWrites = false
    opts.ValueThreshold = 256
    opts.CompactL0OnClose = true
    db, err := badger.Open(opts)
    if err != nil {
        log.Println("badger open failed", "path", path, "err", err)
        return nil, err
    }
    return db, nil
}

内存模式/无盘模式

默认情况下,Badger 确保所有数据都保存在磁盘上。它还支持纯内存模式。当 Badger 在内存模式下运行时,所有数据都存储在内存中。在内存模式下读写速度要快得多,但在崩溃或关闭的情况下,存储在 Badger 中的所有数据都会丢失。要在内存模式下打开 badger,请设置 InMemory选项。

opts := badger.DefaultOptions(path).WithInMemory(true)

关闭数据库

func Close() {
    err := badgerDB.Close()
    if err == nil {
        log.Println("database closed", "err", err)
    } else {
        log.Println("failed to close database", "err", err)
    }
}

写入数据

要保存键/值对,请使用以下 Txn.Set()方法;

键/值对也可以通过首先创建来保存 Entry,然后 Entry使用 Txn.SetEntry(). Entry还公开了在其上设置属性的方法。

func Set(key []byte, value []byte) {
    wb := badgerDB.NewWriteBatch()
    defer wb.Cancel()
    err := wb.SetEntry(badger.NewEntry(key, value).WithMeta(0))
    if err != nil {
        log.Println("Failed to write data to cache.","key", string(key), "value", string(value), "err", err)
    }
    err = wb.Flush()
    if err != nil {
        log.Println("Failed to flush data to cache.","key", string(key), "value", string(value), "err", err)
    }
}

设置TTL的写入数据

Badger 允许在键上设置可选的生存时间 (TTL) 值。一旦 TTL 过去,密钥将不再可检索,并且将有资格进行垃圾收集。 可以使用和API 方法将 TTL 设置为 time.Duration值。 Entry.WithTTL() Txn.SetEntry()

func SetWithTTL(key []byte, value []byte, ttl int64) {
    wb := badgerDB.NewWriteBatch()
    defer wb.Cancel()
    err := wb.SetEntry(badger.NewEntry(key, value).WithMeta(0).WithTTL(time.Duration(ttl * time.Second.Nanoseconds())))
    if err != nil {
        log.Println("Failed to write data to cache.","key", string(key), "value", string(value), "err", err)
    }
    err = wb.Flush()
    if err != nil {
        log.Println("Failed to flush data to cache.","key", string(key), "value", string(value), "err", err)
    }
}

读取数据

要读取数据,我们可以使用以下 Txn.Get()方法。

func Get(key []byte) string {
    var ival []byte
    err := badgerDB.View(func(txn *badger.Txn) error {
        item, err := txn.Get(key)
        if err != nil {
            return err
        }
        ival, err = item.ValueCopy(nil)
        return err
    })
    if err != nil {
        log.Println("Failed to read data from the cache.","key", string(key), "error", err)
    }
    return string(ival)
}

存在键

func Has(key []byte) (bool, error) {
    var exist bool = false
    err := badgerDB.View(func(txn *badger.Txn) error {
        _, err := txn.Get(key)
        if err != nil {
            return err
        } else {
            exist = true
        }
        return err
    })
    // align with leveldb, if the key doesn't exist, leveldb returns nil
    if strings.HasSuffix(err.Error(), "not found") {
        err = nil
    }
    return exist, err
}

删除键

使用 Txn.Delete()方法删除 key。

func Delete(key []byte) error {
    wb := badgerDB.NewWriteBatch()
    defer wb.Cancel()
    return wb.Delete(key)
}

遍历key和value

要迭代键,我们可以使用 Iterator,可以使用 Txn.NewIterator()方法获得。迭代以按字节排序的字典顺序发生。

func IteratorKeysAndValues(){

    err := badgerDB.View(func(txn *badger.Txn) error {
        opts := badger.DefaultIteratorOptions
        opts.PrefetchSize = 10
        it := txn.NewIterator(opts)
        defer it.Close()
        for it.Rewind(); it.Valid(); it.Next() {
            item := it.Item()
            k := item.Key()
            err := item.Value(func(v []byte) error {
                fmt.Printf("key=%s, value=%s\n", k, v)
                return nil
            })
            if err != nil {
                return err
            }
        }
        return nil
    })
    if err != nil {
        log.Println("Failed to iterator keys and values from the cache.","error", err)
    }
}

遍历keys

Badger 支持一种独特的迭代模式,称为 _key-only_迭代。它比常规迭代快几个数量级,因为它只涉及对 LSM 树的访问,它通常完全驻留在 RAM 中。要启用仅键迭代,您需要将该 IteratorOptions.PrefetchValues 字段设置为 false. 这也可用于在迭代期间对选定键进行稀疏读取, item.Value()仅在需要时调用。

func IteratorKeys(){
    err := badgerDB.View(func(txn *badger.Txn) error {
        opts := badger.DefaultIteratorOptions
        opts.PrefetchValues = false
        it := txn.NewIterator(opts)
        defer it.Close()
        for it.Rewind(); it.Valid(); it.Next() {
            item := it.Item()
            k := item.Key()
            fmt.Printf("key=%s\n", k)
        }
        return nil
    })

    if err != nil {
        log.Println("Failed to iterator keys from the cache.","error", err)
    }
}

前缀扫描

要遍历一个键前缀,您可以组合 Seek()and ValidForPrefix()

func SeekWithPrefix(prefixStr string){
    err := badgerDB.View(func(txn *badger.Txn) error {
        it := txn.NewIterator(badger.DefaultIteratorOptions)
        defer it.Close()
        prefix := []byte(prefixStr)
        for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
            item := it.Item()
            k := item.Key()
            err := item.Value(func(v []byte) error {
                fmt.Printf("key=%s, value=%s\n", k, v)
                return nil
            })
            if err != nil {
                return err
            }
        }
        return nil
    })
    if err != nil {
        log.Println("Failed to seek prefix from the cache.", "prefix", prefixStr,"error", err)
    }
}

Original: https://www.cnblogs.com/dawn-lewis/p/16055348.html
Author: DawnLewis
Title: Badger简单使用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516390/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 记一次提升18倍的性能优化

    背景 最近负责的一个自研的 Dubbo 注册中心经常收到 CPU 使用率的告警,于是进行了一波优化,效果还不错,于是打算分享下思考、优化过程,希望对大家有一些帮助。 自研 Dubb…

    Go语言 2023年5月25日
    079
  • Minio SDK访问Bucket的策略配置

    配置用户来访问 Bucket Minio 是高性能的对象存储服务,基于golang开发的,可以本地部署。用它来管理自己系统中的上传下载的文件很方便。​ 通过 SDK 访问 Mini…

    Go语言 2023年5月25日
    087
  • sync:二. 延迟初始化(once)

    sync.Once 是 Go 标准库提供的使函数只执行一次的实现。作用与 init 函数类似,但有区别。在某些情况下预先初始化一个变量会增加函数的启动延迟,如果实际执行时可能用不上…

    Go语言 2023年5月25日
    079
  • 紫色飞猪的研发之旅–06go自定义状态码

    在实际开发中,需要前后端需要协商状态码,状态码用于后端返前端时使用。在一个团队中,定义的状态码讲道理应该是一致的,项目开始的起始阶段状态码应该是定义了个七七八八的,随着功能的叠加而…

    Go语言 2023年5月25日
    071
  • golang实现一个简单的websocket聊天室

    基本原理:1.引入了 golang.org/x/net/websocket 包。2.监听端口。3.客户端连接时,发送结构体: {“type”:”…

    Go语言 2023年5月25日
    080
  • GO环境配置

    一、环境安装及配置 引用链接:Go语言环境安装及配置 Go版本安装 百度网盘msi地址:版本v1.18.1提取码:m1mc GoLand工具 链接:【版本2020.1】提取码:7x…

    Go语言 2023年5月25日
    081
  • 自己实现一个Controller——标准型

    标准Controller 上一篇通过一个简单的例子,编写了一个controller-manager,以及一个极简单的controller。从而对controller的开发有个最基本…

    Go语言 2023年5月25日
    089
  • Golang使用swaggo自动生成Restful API文档

    相信很多程序猿和我一样不喜欢写API文档。写代码多舒服,写文档不仅要花费大量的时间,有时候还不能做到面面具全。但API文档是必不可少的,相信其重要性就不用我说了,一份含糊的文档甚至…

    Go语言 2023年5月25日
    062
  • Go – 关于 protoc 工具的小疑惑

    protoc 工具可以干什么? protoc 工具可以 通过相关插件 将 .proto 文件编译成 C、 C++、 Golang、 Java、 Python、 PHP 等多种语言的…

    Go语言 2023年5月25日
    057
  • Go语言之高级篇Beego框架之爬虫项目实战

    一、爬虫项目 1、爬虫基础 a、网页上面会有相同的数据 b、去重处理 布隆过滤器哈希存储 c、标签匹配: 正则表达式beautiful soup或lxml这种标签提取库 d、动态内…

    Go语言 2023年5月29日
    061
  • Go语言内置函数大全

    https://studygolang.com/articles/1708 Original: https://www.cnblogs.com/answercard/p/12574…

    Go语言 2023年5月29日
    063
  • go tool – 快速生成CHANGELOG.md

    在git项目中,通过添加CHANGELOG.md可以展示项目的版本更新记录,方便用户查看项目的重大bug修复或不兼容版本信息。 安装: 打开项目目录运行 或者通过命令行指定项目目录…

    Go语言 2023年5月25日
    070
  • Maglev : A Fast and Reliable Software Network Load Balancer (using Consistent Hashing)

    前言(为什么想读这一篇论文) 这一篇论文吸引我注意的原因是,Consistent Hashing ;本来的特性就是作为分布式缓存之用。谷歌将他们的负载均衡器(代号:Maglev)发…

    Go语言 2023年5月25日
    063
  • go 错误处理设计思考

    前段时间准备对线上一个golang系统服务进行内部开源,对代码里面的错误处理进行了一波优化。 优化的几个原因: 错误处理信息随意,未分类未定义。看到错误日志不能第一时间定位 错误的…

    Go语言 2023年5月25日
    059
  • go微服务框架Kratos笔记(五)使用nacos作为服务注册和服务发现中心

    引言 上篇介绍了如何使用nacos作为配置管理中心,并使用viper来解析配置官方介绍nacos不仅可以用来做配置中心还支持服务注册、发现以及动态DNS服务功能 nacos的安装 …

    Go语言 2023年5月25日
    055
  • B树-查找

    B树系列文章 1. B树-介绍 2. B树-查找 3. B树-插入 4. B树-删除 查找 假设有一棵3阶B树,如下图所示。 下面说明在该B树中查找 52的过程 首先,从根结点出发…

    Go语言 2023年5月25日
    067
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球