Skip to content

Commit

Permalink
Merge #136558
Browse files Browse the repository at this point in the history
136558: rpc: add BenchmarkGRPCPing r=tbg a=tbg

This benchmarks simple unary requests across a gRPC server with
CockroachDB-specific settings (snappy compression, etc).

The benchmarks show a problematic amount of allocations especially
at small payload sizes, which is likely a common case in CRDB.

We also see that it's highly beneficial to reuse RPC streams, i.e.
to use bidirectional streaming RPCs to implement unary request-response RPCs.
This is because gRPC implements unary RPCs using one-off streams, which
incurs high overhead. I would liken it to CockroachDB using DistSQL for point
lookups.

<details><summary>Results</summary>
<p>

```
./dev bench --timeout 1h --ignore-cache --stream-output --bench-mem ./pkg/rpc --filter BenchmarkGRPCPing --test-args '-test.benchtime=5s -test.cpu=8 -test.count 7 -test.timeout=1h' 2>&1 | tee -a bench.txt
benchstat -col /rpc bench.txt
```

```
                         │  UnaryUnary  │            StreamStream            │
                         │    sec/op    │   sec/op     vs base               │
GRPCPing/bytes=______1-8   117.23µ ± 6%   63.78µ ± 6%  -45.60% (p=0.001 n=7)
GRPCPing/bytes=____256-8   119.66µ ± 2%   69.45µ ± 4%  -41.96% (p=0.001 n=7)
GRPCPing/bytes=___1024-8   118.16µ ± 5%   65.98µ ± 2%  -44.16% (p=0.001 n=7)
GRPCPing/bytes=___2048-8   127.25µ ± 3%   79.78µ ± 6%  -37.31% (p=0.001 n=7)
GRPCPing/bytes=___4096-8   141.04µ ± 1%   86.34µ ± 4%  -38.78% (p=0.001 n=7)
GRPCPing/bytes=___8192-8    174.0µ ± 4%   117.8µ ± 3%  -32.31% (p=0.001 n=7)
GRPCPing/bytes=__16384-8    241.6µ ± 2%   180.7µ ± 5%  -25.21% (p=0.001 n=7)
GRPCPing/bytes=__32768-8    349.8µ ± 2%   296.5µ ± 2%  -15.25% (p=0.001 n=7)
GRPCPing/bytes=__65536-8    495.1µ ± 2%   428.3µ ± 5%  -13.49% (p=0.001 n=7)
GRPCPing/bytes=_262144-8    1.418m ± 4%   1.386m ± 3%        ~ (p=0.053 n=7)
GRPCPing/bytes=1048576-8    6.002m ± 6%   5.885m ± 2%        ~ (p=0.259 n=7)
geomean                     301.1µ        214.6µ       -28.74%

                         │  UnaryUnary  │             StreamStream             │
                         │     B/s      │      B/s       vs base               │
GRPCPing/bytes=______1-8   400.4Ki ± 5%    732.4Ki ± 5%  +82.93% (p=0.001 n=7)
GRPCPing/bytes=____256-8   4.463Mi ± 2%    7.687Mi ± 4%  +72.22% (p=0.001 n=7)
GRPCPing/bytes=___1024-8   16.92Mi ± 5%    30.30Mi ± 2%  +79.09% (p=0.001 n=7)
GRPCPing/bytes=___2048-8   31.06Mi ± 3%    49.54Mi ± 6%  +59.50% (p=0.001 n=7)
GRPCPing/bytes=___4096-8   55.71Mi ± 1%    91.02Mi ± 5%  +63.37% (p=0.001 n=7)
GRPCPing/bytes=___8192-8   90.06Mi ± 4%   133.04Mi ± 3%  +47.73% (p=0.001 n=7)
GRPCPing/bytes=__16384-8   129.5Mi ± 2%    173.2Mi ± 5%  +33.70% (p=0.001 n=7)
GRPCPing/bytes=__32768-8   178.8Mi ± 2%    211.0Mi ± 2%  +18.00% (p=0.001 n=7)
GRPCPing/bytes=__65536-8   252.6Mi ± 2%    292.0Mi ± 5%  +15.60% (p=0.001 n=7)
GRPCPing/bytes=_262144-8   352.6Mi ± 4%    360.9Mi ± 4%        ~ (p=0.053 n=7)
GRPCPing/bytes=1048576-8   333.2Mi ± 6%    339.9Mi ± 2%        ~ (p=0.259 n=7)
geomean                    48.06Mi         67.42Mi       +40.27%

                         │  UnaryUnary   │            StreamStream             │
                         │     B/op      │     B/op      vs base               │
GRPCPing/bytes=______1-8   14.992Ki ± 2%   3.633Ki ± 2%  -75.77% (p=0.001 n=7)
GRPCPing/bytes=____256-8   17.512Ki ± 3%   6.460Ki ± 1%  -63.11% (p=0.001 n=7)
GRPCPing/bytes=___1024-8    26.63Ki ± 1%   15.67Ki ± 1%  -41.18% (p=0.001 n=7)
GRPCPing/bytes=___2048-8    38.52Ki ± 1%   27.67Ki ± 1%  -28.17% (p=0.001 n=7)
GRPCPing/bytes=___4096-8    65.89Ki ± 1%   54.97Ki ± 0%  -16.57% (p=0.001 n=7)
GRPCPing/bytes=___8192-8    116.9Ki ± 1%   105.4Ki ± 1%   -9.88% (p=0.001 n=7)
GRPCPing/bytes=__16384-8    215.6Ki ± 0%   203.5Ki ± 1%   -5.61% (p=0.001 n=7)
GRPCPing/bytes=__32768-8    459.8Ki ± 1%   444.5Ki ± 1%   -3.33% (p=0.001 n=7)
GRPCPing/bytes=__65536-8    808.4Ki ± 1%   791.8Ki ± 1%   -2.05% (p=0.001 n=7)
GRPCPing/bytes=_262144-8    3.289Mi ± 0%   3.276Mi ± 0%   -0.40% (p=0.017 n=7)
GRPCPing/bytes=1048576-8    12.94Mi ± 0%   12.94Mi ± 0%        ~ (p=0.053 n=7)
geomean                     182.4Ki        130.5Ki       -28.42%

                         │ UnaryUnary  │           StreamStream            │
                         │  allocs/op  │ allocs/op   vs base               │
GRPCPing/bytes=______1-8   182.00 ± 0%   46.00 ± 0%  -74.73% (p=0.001 n=7)
GRPCPing/bytes=____256-8   182.00 ± 0%   46.00 ± 0%  -74.73% (p=0.001 n=7)
GRPCPing/bytes=___1024-8   182.00 ± 0%   47.00 ± 0%  -74.18% (p=0.001 n=7)
GRPCPing/bytes=___2048-8   183.00 ± 0%   48.00 ± 2%  -73.77% (p=0.001 n=7)
GRPCPing/bytes=___4096-8   183.00 ± 0%   48.00 ± 0%  -73.77% (p=0.001 n=7)
GRPCPing/bytes=___8192-8   183.00 ± 0%   50.00 ± 2%  -72.68% (p=0.001 n=7)
GRPCPing/bytes=__16384-8   194.00 ± 0%   55.00 ± 2%  -71.65% (p=0.001 n=7)
GRPCPing/bytes=__32768-8   209.00 ± 0%   72.00 ± 1%  -65.55% (p=0.001 n=7)
GRPCPing/bytes=__65536-8   216.00 ± 0%   80.00 ± 1%  -62.96% (p=0.001 n=7)
GRPCPing/bytes=_262144-8    275.0 ± 0%   141.0 ± 1%  -48.73% (p=0.001 n=7)
GRPCPing/bytes=1048576-8    487.0 ± 1%   350.0 ± 3%  -28.13% (p=0.001 n=7)
geomean                     214.1        69.37       -67.60%
```

</p>
</details> 

Informs #134971.


Co-authored-by: Tobias Grieger <[email protected]>
  • Loading branch information
craig[bot] and tbg committed Dec 10, 2024
2 parents 5f83714 + 2d215ad commit bb4d357
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/rpc/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ go_test(
"//pkg/spanconfig",
"//pkg/testutils",
"//pkg/testutils/datapathutils",
"//pkg/testutils/grpcutils",
"//pkg/testutils/skip",
"//pkg/ts/tspb",
"//pkg/util",
Expand All @@ -161,6 +162,7 @@ go_test(
"@com_github_cockroachdb_datadriven//:datadriven",
"@com_github_cockroachdb_errors//:errors",
"@com_github_cockroachdb_redact//:redact",
"@com_github_gogo_protobuf//types",
"@com_github_gogo_status//:status",
"@com_github_golang_mock//gomock",
"@com_github_prometheus_client_model//go",
Expand Down
109 changes: 109 additions & 0 deletions pkg/rpc/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ package rpc

import (
"context"
"crypto/rand"
"fmt"
"io"
"net"
"strings"
"sync"
"sync/atomic"
"testing"
Expand All @@ -21,6 +23,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/settings"
"github.com/cockroachdb/cockroach/pkg/settings/cluster"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/grpcutils"
"github.com/cockroachdb/cockroach/pkg/testutils/skip"
"github.com/cockroachdb/cockroach/pkg/util"
"github.com/cockroachdb/cockroach/pkg/util/circuit"
Expand All @@ -35,6 +38,7 @@ import (
"github.com/cockroachdb/cockroach/pkg/util/tracing"
"github.com/cockroachdb/cockroach/pkg/util/uuid"
"github.com/cockroachdb/errors"
"github.com/gogo/protobuf/types"
gogostatus "github.com/gogo/status"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -2230,3 +2234,108 @@ func TestInitialHeartbeatFailedError(t *testing.T) {
return err
})
}

func BenchmarkGRPCPing(b *testing.B) {
for _, bytes := range []int{1, 1 << 8, 1 << 10, 1 << 11, 1 << 12, 1 << 13, 1 << 14, 1 << 15, 1 << 16, 1 << 18, 1 << 20} {
bstr := fmt.Sprintf("%d", bytes)
bname := strings.Repeat("_", 7-len(bstr)) + bstr
b.Run("bytes="+bname, func(b *testing.B) {
stopper := stop.NewStopper()
ctx := context.Background()
defer stopper.Stop(ctx)

clock := &timeutil.DefaultTimeSource{}
maxOffset := 250 * time.Millisecond
srvRPCCtx := newTestContext(uuid.MakeV4(), clock, maxOffset, stopper)
const serverNodeID = 1
srvRPCCtx.NodeID.Set(ctx, serverNodeID)
s := newTestServer(b, srvRPCCtx)

randBytes := make([]byte, bytes)
_, err := rand.Read(randBytes)
require.NoError(b, err)

req := &PingRequest{Ping: string(randBytes)}
resp := &PingResponse{Pong: string(randBytes)}
anyreq, err := types.MarshalAny(req)
require.NoError(b, err)
anyresp, err := types.MarshalAny(resp)
require.NoError(b, err)

require.NoError(b, err)
b.Logf("marshaled request size: %d bytes (%d bytes of overhead)", req.Size(), req.Size()-bytes)

tsi := &grpcutils.TestServerImpl{
UU: func(ctx context.Context, req *types.Any) (*types.Any, error) {
return anyresp, nil
},
SS: func(srv grpcutils.GRPCTest_StreamStreamServer) error {
for {
if _, err := srv.Recv(); err != nil {
return err
}
if err := srv.Send(anyresp); err != nil {
return err
}
}
},
}

grpcutils.RegisterGRPCTestServer(s, tsi)

ln, err := netutil.ListenAndServeGRPC(srvRPCCtx.Stopper, s, util.TestAddr)
if err != nil {
b.Fatal(err)
}
remoteAddr := ln.Addr().String()

cliRPCCtx := newTestContext(uuid.MakeV4(), clock, maxOffset, stopper)
cliRPCCtx.NodeID.Set(ctx, 2)
cc, err := cliRPCCtx.grpcDialRaw(ctx, remoteAddr, DefaultClass)
require.NoError(b, err)

for _, tc := range []struct {
name string
invoke func(c grpcutils.GRPCTestClient, N int) error
}{
{"UnaryUnary", func(c grpcutils.GRPCTestClient, N int) error {
for i := 0; i < N; i++ {
_, err := c.UnaryUnary(ctx, anyreq)
if err != nil {
return err
}
}
return nil
}},
{
"StreamStream", func(c grpcutils.GRPCTestClient, N int) error {
sc, err := c.StreamStream(ctx)
if err != nil {
return err
}
for i := 0; i < N; i++ {
if err := sc.Send(anyreq); err != nil {
return err
}
if _, err := sc.Recv(); err != nil {
return err
}
}
return nil
}},
} {

b.Run("rpc="+tc.name, func(b *testing.B) {

c := grpcutils.NewGRPCTestClient(cc)

b.SetBytes(int64(req.Size() + resp.Size()))
b.ResetTimer()
if err := tc.invoke(c, b.N); err != nil {
b.Fatal(err)
}
})
}
})
}
}

0 comments on commit bb4d357

Please sign in to comment.