-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Move segment update APIs from Coordinator to Overlord #17545
base: master
Are you sure you want to change the base?
Conversation
@ResourceFilters(DatasourceResourceFilter.class) | ||
public Response markAllNonOvershadowedSegmentsAsUsed( | ||
@PathParam("dataSourceName") final String dataSourceName, | ||
@Context HttpServletRequest req |
Check notice
Code scanning / CodeQL
Useless parameter Note
return Response.status(Response.Status.BAD_REQUEST).entity( | ||
org.apache.druid.java.util.common.StringUtils.format("Could not parse Segment ID[%s]", segmentIdString) | ||
).build(); |
Check warning
Code scanning / CodeQL
Cross-site scripting Medium
user-provided value
return Response.status(Response.Status.BAD_REQUEST).entity( | ||
org.apache.druid.java.util.common.StringUtils.format("Could not parse Segment ID[%s]", segmentIdString) | ||
).build(); |
Check warning
Code scanning / CodeQL
Cross-site scripting Medium
user-provided value
DataSourcesResource dataSourcesResource = createResource(); | ||
prepareRequestForAudit(); | ||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload, request); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, payload, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
DataSourcesResource dataSourcesResource = createResource(); | ||
prepareRequestForAudit(); | ||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload, request); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, segmentFilter, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
DataSourcesResource dataSourcesResource = createResource(); | ||
prepareRequestForAudit(); | ||
|
||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload, request); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, segmentFilter, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
DataSourcesResource dataSourcesResource = createResource(); | ||
prepareRequestForAudit(); | ||
|
||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload, request); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, segmentFilter, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
@@ -1370,7 +1399,7 @@ | |||
{ | |||
DataSourcesResource dataSourcesResource = createResource(); | |||
|
|||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", null, request); | |||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, null, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
|
||
Response response = dataSourcesResource.markSegmentsAsUnused("datasource1", payload, request); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, payload, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
EasyMock.replay(overlordClient); | ||
|
||
DataSourcesResource dataSourcesResource = createResource(); | ||
Response response = dataSourcesResource.markSegmentsAsUnused(TestDataSource.WIKI, segmentFilter, request); |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markSegmentsAsUnused
() -> dataSourcesResource.markAsUnusedAllSegmentsOrKillUnusedSegmentsInInterval( | ||
"datasource", | ||
"true", | ||
"???", | ||
request | ||
) |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
DataSourcesResource.markAsUnusedAllSegmentsOrKillUnusedSegmentsInInterval
return Response.status(Response.Status.BAD_REQUEST).entity( | ||
StringUtils.format("Could not parse Segment ID[%s] for DataSource[%s]", segmentIdString, dataSourceName) | ||
).build(); |
Check warning
Code scanning / CodeQL
Cross-site scripting Medium
user-provided value
Cross-site scripting vulnerability due to a
user-provided value
|
||
DataSourcesResource dataSourcesResource = createResource(); | ||
final StringFullResponseHolder responseHolder = new StringFullResponseHolder( |
Check notice
Code scanning / CodeQL
Deprecated method or constructor invocation Note test
Description
#17336 proposes adding a cache of segments on the leader Overlord to speed up segment allocation and other segment actions. But any caching mechanism can be efficient only if the leader Overlord is the source of truth and all segment updates happen through it.
This PR tries to move the Coordinator APIs which update segments to the Overlord instead.
Changes
Main classes to review
DataSourcesResource
OverlordDataSourcesResources
OverlordClient
andOverlordClientImpl
Summary of changes
OverlordDataSourcesResource
with APIs to mark segments used/unusedOverlordClient
OverlordClient
inDataSourcesResource
so that Coordinator APIs internallycall the corresponding Overlord APIs
Other minor changes
OverlordClient
on the coordinator sideDataSourcesResource
.OverlordClient
is always non-null in production.TestSegmentsMetadataManager
New Overlord APIs
POST /druid/indexer/v1/datasources/{dataSourceName}
DELETE /druid/indexer/v1/datasources/{dataSourceName}
POST /druid/indexer/v1/datasources/{dataSourceName}/markUsed
POST /druid/indexer/v1/datasources/{dataSourceName}/markUnused
POST /druid/indexer/v1/datasources/{dataSourceName}/segments/{segmentId}
DELETE /druid/indexer/v1/datasources/{dataSourceName}/segments/{segmentId}
Sample response
Rolling upgrades
During a rolling upgrade, if the leader Coordinator gets upgraded before the leader Overlord,
it might try to call new Overlord APIs but that would throw a 404 NOT FOUND error.
In this case, the Coordinator falls back to the original method of updating the metadata store directly.
Pending items
Changes not in this PR
Release note
Add new Overlord APIs to mark non-overshadowed segments as used
POST /druid/indexer/v1/datasources/{dataSourceName}
POST /druid/indexer/v1/datasources/{dataSourceName}/markUsed
POST /druid/indexer/v1/datasources/{dataSourceName}/segments/{segmentId}
Add new Overlord APIs to mark segments as unused:
POST /druid/indexer/v1/datasources/{dataSourceName}/markUnused
DELETE /druid/indexer/v1/datasources/{dataSourceName}/segments/{segmentId}
DELETE /druid/indexer/v1/datasources/{dataSourceName}
The corresponding Coordinator APIs are being deprecated and will be removed in a future release:
POST /druid/coordinator/v1/datasources/{dataSourceName}
POST /druid/coordinator/v1/datasources/{dataSourceName}/markUsed
POST /druid/coordinator/v1/datasources/{dataSourceName}/markUnused
POST /druid/coordinator/v1/datasources/{dataSourceName}/segments/{segmentId}
DELETE /druid/coordinator/v1/datasources/{dataSourceName}/segments/{segmentId}
DELETE /druid/coordinator/v1/datasources/{dataSourceName}
Until they are removed, these Coordinator APIs will internally invoke respective Overlord APIs.
This PR has: