Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support remote engine server with flatbuffer write #1539

Closed
wants to merge 16 commits into from

Conversation

zealchen
Copy link
Contributor

@zealchen zealchen commented Jun 29, 2024

Rationale

Our benchmarks show flatbuffers has the best perf, thus we replace the remote server write operation from protobuf to flatbuffers protocol.

#1515

Detailed Changes

  1. Add a new flatbuffer(remote_engine.fbs) protocol schema.
  2. Implement RemoteEngineFbService trait for RemoteEngineServiceImpl as the new flatbuffer-based service.
  3. Make the write& batch_write interface backward compatible through the macros TonicWriteRequestExt and TonicWriteBatchRequestExt.
  4. Add Client/Server side implementation for flatbuffer write.

Test Plan

Manual test as follows:

  1. run horaemeta-server and two hoaredb-server on my Mac(M1) local machine.
  2. create a partition table:
curl --location --request POST 'http://127.0.0.1:5440/sql' \
-d '
CREATE TABLE `demo`(
    `name`string TAG,
    `id` int TAG,
    `value` double NOT NULL,
    `t` timestamp NOT NULL,
    TIMESTAMP KEY(t)
    ) PARTITION BY KEY(name) PARTITIONS 2 ENGINE = Analytic
'
  1. send write request:
curl --location --request POST 'http://127.0.0.1:15440/sql' \
-d '
INSERT INTO demo (t, name, value, id)
    VALUES (1702224000000, "horaedb", 100, 1)
'

Write request serialization benchmark test:

ANALYTIC_BENCH_CONFIG_PATH=bench.toml cargo bench -p benchmarks
  1. ContiguousRowWriter inner type build with ByteVec:
    pb encode: 131.916µs, pb decode: 63µs, fb encode: 174.459µs, fb decode: 83ns
  2. ContiguousRowWriter inner type build with FlatbufferBuilder:
    pb encode: 131.583µs, pb decode: 71.292µs, fb encode: 376.5µs, fb decode: 42ns

@zealchen zealchen changed the title support remote engine server with flatbuffer write [feat] Support remote engine server with flatbuffer write Jun 29, 2024
@zealchen zealchen changed the title [feat] Support remote engine server with flatbuffer write feat: Support remote engine server with flatbuffer write Jun 29, 2024
@github-actions github-actions bot added the feature New feature or request label Jun 29, 2024
@jiacai2050 jiacai2050 self-requested a review July 1, 2024 09:53
src/components/fb_util/src/common.rs Outdated Show resolved Hide resolved
code: header.code,
msg: header.error.clone(),
code: header.code(),
msg: header.error().unwrap().to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

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

The unwrap is safe here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change to unwrap_or() and also update server side to response None if error message if empty.

src/server/src/grpc/remote_engine_service/mod.rs Outdated Show resolved Hide resolved
.await?;
match result {
TonicWriteResponseExt::Flatbuffer(v) => Ok(v),
TonicWriteResponseExt::Proto(_) => Err(Status::new(Code::Internal, "logic error")),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
TonicWriteResponseExt::Proto(_) => Err(Status::new(Code::Internal, "logic error")),
TonicWriteResponseExt::Proto(_) => Err(Status::new(Code::Internal, "only support flatbuffer payload")),

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay.

src/server/src/grpc/remote_engine_service/mod.rs Outdated Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

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

common.rs is not suitable here, the file is only designed for remote_service, so remote_service.rs maybe better name.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay.

@@ -165,6 +166,7 @@ pub struct RpcServices {
rpc_server: InterceptedService<StorageServiceServer<StorageServiceImpl>, AuthWithFile>,
meta_rpc_server: Option<MetaEventServiceServer<MetaServiceImpl>>,
remote_engine_server: RemoteEngineServiceServer<RemoteEngineServiceImpl>,
remote_engine_server_ext: RemoteEngineFbServiceServer<RemoteEngineServiceImpl>,
Copy link
Contributor

Choose a reason for hiding this comment

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

remote_engine_fb_server ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay.

})?;
let mut rpc_client = RemoteEngineServiceClient::<Channel>::new(route_context.channel);

let mut rpc_client = RemoteEngineFbServiceClient::<Channel>::new(route_context.channel);
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean remote server will only have request with fb payload?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding a REQUEST_TYPE environment variable to support both protobuf and flatbuffer protocol.

}
TonicWriteBatchRequestExt::Flatbuffer(v) => {
let request = Arc::new(v.into_inner());
let req = request.deserialize::<FBWriteBatchRequest>().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

There are several unwrap in this block, are they all safe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. FlatBufferBytes::deserialize is changed to unsafe function call as internal request routing is supposed to be safe among servers.
  2. Other unwraps are all based on batch() which cannot be None in internal procedure.
  3. Always follow the backwards compatibility solution for the schema design (https://flatbuffers.dev/flatbuffers_guide_tutorial.html)


fn build_fb_write_response(resp: WriteResponse) -> FlatBufferBytes {
let mut builder = flatbuffers::FlatBufferBuilder::with_capacity(1024);
let header = resp.header.unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this unwrap?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Change it to unwrap_or_default?

@@ -109,6 +130,16 @@ pub struct TableIdentifier {
pub table: String,
}

impl From<FBTableIdentifier<'_>> for TableIdentifier {
Copy link
Contributor

Choose a reason for hiding this comment

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

Impl TryFrom to remove those unwrap?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@jiacai2050
Copy link
Contributor

As said in description, the improvement after introduce Flatbuffer is not what we originally expected, the reason is that this PR only refactor upper layer of the put request, the ContiguousRow's encoding is unchanged, however it's where cost mainly come from, so we cannot get much perf improvement without refactor it.

But ContiguousRow is a heavily used structure in write path, refactor it would introduce much more changes, so I suggest we stop working on this, sorry for not find this earlier.

Really appreciated your work on this.

@jiacai2050 jiacai2050 closed this Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants