英文:
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":""}
注意:我在这里仅为示例目的更改了Username
、Password
、Server/connStr
、bucket
和id
。请问我在这里漏掉了什么?
英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论