Badger简介

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

文档:https://dgraph.io/docs/badger/get-started/

Github 地址:https://github.com/dgraph-io/badger

安装

安装 Badger

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

  1. 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。

安装 Badger 命令行工具

https://github.com/dgraph-io/badger/releases下载并提取最新的 Badger DB 版本,然后运行以下命令。

  1. cd badger-<version>/badger
  2. go install

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

数据库操作

打开数据库

  1. func Open(path string) (*badger.DB, error) {
  2. if _, err := os.Stat(path); os.IsNotExist(err) {
  3. os.MkdirAll(path, 0755)
  4. }
  5. opts := badger.DefaultOptions(path)
  6. opts.Dir = path
  7. opts.ValueDir = path
  8. opts.SyncWrites = false
  9. opts.ValueThreshold = 256
  10. opts.CompactL0OnClose = true
  11. db, err := badger.Open(opts)
  12. if err != nil {
  13. log.Println("badger open failed", "path", path, "err", err)
  14. return nil, err
  15. }
  16. return db, nil
  17. }

内存模式/无盘模式

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

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

关闭数据库

  1. func Close() {
  2. err := badgerDB.Close()
  3. if err == nil {
  4. log.Println("database closed", "err", err)
  5. } else {
  6. log.Println("failed to close database", "err", err)
  7. }
  8. }

存储操作

写入数据

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

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

  1. func Set(key []byte, value []byte) {
  2. wb := badgerDB.NewWriteBatch()
  3. defer wb.Cancel()
  4. err := wb.SetEntry(badger.NewEntry(key, value).WithMeta(0))
  5. if err != nil {
  6. log.Println("Failed to write data to cache.","key", string(key), "value", string(value), "err", err)
  7. }
  8. err = wb.Flush()
  9. if err != nil {
  10. log.Println("Failed to flush data to cache.","key", string(key), "value", string(value), "err", err)
  11. }
  12. }

设置TTL的写入数据

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

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

读取数据

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

  1. func Get(key []byte) string {
  2. var ival []byte
  3. err := badgerDB.View(func(txn *badger.Txn) error {
  4. item, err := txn.Get(key)
  5. if err != nil {
  6. return err
  7. }
  8. ival, err = item.ValueCopy(nil)
  9. return err
  10. })
  11. if err != nil {
  12. log.Println("Failed to read data from the cache.","key", string(key), "error", err)
  13. }
  14. return string(ival)
  15. }

存在键

  1. func Has(key []byte) (bool, error) {
  2. var exist bool = false
  3. err := badgerDB.View(func(txn *badger.Txn) error {
  4. _, err := txn.Get(key)
  5. if err != nil {
  6. return err
  7. } else {
  8. exist = true
  9. }
  10. return err
  11. })
  12. // align with leveldb, if the key doesn't exist, leveldb returns nil
  13. if strings.HasSuffix(err.Error(), "not found") {
  14. err = nil
  15. }
  16. return exist, err
  17. }

删除键

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

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

查询操作

遍历key和value

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

  1. func IteratorKeysAndValues(){
  2. err := badgerDB.View(func(txn *badger.Txn) error {
  3. opts := badger.DefaultIteratorOptions
  4. opts.PrefetchSize = 10
  5. it := txn.NewIterator(opts)
  6. defer it.Close()
  7. for it.Rewind(); it.Valid(); it.Next() {
  8. item := it.Item()
  9. k := item.Key()
  10. err := item.Value(func(v []byte) error {
  11. fmt.Printf("key=%s, value=%s\n", k, v)
  12. return nil
  13. })
  14. if err != nil {
  15. return err
  16. }
  17. }
  18. return nil
  19. })
  20. if err != nil {
  21. log.Println("Failed to iterator keys and values from the cache.","error", err)
  22. }
  23. }

遍历keys

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

  1. func IteratorKeys(){
  2. err := badgerDB.View(func(txn *badger.Txn) error {
  3. opts := badger.DefaultIteratorOptions
  4. opts.PrefetchValues = false
  5. it := txn.NewIterator(opts)
  6. defer it.Close()
  7. for it.Rewind(); it.Valid(); it.Next() {
  8. item := it.Item()
  9. k := item.Key()
  10. fmt.Printf("key=%s\n", k)
  11. }
  12. return nil
  13. })
  14. if err != nil {
  15. log.Println("Failed to iterator keys from the cache.","error", err)
  16. }
  17. }

前缀扫描

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

  1. func SeekWithPrefix(prefixStr string){
  2. err := badgerDB.View(func(txn *badger.Txn) error {
  3. it := txn.NewIterator(badger.DefaultIteratorOptions)
  4. defer it.Close()
  5. prefix := []byte(prefixStr)
  6. for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
  7. item := it.Item()
  8. k := item.Key()
  9. err := item.Value(func(v []byte) error {
  10. fmt.Printf("key=%s, value=%s\n", k, v)
  11. return nil
  12. })
  13. if err != nil {
  14. return err
  15. }
  16. }
  17. return nil
  18. })
  19. if err != nil {
  20. log.Println("Failed to seek prefix from the cache.", "prefix", prefixStr,"error", err)
  21. }
  22. }

Badger简单使用的更多相关文章

  1. badger 一个高性能的LSM K/V store

    原文:https://colobu.com/2017/10/11/badger-a-performant-k-v-store/ github地址:https://github.com/dgraph-i ...

  2. 【造轮子】打造一个简单的万能Excel读写工具

    大家工作或者平时是不是经常遇到要读写一些简单格式的Excel? shit!~很蛋疼,因为之前吹牛,就搞了个这东西,还算是挺实用,和大家分享下. 厌烦了每次搞简单类型的Excel读写?不怕~来,喜欢流式 ...

  3. Fabio 安装和简单使用

    Fabio(Go 语言):https://github.com/eBay/fabio Fabio 是一个快速.现代.zero-conf 负载均衡 HTTP(S) 路由器,用于部署 Consul 管理的 ...

  4. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  5. 哪种缓存效果高?开源一个简单的缓存组件j2cache

    背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...

  6. 在Openfire上弄一个简单的推送系统

    推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...

  7. 我的MYSQL学习心得(一) 简单语法

    我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...

  8. 使用 Nodejs 搭建简单的Web服务器

    使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...

  9. ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面

    前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...

随机推荐

  1. 理解Faster R-CNN

    首先放R-CNN的原理图 显然R-CNN的整过过程大致上划分为四步: 1.输入图片 2.生成候选窗口 3.对局部窗口进行特征提取(CNN) 4.分类(Classify regions) 而R-CNN的 ...

  2. mysql悬案 之 为什么用docker启动的mysql配置文件不生效

    文章目录 故事前景 查看docker启动时挂载了哪些目录 使用相同镜像启动一个mysql 新建一个目录用来存放容器内的mysql配置文件 复制容器内的mysql配置文件到本地 查看mysql配置文件目 ...

  3. SpringMVC--@RequestMapping注解标注方法解析

    SpringMVC--@RequestMapping注解标注方法解析 本文是基于springboot进行源码追踪分析 问题 @RequestMapping注释的类及方法,Spring是何时,何种方式解 ...

  4. 图解python | for循环

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/56 本文地址:http://www.showmeai.tech/article-det ...

  5. [LeetCode]1470. 重新排列数组

    给你一个数组 nums ,数组中有 2n 个元素,按 [x1,x2,...,xn,y1,y2,...,yn] 的格式排列. 请你将数组按 [x1,y1,x2,y2,...,xn,yn] 格式重新排列, ...

  6. Nginx 配置apple-app-site-association

    ios突然给我发了如上链接和一个json,说他那边需要放一个 apple-app-site-association 文件用来支持他那边的功能,文件不需要后缀. 先说一下要求:线上官网的地址后面跟上他所 ...

  7. [Python]Python入门笔记:语法基础

    Python笔记 一.基本语法 1.1 注释 文档注释: """contents""" 多行注释: ''' contents ''' 单行注 ...

  8. [GAME] [Civilization] 文明6字体及字体大小修改

    一.前言 文明作为一款文本信息量较大的游戏,提供的字体和UI界面设置还是偏少了一些,对干眼用户极不友好 二.用户界面整体缩放 首先是游戏自带的缩放选项:图象选项-图像-UI质量提升,设置为150%或更 ...

  9. WPS备份的位置

    C:\Users\Administrator\AppData\Roaming\kingsoft\office6\backup 也可以从左上图标->工具->备份管理->查看其它备份,直 ...

  10. C语言刷 堆(优先队列)

    703. 数据流中的第 K 大元素 /* 小根堆 */ typedef struct { int heapCapacity; int heapSize; int *heap; } KthLargest ...