Skip to content

Add optional FlatBuffers RPC support - #3559

Open
AnDiXL wants to merge 6 commits into
apache:masterfrom
AnDiXL:review/flatbuffers-rpc-3558
Open

AnDiXL wants to merge 6 commits into
apache:masterfrom
AnDiXL:review/flatbuffers-rpc-3558

Conversation

@AnDiXL

@AnDiXL AnDiXL commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

This continues the RPC work in #3197 on top of #3558, which is now merged. #3558 added the FlatBuffers messages, builders, service descriptors and the brpc_flatc generator; this PR adds the optional fb_rpc transport on top of it.

The branch is rebased onto master after #3558 and contains only the four RPC commits.

What is changed and the side effects?

  • Add FlatBuffers RPC protocol support: optional fb_rpc transport, Channel/Controller/Server integration, service lifecycle handling, attachments, retries and concurrency, with 33 protocol tests.
  • Add a generated FlatBuffers RPC example: generated client/server example with a bounded loopback smoke test. This is functional validation, not a performance benchmark.
  • Add explicit FlatBuffers ON validation: an ON validation runner, its self-tests and a GitHub Actions workflow.
  • Document FlatBuffers setup and example checks: Chinese and English setup, dependency, ABI and example-verification documentation.

The transport uses explicit metadata lengths, so optional fields can be appended later while the known prefix stays readable. Existing protobuf-facing Protocol callback signatures are unchanged.

Side effects and limits:

  • FlatBuffers stays disabled by default. Enabling it changes the Channel, Controller and Server ABI, so the library and its users must be built with matching settings. Protobuf remains a dependency.
  • FRPC authentication, compression, checksums and streaming are not supported. No compatibility with earlier experimental FRPC wire formats and no performance improvement is claimed.
  • After the CMake restructuring in Refactor CMake source and target ownership into module directories #3618, the build tree no longer stages output/include. The ON runner and the docs now install the runtime into a prefix before building the example.

Validation

Run on the rebased head 48177aa2:

Environment Result
macOS, Apple Clang 15, Protobuf 3.21, CMake ON runner 22 message + 33 protocol tests, two codegen tests, one example smoke; no failures or skips
Linux x86_64 (Ubuntu 22.04 container), GCC 11, CMake ON runner same counts, no failures or skips
macOS, example linked against the shared library (LINK_SO=ON) smoke passed
macOS, FlatBuffers OFF (default) builds; no FlatBuffers sources are compiled
python3 .github/scripts/test_flatbuffers_on.py 26 tests passed

The example smoke verifies 13 replies, 2 expected schema rejections and a clean shutdown.

Not covered by these runs: Make and Bazel ON modes (left to CI), sanitizer runs and performance benchmarks.


Check List:

  • Add optional FlatBuffers messages and code generation #3558 has merged and this branch is rebased onto the updated master.
  • Protocol regressions, generated example and enablement documentation are included.
  • macOS and Linux GCC ON runs passed on the rebased head.
  • Hosted CI for this PR has completed.

@AnDiXL

AnDiXL commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

Hi @chenBright @wwbmmm @zchuango @darion-yaphet, thanks again for all the reviews on #3558!

#3559 is the last PR in the FlatBuffers series: the optional fb_rpc transport on top of #3558.

Could you please take a look when you have time? Any feedback is welcome. Thanks!

xulei25 added 4 commits October 23, 2026 15:26
Add the optional fb_rpc transport with length-delimited metadata and
stable method IDs, and integrate it with Channel, Controller and Server
without changing the existing protobuf Protocol callback signatures.

Keep request buffers immutable across retries and concurrent calls, and
manage service ownership, asynchronous completion and concurrency
limits. Reject invalid frames and unsupported authentication,
compression, checksums and streams.

The feature stays disabled by default in CMake, Make and Bazel. Add 33
protocol tests covering the wire format, service lifecycle, malformed
input and real RPC round trips.
Add a client/server example built from a generated service, with a
bounded loopback smoke test: 13 verified replies, 2 expected schema
rejections and a clean shutdown. It is a functional check, not a
benchmark.

The example takes an installed FlatBuffers-enabled bRPC and writes the
code generated by flatc and brpc_flatc into its own build directory.
Add a runner that builds and tests the FlatBuffers-enabled
configuration with CMake, Make or Bazel and rejects empty, filtered or
skipped test runs. Add its self-tests and a GitHub Actions workflow that
runs it on Linux and macOS when FlatBuffers-related paths change.
Add Chinese and English guides covering how to enable FlatBuffers, the
dependency and ABI requirements, building the runtime, running the
example and its smoke test, the network RPC API and the FRPC wire
format. Update the generator README for the RPC example.
@AnDiXL
AnDiXL force-pushed the review/flatbuffers-rpc-3558 branch from 48177aa to 8cbb17b Compare October 23, 2026 07:33
@chenBright
chenBright requested a balanced review from Copilot October 23, 2026 08:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

4 open issues
What changed in this PR

This PR adds optional FlatBuffers RPC (“fb_rpc”) transport support on top of the existing FlatBuffers message/service generation work, plus an end-to-end example and a dedicated FlatBuffers-ON validation workflow.

Changes:

  • Integrates fb_rpc as a new built-in Protocol with Channel/Controller/Server support, service registration, and concurrency integration.
  • Adds comprehensive FlatBuffers protocol/unit tests and wires them into CMake/Make/Bazel test builds.
  • Adds a generated client/server example with a bounded smoke test, updated documentation (EN/CN), and a GitHub Actions “FlatBuffers ON” gate runner.
File Description
tools/​flatbuffers/​README.md Updates generator README to point to runtime enablement + fb_rpc usage and verification guidance.
test/​brpc_flatbuffers_protocol_unittest.cpp Adds dedicated protocol-level and lifecycle tests for fb_rpc.
test/​brpc_channel_unittest.cpp Avoids colliding with newly assigned built-in protocol IDs in channel tests.
test/​Makefile Ensures FlatBuffers protocol tests are excluded when FlatBuffers is OFF and builds/link rules include the new test.
test/​CMakeLists.txt Adds brpc_flatbuffers_protocol_unittest to CMake test targets when FlatBuffers is ON.
test/​BUILD.bazel Adds Bazel cc_test for brpc_flatbuffers_protocol_unittest and excludes it from generic globbed tests.
src/​brpc/​server.h Introduces FlatBuffers service registration API and internal method property plumbing (guarded by BRPC_WITH_FLATBUFFERS).
src/​brpc/​server.cpp Implements FlatBuffers service registry, versioning/stat exposure, concurrency limiter hookup, and conflict checks with protobuf services.
src/​brpc/​policy/​flatbuffers_protocol.h Declares the fb_rpc protocol hook points (parse/verify/serialize/pack/process).
src/​brpc/​policy/​flatbuffers_protocol.cpp Implements FRPC framing, request/response processing, and async completion lifecycle for FlatBuffers RPC.
src/​brpc/​options.proto Reserves built-in PROTOCOL_FLATBUFFERS_RPC = 30.
src/​brpc/​global.cpp Registers fb_rpc as a built-in protocol when FlatBuffers is enabled.
src/​brpc/​details/​server_private_accessor.h Exposes FlatBuffers method lookup to protocol code via server private accessor.
src/​brpc/​details/​controller_private_accessor.h Adds private setter for FlatBuffers method descriptor on Controller.
src/​brpc/​controller.h Adds Controller::flatbuffers_method() accessor and stores FlatBuffers method descriptor pointer.
src/​brpc/​controller.cpp Clears FlatBuffers method context in Controller::ResetPods().
src/​brpc/​channel.h Extends Channel to implement flatbuffers::RpcChannel and adds FBCallMethod.
src/​brpc/​channel.cpp Routes FlatBuffers calls via FBCallMethod, adds entry validation, and adjusts tracing method-name selection.
src/​brpc/​CMakeLists.txt Ensures flatbuffers_protocol.cpp is excluded when FlatBuffers is OFF.
example/​benchmark_fb/​smoke.py Adds bounded end-to-end smoke test orchestration for generated FB client/server.
example/​benchmark_fb/​server.cpp Adds example FlatBuffers server (protocol fb_rpc, service registration, graceful shutdown).
example/​benchmark_fb/​echo.fbs Defines example schema and stable wire ID for the RPC method.
example/​benchmark_fb/​client.cpp Adds example FlatBuffers client driving generated stub + verifies response schema/attachments.
example/​benchmark_fb/​README.md Documents building/running the example and what the smoke test validates.
example/​benchmark_fb/​CMakeLists.txt Adds standalone CMake build for the example + codegen steps and smoke CTest.
docs/​en/​flatbuffers.md Expands docs to cover fb_rpc enablement, full verification steps, and limitations.
docs/​cn/​flatbuffers.md Mirrors EN documentation updates for fb_rpc enablement and verification steps.
README_cn.md Links to the CN FlatBuffers RPC guide.
README.md Links to the EN FlatBuffers RPC guide.
Makefile Excludes flatbuffers_protocol.cpp from Make builds when FlatBuffers is OFF.
CMakeLists.txt Updates WITH_FLATBUFFERS option description to include RPC support.
BUILD.bazel Includes flatbuffers_protocol.cpp in FlatBuffers-enabled Bazel source patterns.
.gitignore Stops ignoring .github/ to keep workflows/scripts discoverable.
.github/​workflows/​flatbuffers-on.yml Adds a CI workflow that runs the FlatBuffers-ON gates across CMake/Make/Bazel on Linux/macOS.
.github/​scripts/​test_flatbuffers_on.py Adds self-tests validating the gate script’s report parsing and safety checks.
.github/​scripts/​flatbuffers-on.py Adds an “ON runner” that builds deps, runs unit/codegen/example tests, and rejects empty/skipped runs.

