分享
  1. 首页
  2. 文章

golang grpc thrift with aerospike

dazheng · · 4494 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

面对着数百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 inf
namespace java inf
namespace cpp inf
struct 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:
grpc服务端 服务端
grpc客户端 客户端

thrift:
thrift服务端 服务端
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上,需要越狱获取,很不方便。

版权声明:欢迎转载。


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:dazheng

查看原文:golang grpc thrift with aerospike

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4494 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