Golang Go语言中的性能怪兽--badger key value db

发布于 1周前 作者 sinazl 来自 Go语言

##key value db 中的性能怪兽--badger

###前言

对于我来说今天是个值得庆祝的日子,因为本公众号迎来了很多新的朋友。在此也希望我的原创文章 能带给你们越来越多的干货,另外回答一下老铁们比较关心的问题:“是否会有从入门到精通的教程?”,我的回答是 一定会有,但不是 入门到精通 ,而是 入门到大数据项目实战 并且最近就会整理出课表分享给大家。也希望老铁们持续关注,并给我留言转发(留言可以直接给该公众号发文字消息,因为腾讯把留言功能暂时关闭了,什么时候开放暂时不清楚)。

###简介

Badger

大数据中常用到一类工具就是 key-value db,今天我就给大家介绍一下 badger, 一个可嵌入,持久,简单,快速的键值( KV )存储,并且是用纯 Go 编写(没有 CGO )。Badger 在进行随机读取时比 RocksDB 快至少 3.5 倍。 对于 128B 到 16KB 之间的数据量,数据加载速度是 RocksDB 的 0.86x - 14 倍。

We call it Badger. Based on benchmarks, Badger is at least 3.5x faster than RocksDB when doing random reads. For value sizes between 128B to 16KB, data loading is 0.86x - 14x faster compared to RocksDB, with Badger gaining significant ground as value size increases. On the flip side, Badger is currently slower for range key-value iteration, but that has a lot of room for optimization.

###优势

Badger 的优势很明显,叫它性能怪兽是有原因的:

urthermore, during benchmarking, we found that Badger ’ s LSM tree is so small, it can easily fit in RAM. For 1KB values and 75 million 22 byte keys, the raw size of the entire dataset is 72 GB. Badger ’ s LSM tree size for this setup is a mere 1.7G, which can easily fit into RAM. This is what causes Badger ’ s random key lookup performance to be at least 3.5x faster, and Badger ’ s key-only iteration to be blazingly faster than RocksDB.

  • 随机读取速度快

  • 可直接嵌入应用

  • 使用简单方便

  • 支持多种加载模式

  • 针对 SSD 优化加成

  • 纯 Go 编写

  • 基于 LSM-tree 更小巧

###劣势

劣势在官方网站上也有相关说明(如下),对于不支持集群的问题可以考虑一下 Apple 最近开源的 Foundationdb

On the flip side, Badger is currently slower for range key-value iteration, but that has a lot of room for optimization.

  • 迭代速度比较慢

  • 不支持集群

  • 不可多个应用同时操作数据库

###性能

###应用

####打开数据库

打开数据时有三种加载模式,默认模式是传统的文件 IO,:


const (
   // FileIO indicates that files must be loaded using standard I/O
   FileIO FileLoadingMode = iota
   // LoadToRAM indicates that file must be loaded into RAM
   LoadToRAM
   // MemoryMap indicates that that the file must be memory-mapped
   MemoryMap
)

func GetDB(path string) *badger.DB { opts := badger.DefaultOptions opts.Dir = path opts.ValueDir = path opts.TableLoadingMode = options.FileIO db, err := badger.Open(opts) if err != nil { fmt.Println(“Open db failed:”, err.Error()) return nil } return db }

####set 数据

set 数据都是以 byte 数组的形式入参,毕竟什么样的数据都可以转成[]byte,此处可以封装一下缓存来提高插入数据的效率和性能.


func Set(k []byte, v []byte) {
   db.DB.Update(func(tx *badger.Txn) error {
      err := tx.Set(k, v)
      if err != nil {
         fmt.Println("Key-value db set value failed : ", err.Error())
         return err
      }
      return nil
   })
}

####get 数据


func  Get(k []byte) ([]byte, error) {
   var r []byte
   err := db.DB.View(func(tx *badger.Txn) error {
  item, err := tx.Get(k)
  if err != nil {
     return err
  } else {
     r, err = item.Value()
     if err != nil {
        return err
     }
  }
  return nil

}) return r, err }

####遍历数据

遍历数据的效率其实也没有想象中那么差,100 万的数据,Key 的长度为 50 个随机字母,遍历完成的时间是 2 分 03 秒,我们项目上对这个速度已经是比较满意的啦。


 db.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()
      v, err := item.Value()
      if err != nil {
         return err
      }
      fmt.Printf("%s  key=%s, value=%s\n",time.Now().Format("2006-01-02 15:04:05"), k, v)
   }
   return nil
})

####Prefix

Badger 当然也支持 Prefix 扫描遍历:


db.View(func(txn *badger.Txn) error {
  it := txn.NewIterator(badger.DefaultIteratorOptions)
  defer it.Close()
  prefix := []byte("1234")
  for it.Seek(prefix); it.ValidForPrefix(prefix); it.Next() {
    item := it.Item()
    k := item.Key()
    v, err := item.Value()
    if err != nil {
      return err
    }
    fmt.Printf("key=%s, value=%s\n", k, v)
  }
  return nil
})


Golang Go语言中的性能怪兽--badger key value db

更多关于Golang Go语言中的性能怪兽--badger key value db的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

比 rocksdb 快? 别扯了。

更多关于Golang Go语言中的性能怪兽--badger key value db的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


rocksdb 15w/s 随机读写, 用的还是 21w iops 的渣渣 ssd。

那 badger 是多少呢?

#4 这就是个 toy project, 还有那个 boltdb, 线上一用各方面渣到哭。

bolt 的写入性能极其不好,这是和实现方式有关的。反正我比较了一把,最好还是选择了 rocksdb.badger 这个玩具真的还是不太适合线上,印象中性能也不怎么滴

php 怎么用?

那有什么推荐的吗?

rocksdb,比较成熟稳定

针对帖子“Golang Go语言中的性能怪兽——Badger Key Value DB”,以下是我的专业回复:

BadgerDB确实是一个在Go语言社区中广受赞誉的高性能键值数据库。它完全由Go语言编写,旨在提供嵌入式、持久化、简单且快速的键值存储解决方案。以下是我对BadgerDB的一些关键特性的归纳:

  1. 高性能:BadgerDB经过精心调优,无论是读操作还是写操作,都能表现出卓越的性能。这使得它成为追求高速度、低延迟场景下的理想选择。
  2. 事务支持:BadgerDB引入了读写事务,保证了操作的原子性和一致性,这对于数据完整性至关重要。
  3. 内存管理:BadgerDB拥有智能的垃圾回收机制,能够减少运行时的内存压力,提高整体效率。同时,通过配置选项,用户可以限制内存使用,避免系统性能下降。
  4. 易于集成:BadgerDB提供了丰富的API和详尽的文档,降低了学习成本,使得开发者可以轻松集成并利用其特性。
  5. 高可定制性:BadgerDB允许用户调整诸如预取大小等参数,以适应不同的工作负载需求。

综上所述,BadgerDB凭借其出色的性能、事务支持、内存管理以及易于集成和高可定制性等特点,在Go语言社区中赢得了广泛的认可。如果你正在寻找一种高性能的键值数据库解决方案,BadgerDB绝对值得尝试。

回到顶部