Golang mongo驱动程序性能

时间:2019-10-16 09:36:24

标签: mongodb performance go

我已经编写了一些测试mongodb的代码。 但是它的速度是如此糟糕。 怎么了?

func mgoSpeedTest(N int) int64 {
    session, err := mgo.Dial(MongoHost)
    if err != nil {
        panic(err)
    }
    defer session.Close()
    session.SetMode(mgo.Monotonic, true)

    start := time.Now()
    for i := 0; i < N; i++ {
        sessionCopy := session.Copy()
        c := session.DB(MongoDB).C(MongoCol)
        _, err = c.Find(bson.M{"id": 1}).Count()
        if err != nil {
            log.Fatal(err)
        }
        sessionCopy.Close()
    }
    t := time.Now()
    elapsed := t.Sub(start)
    return elapsed.Milliseconds()
}

func main() {
    // speed test
    N := 1000
    ms = mgoSpeedTest(N)
    println(fmt.Sprintf("mgo: %d", ms))
}

答案~~ 3500ms 我尝试使用mongo-client,但是速度是相同的〜3700-3800

1 个答案:

答案 0 :(得分:1)

  

重要

     

令我非常沮丧的是,我不能建议再使用mgo,因为它似乎是no longer maintained as of the time of this writing

我很好奇,并编写了一些自己的基准。它通过docker使用单个实例MongoDB:

$ docker run -d --name mongobench -p 27017:27017 mongo
731e5f57d677718244c2304a992abd44a5a4bbad6f1fd8e5a23e53b3c4f9ada4
  

注意:您获得的哈希值将有所不同。

根据基准,它有两个方面:简单插入和批量插入。批量插入是处理大量插入的首选方法。

它同时测试mgo驱动程序和mongo-go-driver:

package mongobench

// Use
//  docker run -d --name mongobench -p 27017:27017 mongo
// to create a suitable test instance and access it via
//  docker exec -it mongobench mongo

import (
    "context"
    "log"
    "testing"

    "github.com/globalsign/mgo"
    "github.com/globalsign/mgo/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

const DefaultHost = "localhost:27017"
const DefaultDB = "test"
const DefaultCollection = "bench"

var sess *mgo.Session
var client *mongo.Client

func init() {
    var err error

    sess, err = mgo.Dial(DefaultHost)
    if err != nil {
        log.Fatalf("setting up session: %s", err)
    }

    client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://" + DefaultHost))
    if err != nil {
        log.Fatalf("setting up client: %s", err)
    }

    if err = client.Connect(context.Background()); err != nil {
        log.Fatalf("connecting with client: %s", err)
    }
}
func BenchmarkMgoInsert(b *testing.B) {

    c := sess.DB(DefaultDB).C("simple")
    if _, err := c.RemoveAll(bson.M{}); err != nil {
        b.Logf("cleaning collection 'simple': %s", err)
        b.FailNow()
    }

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        if err := c.Insert(&Data{ID: bson.NewObjectId(), Counter: i}); err != nil {
            b.Logf("error inserting: %s", err)
            b.FailNow()
        }
    }
}

func BenchmarkMgoBulk(b *testing.B) {
    c := sess.DB(DefaultDB).C("bulk")
    if _, err := c.RemoveAll(bson.M{}); err != nil {
        b.Logf("cleaning collection 'simple': %s", err)
        b.FailNow()
    }

    b.ResetTimer()

    bulk := c.Bulk()

    for i := 0; i < b.N; i++ {
        bulk.Insert(&Data{ID: bson.NewObjectId(), Counter: i})
    }

    if _, err := bulk.Run(); err != nil {
        b.Logf("executing bulk: %s", err)
        b.FailNow()
    }
}

func BenchmarkMongoInsert(b *testing.B) {
    c := client.Database(DefaultDB).Collection("mongosimple")
    if _, err := c.DeleteMany(context.Background(), bson.M{}); err != nil {
        b.Logf("cleaning collection 'mongosimple': %s", err)
        b.FailNow()
    }

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        c.InsertOne(context.Background(), &Data{ID: bson.NewObjectId(), Counter: i})
    }
}

func BenchmarkMongoBulk(b *testing.B) {

    c := client.Database(DefaultDB).Collection("mongobulk")
    if _, err := c.DeleteMany(context.Background(), bson.M{}); err != nil {
        b.Logf("cleaning collection 'mongosimple': %s", err)
        b.FailNow()
    }

    d := make([]mongo.WriteModel, b.N)

    b.ResetTimer()

    for i := 0; i < b.N; i++ {
        d[i] = mongo.NewInsertOneModel().SetDocument(Data{ID: bson.NewObjectId(), Counter: i})
    }

    if _, err := c.BulkWrite(context.Background(), d); err != nil {
        b.Logf("inserting bulk: %s", err)
        b.FailNow()
    }

}
goos: darwin
goarch: amd64
pkg: github.com/mwmahlberg/so-mongobench
BenchmarkMgoInsert-4            1164       1100919 ns/op        1501 B/op         44 allocs/op
BenchmarkMgoBulk-4            201560          6512 ns/op         258 B/op          4 allocs/op
BenchmarkMongoInsert-4          1171       1019140 ns/op        3642 B/op         66 allocs/op
BenchmarkMongoBulk-4          181040          7251 ns/op        1151 B/op         15 allocs/op

我们可以看到,两个驱动程序的速度都比您描述的快几个数量级,因此可以肯定地认为不是造成延迟的驱动程序。