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

Implement Netty based s3 API in worker #17661

Merged
merged 52 commits into from
Aug 3, 2023

Conversation

Jackson-Wang-7
Copy link
Contributor

What changes are proposed in this pull request?

Implement Netty based s3 API in worker

Why are the changes needed?

Please clarify why the changes are needed. For instance,

  1. If you propose a new API, clarify the use case for a new API.
  2. If you fix a bug, describe the bug.

Does this PR introduce any user facing changes?

Please list the user-facing changes introduced by your change, including

  1. change in user-facing APIs
  2. addition or removal of property keys
  3. webui

@Jackson-Wang-7 Jackson-Wang-7 changed the title Implement Netty based s3 API in worker(WIP) Implement Netty based s3 API in worker Jun 25, 2023
@Jackson-Wang-7
Copy link
Contributor Author

@lucyge2022 @JiamingMai @beinan please take a review about this PR. I started the pipeline of the HTTP protocol on the existing NettyDataServer to process S3 requests. Currently, it supports headObject and getObject (including zero-copy and non-zero-copy). I'm working on the listObject, putObject and other Ops.

Copy link
Contributor

@apc999 apc999 left a comment

Choose a reason for hiding this comment

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

Thanks for the great work! left some comments mostly in style and convention

pagedFileReader.getMultipleDataFileChannel(mHandler.getContext().channel(), length);
}
if (packet != null) {
mHandler.processTransferResponse(packet);
Copy link
Contributor

Choose a reason for hiding this comment

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

if we read from pagestore, which is a list of defaultfileregion opened for multiple pages for the total lengthed object, where the buffer is read thru the page files when u process them one by one, will it race with other reads thru Netty data reader? Meaning will we be reading a page where it no long exist any more during the read?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Don't worry, that's what we do in the rpc reading. I follow the exact same page reading process here and I have confirmed the opinions of Jiaming and Bowen on this process。 it's okay.

ByteBuf buf = mContext.channel().alloc().buffer(packetSize, packetSize);
try {
while (buf.writableBytes() > 0 && blockReader.transferTo(buf) != -1) {
mContext.write(new DefaultHttpContent(buf));
Copy link
Contributor

Choose a reason for hiding this comment

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

why not directly write buf?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to pass it package by package here, so we wrapped it with HTTPContent.

try {
while (buf.writableBytes() > 0 && blockReader.transferTo(buf) != -1) {
mContext.write(new DefaultHttpContent(buf));
buf = mContext.channel().alloc().buffer(packetSize, packetSize);
Copy link
Contributor

Choose a reason for hiding this comment

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

can we reuse a buf here instead of alloc everytime?
also is processMappedResponse ever going to be used now that all BlockReaders are actually PagedFileReader?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to reuse the buf before but I can't control when the channel release the buffer after I write it to the channel. So I just alloc it for the channel and then let channel release them after used.
this processMappedResponse is for the transfer type of MAPPED. This is indeed a limitation of FileRegion, which uses zero-copy and avoids putting data in the user space. But TLS needs to rewrite the data on the fly before sending it, so these two are incompatible

// the encoding type.
boolean isChunkedEncoding = decodedLengthHeader != null;
long toRead;
ByteBuf buf = mHandler.getRequestContent();
Copy link
Contributor

Choose a reason for hiding this comment

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

so FullHttpRequest contains the entire http body? The HttpObjectAggregator helps to aggregate entire http body into a fullhttprequest and then invoke channelread ? Have u tried upload a obj > 512KB ? And what if upload a 5G obj? is this buf gonna be of 5G in size?

@Jackson-Wang-7
Copy link
Contributor Author

@apc999 @lucyge2022 Based on the review comments, I have modified the relevant code. Can you take a look again and see if there are any other code lines that need to be modified?

Currently, only large file uploads are not supported, but considering that this may be a big and significant modification, can I support large file uploads in the next PR?

@Jackson-Wang-7
Copy link
Contributor Author

@apc999 @lucyge2022 Any other comments or changement suggestion for this PR? It is a basic PR, some functions are not currently supported. I will continue to supplement and improve them in subsequent PRs.

…_api

� Conflicts:
�	dora/minicluster/src/main/java/alluxio/multi/process/MultiProcessCluster.java
�	dora/tests/src/test/java/alluxio/client/rest/RestApiTest.java
Copy link
Contributor

@lucyge2022 lucyge2022 left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Contributor

@apc999 apc999 left a comment

Choose a reason for hiding this comment

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

thanks ! it looks good mostly, leaving another batch of comments.

dora/core/server/common/pom.xml Outdated Show resolved Hide resolved
requestHeaders, responseHeaders);
LOG.debug(accessLog + " " + moreInfoStr);
} else {
LOG.info(accessLog);
Copy link
Contributor

Choose a reason for hiding this comment

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

do we log every access?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, we log some basic info for every access request.

Copy link
Contributor

@apc999 apc999 left a comment

Choose a reason for hiding this comment

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

Minor comments left. LGTM!

thanks for the contribution

} else if (e instanceof IOException) {
return createNettyErrorResponse((IOException) e, resource);
} else {
ByteBuf contentBuffer =
Copy link
Contributor

Choose a reason for hiding this comment

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

can we put the allocation of contentBuff from Unpooled.copiedBuffer also into generateS3ErrorResponse, so generateS3ErrorResponse takes a message String as arg in stead of ByteBuff?

ex.

else {
  return generateS3ErrorResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage(),
          HttpHeaderValues.TEXT_PLAIN);
}

the reason is netty buffer allocation can be very tricky, so we want to reduce the locations where we allocate Netty ByteBuf (like using Unpooled.copiedBuffer). Typically, Netty ByteBuf requires calling release to reclaim the resource, but Unpooled.copiedBuffer is an exception. So let's try to consolidate these allocations and it is easier to manage in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch, I will change it

@Jackson-Wang-7
Copy link
Contributor Author

alluxio-bot, merge this please

@alluxio-bot alluxio-bot merged commit dbb6af2 into Alluxio:main Aug 3, 2023
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature This issue is a feature request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants