使用Golang减少Bigtable的访问时间

Jos*_*lez 6 bigtable go

我想在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的方式是正确的吗?也许关键设计不正确?

Bes*_*bug 3

我认为问题是您使用的是一维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 例程可能是问题的根源。

我建议您实现一个工作队列以优化您的任务。