【问题标题】:Why is collection.InsertOne so slow at inserting the first element?为什么 collection.InsertOne 在插入第一个元素时这么慢?
【发布时间】:2019-08-01 01:10:32
【问题描述】:

我正在为 Go 测试新的官方 MongoDB 驱动程序,我注意到第一次调用 collection.InsertOne 总是需要大量时间,而所有后续调用都非常快。为什么?以及如何避免这种破坏性行为?

package main

import (
    "context"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

type Trainer struct {
    Name string
    Age  int
    City string
}

func main() {

    t1 := time.Now()

    // Set client options
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")

    log.Println("Setting client options took", time.Now().Sub(t1))
    t1 = time.Now()

    // Connect to MongoDB
    client, err := mongo.Connect(context.TODO(), clientOptions)
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Connecting took", time.Now().Sub(t1))
    t1 = time.Now()

    // Some dummy data to add to the Database
    ash := Trainer{"Ash", 30, "Pallet Town"}

    // Get a handle for your collection
    collection := client.Database("test").Collection("trainers")
    // Insert a single document

    log.Println("Getting the collection took", time.Now().Sub(t1))
    t1 = time.Now()

    for i := 0; i < 10; i++ {
        _, err := collection.InsertOne(context.TODO(), ash)
        if err != nil {
            log.Fatal(err)
        }
        log.Println("Inserting document took", time.Now().Sub(t1))
        t1 = time.Now()
    }

    err = client.Disconnect(context.TODO())

}

我预计所有插入操作都需要毫秒或纳秒,而第一个操作大约需要 0.6 秒。这是带有时间的日志:

2019/07/31 17:41:39 Setting client options took 0s
2019/07/31 17:41:39 Connecting took 0s
2019/07/31 17:41:39 Getting the collection took 0s
2019/07/31 17:41:40 Inserting document took 606.0339ms
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 875.2µs
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s
2019/07/31 17:41:40 Inserting document took 0s

【问题讨论】:

  • 可能是lazy connection?
  • 我不这么认为。官方的 MongoDB 驱动文档没有提到任何惰性连接,也没有任何配置非惰性连接的方法;此外,即使您预先调用 client.Ping(context.TODO(), nil) - 这将强制建立连接 - 第一个 InsertOne 仍然很慢。
  • 大多数 DB 驱动程序执行延迟连接。尝试使用错误的密码。连接会创建得很好,但第一个查询会失败(因为延迟连接启动)。
  • 要通过 noop 操作强制连接,请尝试 Ping()。
  • 你们是对的。我添加了 Ping() 但我做错了,最终得到了 2 个数据库连接对象,其中只有一个被“ping”了。 Ping() 正确的对象解决了这个问题。谢谢!

标签: mongodb performance go


【解决方案1】:

只是为了结束 cmets 的问题:

MongoDB 驱动程序使用lazy connection。具体见MongoDB docs

调用 Connect 不会阻止服务器发现。如果你想 知道是否已找到并连接到 MongoDB 服务器,使用 Ping 方法:

ctx, _ = context.WithTimeout(context.Background(), 2*time.Second)
err = client.Ping(ctx, readpref.Primary())

这将强制连接并从您的第一次插入中移除插入延迟。

【讨论】:

  • 此外,这让您有机会尽早处理连接问题。
猜你喜欢
  • 1970-01-01
  • 2012-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
相关资源
最近更新 更多