我已经编写了一些代码来测试 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
最佳答案
我很好奇并编译了我自己的一个小基准。它通过 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"
)
type Data struct {
ID primitive.ObjectID `bson:"_id"`
Counter int
}
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
我们可以看到的是,两个驱动程序的速度都比您描述的要快几个数量级,因此可以安全地假设不是驱动程序造成了延迟。关于mongodb - Golang mongo 驱动程序性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58410216/