-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Fix crc mismatch during deepstore upload retry task #14506
Changes from 3 commits
249a4ee
4f01b87
271c305
dc02f8c
ed27889
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -82,6 +82,7 @@ | |
import org.apache.pinot.controller.helix.core.realtime.segment.FlushThresholdUpdater; | ||
import org.apache.pinot.controller.helix.core.retention.strategy.RetentionStrategy; | ||
import org.apache.pinot.controller.helix.core.retention.strategy.TimeRetentionStrategy; | ||
import org.apache.pinot.controller.util.ServerSegmentMetadataReader; | ||
import org.apache.pinot.controller.validation.RealtimeSegmentValidationManager; | ||
import org.apache.pinot.core.data.manager.realtime.SegmentCompletionUtils; | ||
import org.apache.pinot.core.util.PeerServerSegmentFinder; | ||
|
@@ -1557,6 +1558,7 @@ public void uploadToDeepStoreIfMissing(TableConfig tableConfig, List<SegmentZKMe | |
|
||
// Randomly ask one server to upload | ||
URI uri = peerSegmentURIs.get(RANDOM.nextInt(peerSegmentURIs.size())); | ||
String crcFromServer = getSegmentCrcFromServer(realtimeTableName, segmentName, uri.toString()); | ||
String serverUploadRequestUrl = StringUtil.join("/", uri.toString(), "upload"); | ||
serverUploadRequestUrl = | ||
String.format("%s?uploadTimeoutMs=%d", serverUploadRequestUrl, _deepstoreUploadRetryTimeoutMs); | ||
|
@@ -1569,6 +1571,10 @@ public void uploadToDeepStoreIfMissing(TableConfig tableConfig, List<SegmentZKMe | |
|
||
// Update segment ZK metadata by adding the download URL | ||
segmentZKMetadata.setDownloadUrl(segmentDownloadUrl); | ||
// Update ZK crc to that of the server segment crc if unmatched | ||
if (Long.parseLong(crcFromServer) != segmentZKMetadata.getCrc()) { | ||
segmentZKMetadata.setCrc(Long.parseLong(crcFromServer)); | ||
} | ||
// TODO: add version check when persist segment ZK metadata | ||
persistSegmentZKMetadata(realtimeTableName, segmentZKMetadata, -1); | ||
LOGGER.info("Successfully uploaded LLC segment {} to deep store with download url: {}", segmentName, | ||
|
@@ -1593,6 +1599,16 @@ public void uploadToDeepStoreIfMissing(TableConfig tableConfig, List<SegmentZKMe | |
} | ||
} | ||
|
||
@VisibleForTesting | ||
String getSegmentCrcFromServer(String tableNameWithType, String segmentName, String endpoint) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this backward compatible when the server is still running the old pinot version? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The proposed change is not fully backward compatible during the interim period when the controller has been rolled out but the server is still running an older version. This is a common challenge for changes that involve interactions between the controller and server. Below are the considerations and potential solutions to address this issue:
|
||
ServerSegmentMetadataReader serverSegmentMetadataReader = new ServerSegmentMetadataReader(); | ||
String crcFromServer = serverSegmentMetadataReader.getCrcForSegmentFromServer(tableNameWithType, | ||
segmentName, endpoint); | ||
Preconditions.checkState(crcFromServer != null, | ||
"Failed to get CRC from endpoint %s for segment %s", endpoint, segmentName); | ||
return crcFromServer; | ||
} | ||
|
||
@VisibleForTesting | ||
boolean deepStoreUploadExecutorPendingSegmentsIsEmpty() { | ||
return _deepStoreUploadExecutorPendingSegments.isEmpty(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently we read crc and ask server to upload as 2 separate steps. A more ideal solution would be to enhance the server upload API to return both segment location (i.e.
tempSegmentDownloadUrl
) and also crc. The response can be a json wrapping more info other than the download url.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change would require implementing a new server API, as users might be directly utilizing the existing API, making the modification backward-incompatible. If introducing a new API is acceptable, I can proceed with its implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new API is okay since the response format is changing. To keep it backward compatible, controller can first try the new API, and fallback to the old API if new API returns error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sgtm! Updated accordingly.