Skip to content

Feat: Add adaptive input message batching - #3484

Open
FangzuoZhang wants to merge 1 commit into
apache:masterfrom
FangzuoZhang:feature/adaptive-input-message-batching
Open

Feat: Add adaptive input message batching#3484
FangzuoZhang wants to merge 1 commit into
apache:masterfrom
FangzuoZhang:feature/adaptive-input-message-batching

Conversation

@FangzuoZhang

@FangzuoZhang FangzuoZhang commented Aug 24, 2026

Copy link
Copy Markdown

What problem does this PR solve?

Issue Number: N/A

Related work:

Problem Summary:

InputMessenger currently schedules each parsed input message in a separate
bthread. For short message handlers and bursty traffic on a single connection,
bthread creation and scheduling may account for a significant portion of the
request-processing overhead.

This PR introduces optional input message batching. Messages parsed from the
same socket can be processed sequentially in one bthread, reducing scheduling
overhead while preserving the existing behavior by default.

What is changed and the side effects?

Design

Parsed messages
  m1  m2  m3  ...  mN
           |
           v
+--------------------------+
| Batch Size Controller    |
| fixed or adaptive (EMA)  |
| size: 1 / 2 / 4 / 8 / 16|
+------------+-------------+
             |
             v
+--------------------------+
| InputMessageBatch        |
| [m1, m2, ... , mk]       |
+------------+-------------+
             |
             v
      One bthread
             |
             v
  m1 -> m2 -> ... -> mk
  processed sequentially

Changed:

  • Add the experimental input_message_batch_process_size gflag:
    • 0 or 1: preserve the original one-message-per-bthread behavior.
    • Values greater than 1: use a fixed batch size.
    • -1: adaptively select a batch size from 1, 2, 4, 8, and 16.
    • Values smaller than -1 are rejected.
  • Add InputMessageBatch to own and process messages in their original order.
  • Add per-socket adaptive state based on an exponentially weighted moving
    average of messages parsed from each read.
  • Increase the adaptive batch size gradually and decrease it more quickly when
    the observed burst size drops.
  • Reset adaptive history after switching away from adaptive mode.
  • Support batch scheduling in TCP, RDMA, and UBShm/UBRing transports.
  • Preserve the existing last-message scheduling optimization.
  • Keep progressive-read messages on the individual-message path.
  • Disable batching when user code runs in coroutine mode.
  • Fall back to synchronous processing if batch allocation or bthread creation
    fails.

Side effects:

  • Performance effects:

    The default value is 0, so existing deployments retain the original
    scheduling behavior.

    When batching is enabled, it reduces bthread creation and scheduling overhead
    for bursty workloads. A larger fixed batch may increase the time that later
    messages wait behind earlier handlers. Adaptive mode limits the maximum batch
    size to 16 and decreases the batch size quickly when the observed burst size
    drops.

  • Breaking backward compatibility:

    There is no change to the public RPC protocol or default runtime behavior.

    The internal Transport interface gains a QueueMessages virtual method.
    Downstream custom transport implementations derived directly from
    Transport must implement this method.

Performance test

The RDMA performance example was used with a single connection and multiple
outstanding requests on that connection. Each attachment size was tested three
times.

  • Baseline: input_message_batch_process_size=0
  • Optimized: input_message_batch_process_size=-1
  • queue_depth must be greater than 1 to produce message bursts on the same
    connection.
  • Latency values are in microseconds.
  • CPU utilization may exceed 100% because it represents multi-core process CPU
    usage.
  • QPS improvement is calculated against the average QPS of the unoptimized
    baseline.

Average results

The following results were measured on a Kunpeng 950 server in RDMA mode.
Each attachment size was tested three times, and the reported values are the
arithmetic averages of those runs.

  • Baseline: input_message_batch_process_size=0
  • Optimized: input_message_batch_process_size=-1
  • Latency values are in microseconds.
  • CPU utilization may exceed 100% because it represents multi-core process CPU
    usage.
  • QPS improvement is calculated against the average QPS of the baseline.
Attachment Avg Latency P90 P99 Baseline QPS Batched QPS Avg Server CPU Client CPU QPS Improvement
0 bytes 351.00 543.00 810.00 2684.100 2886.265 1336.00% 3950.67% +7.53%
256 bytes 398.00 610.67 927.00 2377.408 2545.978 1315.00% 4798.00% +7.09%
1 KB 438.33 683.67 1044.67 2174.254 2320.362 1322.67% 3732.67% +6.72%
4 KB 660.67 1135.67 2123.33 1486.802 1544.824 1270.00% 2577.33% +3.90%
8 KB 1031.00 2310.00 5289.33 1049.357 1104.763 1177.00% 1993.33% +5.28%
100 KB 7388.67 12362.00 22406.67 134.602 138.385 925.33% 988.00% +2.81%

Check List:

@FangzuoZhang FangzuoZhang changed the title Add adaptive input message batching Feat: Add adaptive input message batching Aug 24, 2026
@chenBright
chenBright requested a lite review from Copilot August 24, 2026 14:19

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.

Pull request overview

This PR adds an optional (experimental) input-message batching path to reduce bthread creation/scheduling overhead under bursty traffic by processing multiple parsed messages from the same socket sequentially in a single bthread, while preserving the existing behavior by default.

Changes:

  • Introduces -input_message_batch_process_size (0/1 disabled, fixed >1, adaptive -1) and implements InputMessageBatch + batch scheduling in InputMessenger.
  • Extends the internal Transport interface with QueueMessages(...) and implements it in TCP/RDMA/UBShm transports.
  • Adds per-socket adaptive batching state (EMA + current batch size) and exposes debug output for the new stats.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/brpc/input_messenger.h Adds InputMessageBatch type and batching-related helper declarations.
src/brpc/input_messenger.cpp Implements batching flag, adaptive sizing logic, and batch enqueueing/flush behavior.
src/brpc/transport.h Adds new pure-virtual QueueMessages API for transports.
src/brpc/tcp_transport.h Declares TCP transport support for QueueMessages.
src/brpc/tcp_transport.cpp Implements batch enqueue via bthread for TCP transport.
src/brpc/rdma_transport.h Declares RDMA transport support for QueueMessages.
src/brpc/rdma_transport.cpp Implements batch enqueue via bthread for RDMA transport.
src/brpc/ubshm_transport.h Declares UBShm transport support for QueueMessages.
src/brpc/ubshm_transport.cpp Implements batch enqueue via bthread for UBShm transport.
src/brpc/socket.h Adds per-socket adaptive batching state fields.
src/brpc/socket.cpp Initializes/resets new per-socket adaptive state; adds debug printing.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +254 to +256
if (!batch->get()) {
batch->reset(new (std::nothrow) InputMessageBatch(batch_size));
}
Comment on lines +177 to +188
void UBShmTransport::QueueMessages(InputMessageBatch* input_msgs,
int* num_bthread_created, bool last_msg) {
CHECK(!last_msg);
if (!input_msgs || input_msgs->empty()) {
delete input_msgs;
return;
}
if (ubring::FLAGS_ub_disable_bthread) {
input_msgs->Run();
delete input_msgs;
return;
}
Comment on lines +186 to +197
void RdmaTransport::QueueMessages(InputMessageBatch* input_msgs,
int* num_bthread_created, bool last_msg) {
CHECK(!last_msg || rdma::FLAGS_rdma_use_polling);
if (!input_msgs || input_msgs->empty()) {
delete input_msgs;
return;
}
if (rdma::FLAGS_rdma_disable_bthread) {
input_msgs->Run();
delete input_msgs;
return;
}
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.

2 participants