lightweight gRPC replacement である dRPC を試してみる。
こんにちは k-jun です。今回は gRPC から諸々の必要ないものを削ぎ落とした結果、高速化された dRPC を試してみます。
誕生の経緯などはこちらの post が詳しそうです。 gRPC には使っていない機能、Option なども多く これら必要ないものを落として Network Storage のサービスを高速化させたとかなんとか。(ざっと雰囲気で読んでいます)
https://www.storj.io/blog/introducing-drpc-our-replacement-for-grpc
post によると、gRPC とすぐに取り替えっこ出来ると書いてあるのでやって見ます。 ちょうどよく、前に gRPC 試した際の repository が残っているので、これを dRPC 化してみます。
https://github.com/k-jun/playground-grpc.git
syntax = "proto3"; option go_package = "github.com/k-jun/grpc"; service PlaygroundDrpc { rpc CreateTodo(TodoData) returns (TodoData) {} rpc ReadTodo(TodoData) returns (TodoData) {} rpc UpdateTodo(TodoData) returns (TodoData) {} rpc DeleteTodo(TodoData) returns (TodoData) {} } message TodoData { string id = 1; string title = 2; string body = 3; }
$ protoc --proto_path=proto --go_out=drpc --go-drpc_out=drpc --go_opt=paths=source_relative --go-drpc_opt=paths=source_relative proto/playground-grpc.proto
ディレクトリ構成は以下な感じ。
$ tree . ├── Makefile ├── README.md ├── drpc │ ├── playground-grpc.pb.go │ └── playground-grpc_drpc.pb.go ├── go.mod ├── go.sum ├── grpc │ └── playground-grpc.pb.go ├── main.go ├── proto │ └── playground-grpc.proto └── server └── server.go
Client 側のコードも書いてみる。
package main import ( "context" "fmt" "net" pb "playground-grpc/drpc" "storj.io/drpc/drpcconn" ) func main() { rawconn, err := net.Dial("tcp", "localhost:8080") if err != nil { panic(err) } conn := drpcconn.New(rawconn) defer conn.Close() client := pb.NewDRPCPlaygroundDrpcClient(conn) ctx := context.Background() creatTodo, err := client.CreateTodo(ctx, &pb.TodoData{ Id: "1", Title: "homework", Body: "math", }) if err != nil { panic(err) } fmt.Println(creatTodo) readTodo, err := client.ReadTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } fmt.Println(readTodo) updateTodo, err := client.UpdateTodo(ctx, &pb.TodoData{Title: "updated title", Body: "updated body"}) if err != nil { panic(err) } fmt.Println(updateTodo) deleteTodo, err := client.DeleteTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } fmt.Println(deleteTodo) }
$ go run cmd/client.go id:"1" title:"homework" body:"math" id:"1" title:"homework" body:"math" title:"updated title" body:"updated body" id:"1"
おおお凄い!実際に動いた!確かに gRPC から移行するのであれば、Server の Register の箇所をちょこっと変えるだけで実装できた。 変更差分を PR にして、まとめると。
https://github.com/k-jun/playground-grpc/pull/1/files
せっかく Golang なので、簡単に Benchmark も取ってみる。
func BenchmarkDRPC(b *testing.B) { rawconn, err := net.Dial("tcp", "localhost:8080") if err != nil { panic(err) } conn := drpcconn.New(rawconn) defer conn.Close() client := pb.NewDRPCPlaygroundDrpcClient(conn) ctx := context.Background() for i := 0; i < b.N; i++ { _, err := client.CreateTodo(ctx, &pb.TodoData{ Id: "1", Title: "homework", Body: "math", }) if err != nil { panic(err) } _, err = client.ReadTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } _, err = client.UpdateTodo(ctx, &pb.TodoData{Title: "updated title", Body: "updated body"}) if err != nil { panic(err) } _, err = client.DeleteTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } } }
$ go test -bench . ./... ? playground-grpc [no test files] goos: darwin goarch: amd64 pkg: playground-grpc/cmd cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz BenchmarkDRPC-12 5433 216052 ns/op PASS ok playground-grpc/cmd 2.607s
gRPC に戻して以下のコードで Benchmark を再び回す。
func BenchmarkGRPC(b *testing.B) { conn, err := grpc.Dial("localhost:8080", []grpc.DialOption{grpc.WithInsecure()}...) if err != nil { panic(err) } defer conn.Close() client := pb.NewPlaygroundGrpcClient(conn) ctx := context.Background() for i := 0; i < b.N; i++ { _, err := client.CreateTodo(ctx, &pb.TodoData{ Id: "1", Title: "homework", Body: "math", }) if err != nil { panic(err) } _, err = client.ReadTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } _, err = client.UpdateTodo(ctx, &pb.TodoData{Title: "updated title", Body: "updated body"}) if err != nil { panic(err) } _, err = client.DeleteTodo(ctx, &pb.TodoData{Id: "1"}) if err != nil { panic(err) } } }
$ go test -bench . ./... ? playground-grpc [no test files] goos: darwin goarch: amd64 pkg: playground-grpc/cmd cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz BenchmarkGRPC-12 3003 398791 ns/op
だめじゃん 笑。半分ぐらいの性能しか出ていない。もとがこんだけ違うと Build しても対して差分は変わらなそう。
それでは今回はこのへんで。