golang grpc thrift with aerospike

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

面對著數百G的資料,數萬的TPS,一直在找合適的資料庫及RPC架構。最近對aerospike和google grpc、apache thrift進行了簡單的測試。
測試的內容比較簡單,就是用戶端根據KEY到服務端進行尋找,返回value。為了測試簡單,資料庫中只有一對key_value。資料庫用的aerospike,RPC架構分別用grpc\thrift,用戶端、服務端都用GO語言開發。
grpc定義如下:

syntax = "proto3";package inf;message AuthRq {        string clientId = 1;        string token = 2;}message AuthRp {        string token = 1;}message DataTypeRq {        AuthRq authRq = 1;        string groupName  = 101;        string enName = 102;}message DataTypeRp {        AuthRp authRp = 1;        int64 codeId = 101;        string cnName = 102;}service Data {        rpc DataType (DataTypeRq) returns (DataTypeRp){};}

thrift定義如下:

namespace go infnamespace java infnamespace cpp infstruct AuthRq {        1: string clientId;        2: string       token;}struct AuthRp {        1: required string      token;}struct DataTypeRq {        1: required AuthRq authrq;        2: required string groupName;        3: required string enName;}struct DataTypeRp {        1: required AuthRp authrp;        2: required i64 codeId;        3: required string CnName;}service Data {        DataTypeRp DataType (1: DataTypeRq dataTypeRq);}

服務端與grpc相關代碼如下:

//DataType 將請求參數轉化為DataTypeM的請求參數,調用DataTypeM,並將結果返回func (t *Data) DataType(ctx context.Context, request *inf.DataTypeRq) (response *inf.DataTypeRp, err error) {    //log.Printf("App request: %#v", request)    //  if authRsp, err := t.Auth(ctx, request.AuthRq); err == nil {    var req DataTypeReq    req.EnName = request.EnName    req.GroupName = request.GroupName    result, err := dataTypeM(req)    response = &inf.DataTypeRp{        AuthRp: &inf.AuthRp{Token: authRsp.Token},        CnName: result.CnName,        CodeId: result.CodeId,    }    return response, err    //  } else {    //      return nil, err    //  }}

服務端與thrift相關代碼如下:

func (t *Data) DataType(request *inf.DataTypeRq) (response *inf.DataTypeRp, err error) {    //log.Printf("App request: %#v", request)    //  if authRsp, err := t.Auth(request.Authrq); err == nil {    var req DataTypeReq    req.EnName = request.EnName    req.GroupName = request.GroupName    result, err := dataTypeM(req)    response = inf.NewDataTypeRp()    response.Authrp.Token = authRsp.Token    response.CnName = result.CnName    response.CodeId = result.CodeId    //log.Printf("DataType response: %#v", response)    return response, err    //  } else {    //      return nil, err    //  }}

服務端與aerospike相關代碼,DataType調用如下函數:

func dataTypeM(request DataTypeReq) (response DataTypeRsp, err error) {    //log.Printf("DataTypeM request: %#v", request)    cacheTable := "data_type_def"    key := request.GroupName + "|" + request.EnName    keys, err := NewKey("test", cacheTable, key)    result, err := asClient.Get(nil, keys)    if result == nil {        for {            hostname, _ := os.Hostname()            serverId := hostname + strconv.Itoa(os.Getpid()) + strconv.Itoa(time.Now().Nanosecond())            if ok := tdp.DLock(key, serverId); ok {                bin1 := NewBin("cnname", "語音接通")                bin2 := NewBin("code_id", 101)                asClient.PutBins(nil, keys, bin1, bin2)                result, _ = asClient.Get(nil, keys)                tdp.UnDLock(key, serverId)                break            } else {                time.Sleep(tryLockSleep * time.Millisecond)                result, _ := asClient.Get(nil, keys)                if result != nil {                    break                }            }        }    }    if result != nil {        response.CnName, _ = result.Bins["cnname"].(string)        tmp, _ := result.Bins["code_id"].(int)        //log.Printf("code_id: %d", tmp)        response.CodeId = int64(tmp)    } else {        log.Printf("can't get result: %#v", request)    }    return response, err}

用戶端代碼如下,與RPC架構無關的代碼完全一樣:

func dataType(client inf.DataClient, t string) {    var request inf.DataTypeRq    var reqAuth inf.AuthRq    reqAuth.ClientId = clientId    reqAuth.Token = token    request.AuthRq = &reqAuth    //  request.ClientId = clientId    //  request.Token = "1"    request.EnName = "app_call_connect_success"    request.GroupName = "USER_EVENT"    response, err := client.DataType(context.Background(), &request)  //thrift中是: response, err := client.DataType(request)    if err == nil {        token = response.AuthRp.Token        log.Printf("token: %s", response.AuthRp.Token)        if response.CodeId != 101 {            log.Printf("DataType  %#v", response)        }    } else if err.Error() == "1" {        log.Printf("auth failer: %#v", err)    }}

測試伺服器是兩台,都是兩顆Intel E5 2630 CPU,服務端在A伺服器上,192G記憶體,aerospike和用戶端在B伺服器上,128G記憶體;多用戶端用goroutine實現。
以下是用戶端並發數在50時的
grpc:
服務端
用戶端

thrift:
服務端
用戶端

在整個測試過程中,用戶端並發數無論是50,還是800,資源使用方式都相差不大。總體來看,thrift服務端或者用戶端,對CPU的使用率偏少,而grpc的使用率偏多,在用戶端50時服務端grpc比thrift多使用30%的CPU。
以下是效能測試結果:

從測試來看grpc效能普遍好於thrift,但兩者效能相差很小。最好的成績是好於17%,最差好於3%。不過,grpc剛出來,還處於alpha階段,所用的protobuf3協議,也處於alpha階段。相信等正式版後,GPRC的效能會有一個提升的。
另外,從開發的角度看,thrift和grpc協議在使用上相差很小,從學習曲線上來講,從一方轉向另一方是比較容易的。目前grpc-go依賴的第三方包,大部分都在googlecode上,需要越獄擷取,很不方便。

著作權聲明:歡迎轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.