-
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
#12117 Support for Server & Controller API to check for Segments reload of a table in servers #13789
#12117 Support for Server & Controller API to check for Segments reload of a table in servers #13789
Changes from 18 commits
03ab3be
557eb73
ab901a3
4e4a961
e3ea6a8
de79260
36beb11
0ee036f
c8ba979
e1c7c64
b9e4fbf
eef4de5
9b904c6
38992b1
d10b8b2
12656ec
b987f0e
c6aa9ca
8848fa6
048eb50
e439b54
028449c
5c50cca
8366580
25ab04c
760450f
ff0f1a1
a5880c2
a0006c9
9bac29a
84bb84b
5491662
8173c1c
3649c78
a14af52
ad11da4
468b36d
d1b330a
ff056b0
33a2408
3d7a0ee
5f555e7
efa1766
00d2220
aa3a722
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 |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/** | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you under the Apache License, Version 2.0 (the | ||
* "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
package org.apache.pinot.common.restlet.resources; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
|
||
/** | ||
* This class gives the data of a server if there exists any segments that need to be reloaded | ||
* | ||
* It has details of server id and returns true/false if there are any segments to be reloaded or not. | ||
*/ | ||
public class SegmentsReloadCheckResponse { | ||
private final boolean _needReload; | ||
private final String _serverInstanceId; | ||
|
||
public String getServerInstanceId() { | ||
return _serverInstanceId; | ||
} | ||
|
||
public boolean getReload() { | ||
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. This method name might not work for JSON serialization. I think it will be mistakenly serialized as |
||
return _needReload; | ||
} | ||
|
||
@JsonCreator | ||
public SegmentsReloadCheckResponse(@JsonProperty("needReload") boolean needReload, | ||
@JsonProperty("serverInstanceId") String serverInstanceId) { | ||
_needReload = needReload; | ||
_serverInstanceId = serverInstanceId; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1013,6 +1013,22 @@ public boolean tryLoadExistingSegment(SegmentZKMetadata zkMetadata, IndexLoading | |
} | ||
} | ||
|
||
boolean needReloadSegment(SegmentZKMetadata zkMetadata, IndexLoadingConfig indexLoadingConfig) | ||
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. Make it |
||
throws Exception { | ||
String segmentName = zkMetadata.getSegmentName(); | ||
SegmentDirectory segmentDirectory = | ||
tryInitSegmentDirectory(segmentName, String.valueOf(zkMetadata.getCrc()), indexLoadingConfig); | ||
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. This can cause exception for consuming segments. We should only check immutable segments. We can read the 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. Checked for ImmutableSegmentImpl instance before passing it through needReload where SegmentDirectory is generated. I think this should avoid any exception cases of consuming segments. Adding more tests along with controller side code and to combine with the same PR. |
||
try { | ||
Schema schema = indexLoadingConfig.getSchema(); | ||
//if re processing or reload is needed on a segment then return true | ||
return ImmutableSegmentLoader.needPreprocess(segmentDirectory, indexLoadingConfig, schema); | ||
} catch (Exception e) { | ||
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. We can probably directly throw the exception out without catch 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. closeSegmentDirectoryQuietly(segmentDirectory); There is this closure being handled in exception cases( so wrote a catch block). Do you want me to handle this in finally? 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. If we can use the 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. Done |
||
_logger.error("Failed to check if reload is needed for a segment {}", segmentName, e); | ||
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. Can we emit a server metric to indicate that something is wrong when running the check? 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. I feel that might be overkilling. IMO we can simply throw the exception out, and client can handle it accordingly. |
||
closeSegmentDirectoryQuietly(segmentDirectory); | ||
throw new Exception(String.format("Failed to perform reload check on the segment %s", segmentName)); | ||
} | ||
} | ||
|
||
@Nullable | ||
private SegmentDirectory tryInitSegmentDirectory(String segmentName, String segmentCrc, | ||
IndexLoadingConfig indexLoadingConfig) { | ||
|
@@ -1024,6 +1040,28 @@ private SegmentDirectory tryInitSegmentDirectory(String segmentName, String segm | |
} | ||
} | ||
|
||
@Override | ||
public boolean needReloadSegments() | ||
throws Exception { | ||
IndexLoadingConfig indexLoadingConfig = fetchIndexLoadingConfig(); | ||
List<SegmentDataManager> segmentDataManagers = acquireAllSegments(); | ||
boolean needReload = false; | ||
try { | ||
for (SegmentDataManager segmentDataManager : segmentDataManagers) { | ||
SegmentZKMetadata segmentZKMetadata = fetchZKMetadata(segmentDataManager.getSegmentName()); | ||
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. Let's not read ZK metadata because it needs to access ZK, and we might end up reading it for thousands of segments. |
||
if (needReloadSegment(segmentZKMetadata, indexLoadingConfig)) { | ||
needReload = true; | ||
break; | ||
} | ||
} | ||
} finally { | ||
for (SegmentDataManager segmentDataManager : segmentDataManagers) { | ||
releaseSegment(segmentDataManager); | ||
} | ||
} | ||
return needReload; | ||
} | ||
|
||
private SegmentDirectory initSegmentDirectory(String segmentName, String segmentCrc, | ||
IndexLoadingConfig indexLoadingConfig) | ||
throws Exception { | ||
|
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.
(minor)
instanceId
might be more concise because this is always returned from server.Do we really need to return it? Controller should already have this info when reading the address of the server
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.
We have it, it's just little complex to separate out server instance when doing multi get request which is why just returning it as well in the response to make it simpler. I will look into this later. For now, we can include instanceId as well I think