go couchbase(gocb)错误 – 模糊超时或明确超时

huangapple go评论85阅读模式
英文:

go couchbase (gocb) error - ambiguous timeout or unambiguous timeout

问题

我刚刚开始使用gocb库在Go语言中使用Couchbase。只是作为一个概念验证,尝试查询我的服务器以获取特定ID的结果。以下是修改后的代码示例:

cOpts := gocb.ClusterOptions{
	Authenticator: gocb.PasswordAuthenticator{
		Username: "user",
		Password: "pw",
	},
}

cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
if err != nil {
	panic(err)
}

qOpts := gocb.QueryOptions{}

// 创建查询
queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"

rows, err := cluster.Query(queryStr, &qOpts)
if err != nil {
	panic(err)
}

fmt.Printf("rows: %v\n", rows)

for rows.Next() {
	var intfc interface{}
	err = rows.Row(&intfc)
	if err != nil {
		panic(err)
	}
	fmt.Printf("interface result: %v\n", intfc)
}

Couchbase服务器版本为5.1。

当我运行上述代码时,可能会出现以下错误:

panic: ambiguous timeout | {"statement":"SELECT * FROM myBucketName WHERE id = '123456789'","client_context_id":"cdd52a06-c7a5-4d3d-8r26-99fg806d559e"}

或者,如果我在gocb.Connect(...之后插入以下代码行,我会得到之后的错误:

err = cluster.WaitUntilReady(25*time.Second, &gocb.WaitUntilReadyOptions{DesiredState: gocb.ClusterStateOnline})
if err != nil {
	panic(err)
}

错误信息如下:

panic: unambiguous timeout | {"InnerError":{"InnerError":{"InnerError":{},"Message":"unambiguous timeout"}},"OperationID":"WaitUntilReady","Opaque":"","TimeObserved":25000263891,"RetryReasons":["NOT_READY"],"RetryAttempts":105,"LastDispatchedTo":"","LastDispatchedFrom":"","LastConnectionID":""}

注意:我在这里仅为示例目的更改了UsernamePasswordServer/connStrbucketid。请问我在这里漏掉了什么?

英文:

I just getting started with Couchbase in Go, using the library gocb.

Just as a proof of concept trying to query my server for a specific ID and get a result. Here is a modified code sample below.

cOpts := gocb.ClusterOptions{
		Authenticator: gocb.PasswordAuthenticator{
			Username: "user",
			Password: "pw",
		},
	}

	cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
	if err != nil {
		panic(err)
	}

	qOpts := gocb.QueryOptions{}

	// create query
	queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"

	rows, err := cluster.Query(queryStr, &qOpts)
	if err != nil {
		panic(err)
	}

	fmt.Printf("rows: %v\n", rows)

	for rows.Next() {
		var intfc interface{}
		err = rows.Row(&intfc)
		if err != nil {
			panic(err)
		}
		fmt.Printf("interface result: %v\n", intfc)

	}

The couchbase server is on 5.1.

I am either getting...

panic: ambiguous timeout | {"statement":"SELECT * FROM myBucketName WHERE id = '123456789'","client_context_id":"cdd52a06-c7a5-4d3d-8r26-99fg806d559e"}

...when I run the above code.
OR
If I put in the following lines after the gocb.Connect(... I get the error that is after that.

err = cluster.WaitUntilReady(25*time.Second, &gocb.WaitUntilReadyOptions{DesiredState: gocb.ClusterStateOnline})
if err != nil {
	panic(err)
}

...error...

panic: unambiguous timeout | {"InnerError":{"InnerError":{"InnerError":{},"Message":"unambiguous timeout"}},"OperationID":"WaitUntilReady","Opaque":"","TimeObserved":25000263891,"RetryReasons":["NOT_READY"],"RetryAttempts":105,"LastDispatchedTo":"","LastDispatchedFrom":"","LastConnectionID":""}  

NOTE: I changed the Username, Password, Server/connStr, bucket, and the id just for example purposes here.

What am I missing here?

答案1

得分: 3

感谢@vsr的答案。
其他的回答都有帮助,但在我尝试了那个建议之后才起作用,即在连接之后添加cluster.Bucket("mybucket")

有一件事情被遗漏了,就是要添加一个"Bucket"名称。请参考下面的代码示例。

除了@vsr的帮助和答案之外,我在文档中找到了一些相关信息。
https://docs.couchbase.com/go-sdk/current/howtos/n1ql-queries-with-sdk.html
在Golang示例中,在开始之后的注释中提到“对于服务器版本6.5或更高版本,您不需要在此处打开一个bucket”,然后下一行打开了一个bucket。这是一个很好的信息。

    cOpts := gocb.ClusterOptions{
        Authenticator: gocb.PasswordAuthenticator{
            Username: "user",
            Password: "pw",
        },
    }

    cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
    if err != nil {
        panic(err)
    }

    bucketName := "myBucket"
    cluster.Bucket(bucketName)

    qOpts := gocb.QueryOptions{}

    // create query
    queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"

    rows, err := cluster.Query(queryStr, &qOpts)
    if err != nil {
        panic(err)
    }

    fmt.Printf("rows: %v\n", rows)

    for rows.Next() {
        var intfc interface{}
        err = rows.Row(&intfc)
        if err != nil {
            panic(err)
        }
        fmt.Printf("interface result: %v\n", intfc)
    }

只需添加cluster.Bucket("myBucket")这一行就可以使其工作。
服务器比较旧,是一个资源不足的开发服务器,所以我还增加了超时时间,以确保查询能够完成。我通过调整集群选项(代码中的cOpts)来增加超时时间,如下所示。

    cOpts := gocb.ClusterOptions{
        Authenticator: gocb.PasswordAuthenticator{
            Username: "user",
            Password: "pw",
        },
        TimeoutsConfig: gocb.TimeoutsConfig{
            ConnectTimeout: 95 * time.Second,
            QueryTimeout:   95 * time.Second,
            SearchTimeout:  95 * time.Second,
        },
    }

这将将超时时间增加到95秒,虽然我并不需要那么长时间,但是服务器的响应速度很慢,同样的查询在UI中需要40秒,所以我只是想确保能够完成查询。
我还调整了查询的超时时间。我不确定它们之间的区别是什么,但是我在下面进行了调整。

    qOpts := gocb.QueryOptions{}
    qOpts.Readonly = true
    qOpts.ScanWait = 95 * time.Second
    qOpts.Timeout = 95 * time.Second

此外,我是新手使用couchbase,查询没有使用索引字段。我查找了该bucket的索引字段,并将其添加到查询中,这样可以将查询时间减少一半以上。

编辑:
在N1QL中使用USE KEYS语句似乎非常快,比任何其他查询都要快。我调整了代码,使qryStr查询字符串如下所示...

queryStr := "SELECT * FROM myBucket USE KEYS ['123456789']"
英文:

Credit to @vsr for the answer.
All the other responses helped, but nothing worked until after I did that suggestion, adding cluster.Bucket("mybucket") after the connection.

One thing that was missing is putting in a "Bucket" name. See below...

In addition to @vsr help and answer, I just found something on the website in the docs about this.
[https://docs.couchbase.com/go-sdk/current/howtos/n1ql-queries-with-sdk.html](Couchbase Docs)
In the Golang example just after getting started, it mentions in the comments of the code that 'For server versions 6.5 or later you do not need to open a bucket here' and then the next line it opens a bucket. Good information.

    cOpts := gocb.ClusterOptions{
        Authenticator: gocb.PasswordAuthenticator{
            Username: "user",
            Password: "pw",
        },
    }

    cluster, err := gocb.Connect("couchbase://my.dev.server.net/", cOpts)
    if err != nil {
        panic(err)
    }

    bucketName := "myBucket"
    cluster.Bucket(bucketName)

    qOpts := gocb.QueryOptions{}

    // create query
    queryStr := "SELECT * FROM myBucket WHERE id = '123456789'"

    rows, err := cluster.Query(queryStr, &qOpts)
    if err != nil {
        panic(err)
    }

    fmt.Printf("rows: %v\n", rows)

    for rows.Next() {
        var intfc interface{}
        err = rows.Row(&intfc)
        if err != nil {
            panic(err)
        }
        fmt.Printf("interface result: %v\n", intfc)
    }

Just adding that cluster.Bucket("myBucket") line made this work.
The server is old, and is a dev server that has a lack of resources, so I also upped the timeouts knowing that it was going to be slow. I upped the timeouts by adjusted the cluster options (cOpts named in the code) to the following...

    cOpts := gocb.ClusterOptions{
        Authenticator: gocb.PasswordAuthenticator{
            Username: "user",
            Password: "pw",
        },
        TimeoutsConfig: gocb.TimeoutsConfig{
			ConnectTimeout: 95 * time.Second,
			QueryTimeout:   95 * time.Second,
			SearchTimeout:  95 * time.Second,
		},
    }

This would up the timeout to 95 seconds, and I didn't need that much, but the server was slow enough that it was taking 40 seconds in the UI for the same query, so I just wanted to make sure.
I also adjusted the timeout for the query. I am not sure what the difference is between them, but I adjusted this below.

	qOpts := gocb.QueryOptions{}
	qOpts.Readonly = true
	qOpts.ScanWait = 95 * time.Second
	qOpts.Timeout = 95 * time.Second

Additionally, I am new to couchbase if you couldn't tell, the query was not using an index field. I looked up the indexed fields for that bucket and added it to the query and that more than halved the time.

EDIT:
Using the USE KEYS statement in N1QL seems to be really fast, faster than any query. I adjusted the code so the qryStr query string was like below...

queryStr := "SELECT * FROM myBucket USE KEYS ['123456789']"

</details>



huangapple
  • 本文由 发表于 2022年7月22日 02:33:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/73071110.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定