Review effort: Lite

Comment thread src/brpc/channel.cpp
return;
}
cntl->set_used_by_rpc();
const bool is_fb_protocol = (_options.protocol == PROTOCOL_FLATBUFFERS_RPC);
Comment thread src/brpc/channel.cpp
const int64_t start_send_us = butil::cpuwide_time_us();
std::string method_name;
if (_get_method_name) {
if (_get_method_name && is_fb == is_fb_protocol) {
Comment thread src/brpc/server.cpp
Comment on lines +1796 to +1798
// Keep ownership with the caller until the entire record is published.
auto record = std::make_unique<FlatBuffersServiceMap::Service>(service, sd);
std::unordered_set<std::string> method_names;
Comment thread src/brpc/server.cpp
Comment on lines +160 to +169
Method* FindMethodByFullName(const butil::StringPiece& fullname) const {
for (const auto& service : services) {
for (const auto& method : service.second->methods) {
if (method.second->property.method->full_name() == fullname) {
return method.second.get();
}
}
}
return nullptr;
}
@wwbmmm

wwbmmm commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

[replied by brpc-oncall robot] Thanks for splitting the RPC increment out of #3197 and for the very thorough documentation. Because this PR adds a new built-in protocol together with public API on Channel/Server (and changes their layout when BRPC_WITH_FLATBUFFERS is on), I'd like to settle a few architecture points before going through the implementation line by line.

  1. Motivation and cost/benefit. The PR explicitly claims no performance improvement yet, and the example is functional validation only. A new wire protocol is a permanent maintenance commitment (framing, compatibility, tests, docs), and fb_rpc gives up authentication, compression, checksums, streaming, log-id/user-field propagation and RPC dump that protocols such as baidu_std already provide. Could you add a short design note (or point to the agreed design in flatbuffers support(3/3): Add flatbuffers protocol support for brpc #3197) that states the concrete use cases this transport targets and why they cannot be served today, ideally with at least a micro-benchmark of fb_rpc against a protobuf/baidu_std baseline? Without that it is hard to judge whether the benefit justifies the cost.

  2. ABI. With BRPC_WITH_FLATBUFFERS=1, Channel gains a second base class and Channel/Controller/Server change layout, so the library and every consumer must be rebuilt with the same setting. The docs are honest about it, but this effectively rules out packaged/prebuilt brpc and doubles the ABI configurations the project has to reason about. Is that acceptable long term, or could the transport live in a separate optional component/target (or avoid changing core class layouts)?

  3. Parallel service registry. Server now keeps a second registry that re-implements ownership, duplicate/conflict checks, the version string, bvar exposure, concurrency-limiter setup and string-based per-method option lookup for FlatBuffers methods, while ListServices and the status surfaces still only see protobuf services (although GetStat().user_service_count now includes FlatBuffers services). Every future per-method option must be added twice or will silently not apply to FlatBuffers services. Would it be feasible to factor this into a shared internal registry abstraction? At minimum the user_service_count vs. ListServices divergence should be resolved, and keeping a full-name index in the registry (as protobuf does with _method_map) would avoid the O(services x methods) name lookups.

  4. Wire format. Since compatibility with the old experimental FRPC variants is explicitly not promised, retaining their mixed endianness (big-endian header, little-endian metadata) and the FRPC magic adds complexity without a stated benefit. Before the format is frozen it would be cheaper to use one endianness throughout; if the legacy layout must be preserved, please state why in the docs, as readers will otherwise assume it is accidental.

Note: Copilot's three findings above look like false positives to me. AdaptiveProtocolType has operator ProtocolType(), so _options.protocol == PROTOCOL_FLATBUFFERS_RPC compiles and is the idiom already used elsewhere in channel.cpp; server.cpp already includes <unordered_set> at the top; and the is_fb == is_fb_protocol guard deliberately avoids calling a protocol's protobuf get_method_name hook with a null method descriptor (GetFlatBuffersMethodName is installed for fb_rpc).

Thanks!

const uint32_t attachment_size = Load32(meta + 8);
const bthread_id_t correlation_id = {Load64(meta + 12)};
Controller* cntl = nullptr;
const int rc = bthread_id_lock(correlation_id, reinterpret_cast<void**>(&cntl));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bthread_id_lock() validates a process-wide correlation ID, but does not verify that the response arrived on the socket used by that request. A response carrying another in-flight RPC's valid ID can therefore modify and complete that RPC.

Please follow the existing protobuf response handlers: check that cntl is non-null and call does_response_match_request_socket() before modifying the Controller or response. Unlock and discard the message when validation fails, and add regression coverage for mismatched sockets and stale retry responses.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, you're right. ProcessFlatBuffersResponse only checked that the correlation id was still valid, so a response on another connection that carried a live id could complete the wrong RPC.

Fixed in a6709e7 the same way as ProcessRpcResponse: after bthread_id_lock(), if cntl is null or does_response_match_request_socket() fails for the socket the response arrived on, the handler logs a warning, unlocks the id and drops the message before touching the Controller or the response. New regression tests cover a live id arriving on a foreign socket, a response from a previous retry, and a preserved backup attempt that may complete only on its own socket. All three fail without the fix.

xulei25 added 2 commits October 28, 2026 11:58
The example client and server could only run a bounded loopback smoke
test. Add an opt-in timed mode so the same binaries can compare fb_rpc
with an equivalent protobuf service over baidu_std:

- echo_pb.proto mirrors echo.fbs, and the server serves both
  protocols on one port.
- --duration_s and --warmup_s run closed-loop callers and print QPS,
  latency percentiles and client CPU as one JSON line.
- --protocol selects fb_rpc or baidu_std, --use_bthread runs callers
  as bthreads, and --allow_remote accepts non-loopback endpoints.
- Request and reply builders reserve the payload size, so large
  messages are not grown by repeated reallocate-and-copy.

Defaults are unchanged and the smoke test still passes. The guides now
describe the example as a functional check with an optional timed mode.
ProcessFlatBuffersResponse only checked that the correlation id was
still live. A response on another connection that carried the id of an
in-flight RPC could therefore modify and complete that RPC.

Like the protobuf response handlers, check that the Controller exists
and that the response arrived on the socket used by the attempt it
answers, before touching the Controller or the response. Otherwise log
a warning, unlock the id and drop the message.

Add regression tests for a live id on a foreign socket, a response from
a previous retry, and a preserved backup attempt that may only complete
on its own socket. The ON runner now expects 36 protocol tests.
@AnDiXL

AnDiXL commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review, @wwbmmm, and for checking the Copilot comments. Below are the benchmark results for point 1 and proposals for points 2–4.

1. Motivation and benchmark

fb_rpc targets services whose payloads are already FlatBuffers, or where per-request parse/serialize cost dominates server CPU. With baidu_std every request and response is fully parsed and re-serialized. With fb_rpc the handler reads fields directly from the received bytes without a parse step (they are copied into one contiguous block only when they span several IOBuf blocks), and the builder output is appended to the socket IOBuf without another serialization pass. This transport has been used in the internal storage network of Baidu AI Cloud for several years; this PR upstreams it.

To measure it I extended example/benchmark_fb with a timed mode and a protobuf control service that has the same fields and is served over baidu_std by the same server binary, so both protocols run with identical client and server code.

Item Value
Hosts 2 × AMD EPYC 7W83 (2 × 64C), client and server on separate hosts
Network bond0, 200 Gb/s, TCP, RTT ≈ 0.02 ms, single connection
Build Ubuntu 22.04 container, GCC 11, Release, Protobuf 3.12.4, FlatBuffers 25.2.10
CPU both processes on the 112 NIC-local cores of NUMA node 0
Load closed loop, 1 / 16 / 64 bthread callers, one synchronous RPC in flight per caller; echo of a string field of the given size, no attachment
Method 3 s warm-up + 30 s, 5 rounds, protocol order alternated per round; Δ is the median of the per-round fb/pb ratios
Server CPU utime + stime of the server process from /proc, sampled every second over the measured window

Summary (fb_rpc vs baidu_std; positive QPS is better, negative CPU is better):

Payload QPS, 1 caller QPS, 16 callers QPS, 64 callers Server CPU/req, 1 Server CPU/req, 16 Server CPU/req, 64
0 B +12% +7% +4% -22% -15% -16%
32 B +13% +8% +9% -19% -16% -19%
256 B +16% +8% +6% -13% -15% -18%
1 KB +13% +9% +12% -21% -17% -18%
4 KB +14% +9% +9% -19% -18% -17%
8 KB +11% +9% +7% -18% -18% -19%
16 KB +15% +8% +9% -15% -19% -19%
64 KB +18% +6% +0% -14% -19% -13%
256 KB +21% +1% +0% -16% -10% -12%
1 MB +30% +4% +5% -18% -17% -24%
  • fb_rpc had higher QPS in 143 of 150 paired rounds; the worst round was −2.3%.
  • 1 caller: +11% to +30% QPS, p50 latency 8% to 24% lower.
  • 16 and 64 callers: +4% to +12% up to 16 KB. At 64 KB and above both protocols reach the limit of the single TCP connection (≈ 2.4 GB/s per direction), so QPS converges. In a single 20 s run with connection_type=pooled at 256 KB, both rise about 4.9× and remain equal (+0.5%), so large-message throughput is bound by kernel copies and the network rather than by the protocol.
  • Server CPU per request is lower in every case, by 10% to 24%. This is the most stable result.

Full results are in the collapsed section at the end.

Builder sizing. MessageBuilder starts at 1 KB and grows by reallocate-and-copy. Without reserving the size, a 1 MB reply doubled server CPU in our first runs (repeated glibc trim and page faults). The updated example reserves the expected size, and the guide will say so for large messages.

Not covered: RDMA, attachments, the full matrix with pooled connections, and newer Protobuf releases.

Missing features. Authentication, compression, checksums and streaming are out of scope for this PR. Because the metadata carries an explicit length, fields such as log-id and user fields can be appended later without breaking the known prefix.

2. ABI

Agreed that the layout should not depend on BRPC_WITH_FLATBUFFERS. Proposal:

  • Channel stops inheriting flatbuffers::RpcChannel. An internal adapter, built only when the option is ON, implements RpcChannel and forwards to Channel.
  • Generated stubs gain a constructor that takes a brpc::Channel* and owns the adapter, so XXX_Stub stub(&channel); stays as it is. The existing RpcChannel* constructor is kept.
  • Controller::_flatbuffers_method and Server::_flatbuffers_services are declared unconditionally, with forward-declared types, and stay null when the option is OFF. The cost is one pointer in Controller and one in Server.
  • The ON validation checks that sizeof and member offsets of Channel, Controller and Server match between ON and OFF builds.

With this, a release has one layout whatever the option is, and protobuf-only users are not affected. A consumer built with ON against a library built with OFF fails at link time instead of at run time. A separate component would still need protocol registration and dispatch hooks in Server, so I don't think it would reduce the coupling much.

3. Service registry

Proposal:

  • Keep FlatBuffers methods out of _method_map. baidu_std, HTTP, sofa, mongo and the nshead adaptor look methods up there by name and expect a protobuf descriptor.
  • Reuse MethodProperty for FlatBuffers methods (two extra pointer fields) and keep a full-name index for them. This replaces the O(services × methods) lookups.
  • Add one internal iteration over both maps and use it for bvar exposure, concurrency limiter setup, MaxConcurrencyOf() / ignore_eovercrowded, ClearServices() and /status. A new per-method option is then added in one place and applies to both kinds of service.
  • Status: add ListFlatBuffersServices() and keep the signature of ListServices(); document user_service_count as the sum of both; show FlatBuffers methods in /status. /list and /protobufs stay protobuf-only, because they return protobuf descriptors.
  • A request over another protocol that names a FlatBuffers method gets ENOMETHOD.

A shared registry abstraction for both kinds of service would touch the protobuf paths much more, so I'd prefer to do it in a follow-up PR.

4. Wire format

Agreed. Compatibility with the earlier experimental FRPC formats is not a goal, so the header and the fixed metadata will both be big-endian (network order), using the butil byte-order helpers, with a test that fixes the byte layout of request and response frames. The FlatBuffers payload stays little-endian as FlatBuffers defines it; it is not part of the frame. I'll keep the FRPC magic, because protocol detection on a shared port relies on it in the same way as PRPC, and document both choices.


The benchmark changes to example/benchmark_fb (timed mode, baidu_std control service, --use_bthread, builder sizing) are in a separate commit, 358a58a. If the proposals for 2 and 3 look right to you, I'll implement them in this PR together with 4.

Full results (1 / 16 / 64 callers, 10 payload sizes, medians of 5 rounds)

1 caller

Payload QPS fb_rpc / baidu_std Δ QPS, median (min ~ max) p50 µs p99 µs Server CPU µs/req
0 B 28,282 / 25,303 +11.8% (+4.7 ~ +24.7) 35 / 38 43 / 51 15.9 / 20.4
32 B 29,006 / 24,198 +13.4% (+10.7 ~ +29.9) 33 / 40 43 / 49 15.7 / 19.4
256 B 27,556 / 23,943 +16.0% (-1.9 ~ +19.5) 36 / 41 45 / 52 17.5 / 20.2
1 KB 26,330 / 23,436 +12.7% (+5.0 ~ +25.6) 37 / 42 46 / 52 16.6 / 21.1
4 KB 24,468 / 20,817 +14.0% (+9.0 ~ +23.3) 40 / 47 51 / 59 19.4 / 23.9
8 KB 21,338 / 18,744 +11.4% (+2.0 ~ +20.1) 46 / 52 57 / 66 20.8 / 25.5
16 KB 19,094 / 16,319 +15.3% (+10.3 ~ +21.2) 51 / 60 66 / 75 25.8 / 30.5
64 KB 7,892 / 6,687 +17.5% (+15.2 ~ +26.7) 122 / 146 187 / 226 61.2 / 70.8
256 KB 2,938 / 2,420 +20.6% (+12.1 ~ +26.5) 333 / 413 488 / 538 182.7 / 217.8
1 MB 821 / 654 +29.7% (+19.6 ~ +38.8) 1207 / 1597 1867 / 2258 993.2 / 1208.1

16 callers

Payload QPS fb_rpc / baidu_std Δ QPS, median (min ~ max) p50 µs p99 µs Server CPU µs/req
0 B 151,965 / 140,095 +6.7% (+2.9 ~ +10.2) 100 / 107 200 / 219 11.7 / 13.8
32 B 151,451 / 138,715 +8.1% (+4.4 ~ +14.1) 99 / 109 200 / 218 11.9 / 14.1
256 B 151,119 / 141,678 +8.5% (-2.3 ~ +10.5) 100 / 106 195 / 213 12.3 / 14.5
1 KB 142,284 / 131,145 +9.0% (+5.6 ~ +13.7) 106 / 115 209 / 224 13.0 / 15.7
4 KB 105,336 / 97,449 +8.7% (+2.0 ~ +19.3) 141 / 152 292 / 316 16.1 / 19.7
8 KB 87,068 / 80,145 +8.8% (+0.4 ~ +13.1) 170 / 184 354 / 382 19.5 / 23.8
16 KB 57,694 / 53,246 +8.0% (+1.8 ~ +12.7) 260 / 282 520 / 559 28.3 / 35.0
64 KB 24,376 / 22,574 +5.7% (+2.2 ~ +16.5) 669 / 722 855 / 945 58.7 / 72.4
256 KB 9,178 / 9,117 +0.8% (-1.1 ~ +1.6) 1739 / 1749 2109 / 2146 200.1 / 223.4
1 MB 2,316 / 2,235 +4.4% (+1.3 ~ +6.9) 6899 / 7144 8178 / 8395 639.2 / 771.8

64 callers

Payload QPS fb_rpc / baidu_std Δ QPS, median (min ~ max) p50 µs p99 µs Server CPU µs/req
0 B 353,581 / 337,546 +4.2% (+1.0 ~ +11.4) 163 / 171 363 / 390 7.4 / 8.8
32 B 362,863 / 329,893 +9.0% (+5.9 ~ +17.8) 158 / 175 349 / 391 7.3 / 9.0
256 B 349,073 / 331,986 +5.6% (+2.9 ~ +7.9) 165 / 173 353 / 377 7.8 / 9.5
1 KB 280,872 / 254,466 +11.7% (+0.6 ~ +14.6) 211 / 242 426 / 458 8.3 / 10.2
4 KB 181,194 / 168,392 +9.3% (+0.0 ~ +13.8) 350 / 376 606 / 649 11.2 / 13.6
8 KB 136,591 / 128,839 +6.9% (+4.2 ~ +8.5) 459 / 491 807 / 855 14.0 / 17.4
16 KB 95,390 / 87,490 +9.0% (+8.1 ~ +13.2) 671 / 736 898 / 1000 23.0 / 28.3
64 KB 36,368 / 36,195 +0.5% (-1.3 ~ +2.5) 1753 / 1765 2004 / 2022 52.1 / 59.8
256 KB 9,301 / 9,189 +0.3% (-1.2 ~ +3.3) 6876 / 6933 7448 / 7828 197.3 / 225.3
1 MB 2,355 / 2,195 +4.8% (+4.3 ~ +10.2) 27180 / 29080 29206 / 30947 659.4 / 867.9

For each case the two protocols ran back to back in the same round on the same server process. 15 of the 30 cases were measured in a second session (0 B, 256 B, 4 KB and 16 KB at all caller counts, and every size at 16 callers); results from the two sessions differ by a few percent on their own, so compare cases within a table row rather than across sessions.

Reproduce with the example (server and client hosts separate):

benchmark_fb_server --listen_addr=SERVER_IP:8901 --allow_remote --duration_s=3600 --max_concurrency=4096
for p in fb_rpc baidu_std; do
  benchmark_fb_client --server=SERVER_IP:8901 --allow_remote --protocol=$p --use_bthread=true \
    --duration_s=30 --warmup_s=3 --thread_num=64 --request_size=1024
done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants