我想在Golang RestApi上减少对表的访问时间.
我有一个带有enpoint的Go restAPI,它需要访问请求体中指定的每个代码的bigtable数据库.我的密钥访问设计是 "provider | client | productCode | date | .."(以及其他4个参数).
对于请求正文的每个productCode,我正在进行异步调用以读取具有指定键的行.
在我的测试中,我要求1000个产品代码,在我的本地机器上获得的时间大约是800~900ms.云计算机上的时间大约为550~450毫秒.
我正在使用bigtable包来访问bigTable,我正在使用以下代码:
package main
import (
"log"
"time"
"golang.org/x/net/context"
"google.golang.org/cloud/bigtable"
)
func main() {
start2 := time.Now()
listPKs := []string{"PROV|CLI|6030|20160714|8|30301.30302|ES", "PROV|CLI|44103|20160714|8|30301.30302|ES", "PROV|CLI|1454871|20160714|8|30301.30302|ES"}
providerRS := getBDresponse(listPKs, 50000)
if providerRS != nil {
///do something
}
elapsed2 := time.Since(start2)
log.Printf("Time access BT: %s", elapsed2)
}
func getBDresponse(listPKs []string, timeoutMiliseconds int) []string {
resp := make(chan string)
table := myClient.Client.Open(TABLE_NAME)
//async call to BT
for _, key := range listPKs {
go asyncDoUniqueCall(key, resp, myContext, table)
}
//get all responses
providerRS := getResponses(resp, timeoutMiliseconds, len(listPKs))
return providerRS
}
func asyncDoUniqueCall(pk string, ch chan string, ctx *context.Context, table *bigtable.Table) {
ch <- GetRowValue(pk, ctx, table)
}
func getResponses(resp chan string, timeoutMiliseconds int, totalNumRQ int) []string {
var ret []string
for j := 0; j < totalNumRQ; j++ {
select {
case rowResponse := <-resp: //catch the response
if rowResponse != "" {
ret = append(ret, rowResponse)
}
case <-time.After(time.Duration(timeoutMiliseconds) * time.Millisecond): // timeout control
return nil
}
}
return ret
}
//GetRowValue open the table and get the row indexed by pk and returns the stored message
func GetRowValue(pk string, ctx *context.Context, table *bigtable.Table) string {
var response string
r, err := table.ReadRow(*ctx, pk)
if err != nil {
return ""
}
if len(r) > 0 {
row := r[COLUMN_FAMILY_NAME]
numCol := len(row)
response = string(row[0].Value)
}
return response
}
Run Code Online (Sandbox Code Playgroud)
我也试过这个例子,时间不是更好:
我使用的是gorutines和chanels吗?我访问BT的方式是正确的吗?也许关键设计不正确?
我认为问题是您使用的是一维chan:
resp := make(chan string)
Run Code Online (Sandbox Code Playgroud)
您应该尝试通过执行以下操作来扩大其尺寸:
resp := make(chan string,len(listPKs))
Run Code Online (Sandbox Code Playgroud)
这是因为,如果您的异步函数在读取 中的信息之前完成,chan那么chan将会被阻塞。
旁注:在不执行任何检查的情况下生成 go 例程可能是问题的根源。
我建议您实现一个工作队列以优化您的任务。
| 归档时间: |
|
| 查看次数: |
446 次 |
| 最近记录: |