-
Notifications
You must be signed in to change notification settings - Fork 593
HDDS-7058. EC: ReplicationManager - Implement ratis container replication check handler #3802
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
Changes from all commits
049302b
03e14d2
a2adb27
389614b
520c6b9
2975ce4
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 |
|---|---|---|
|
|
@@ -15,10 +15,11 @@ | |
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.hadoop.hdds.scm.container; | ||
| package org.apache.hadoop.hdds.scm.container.replication; | ||
|
|
||
| import org.apache.hadoop.hdds.protocol.proto.HddsProtos; | ||
| import org.apache.hadoop.hdds.scm.container.replication.ContainerReplicaCount; | ||
| import org.apache.hadoop.hdds.scm.container.ContainerInfo; | ||
| import org.apache.hadoop.hdds.scm.container.ContainerReplica; | ||
|
|
||
| import java.util.Set; | ||
|
|
||
|
|
@@ -243,11 +244,27 @@ private int missingReplicas() { | |
| */ | ||
| @Override | ||
| public boolean isSufficientlyReplicated() { | ||
| return missingReplicas() + inFlightDel <= 0; | ||
| return isSufficientlyReplicated(false); | ||
| } | ||
|
|
||
| /** | ||
| * Return true is the container is over replicated. Decommission and | ||
| * Return true if the container is sufficiently replicated. Decommissioning | ||
| * and Decommissioned containers are ignored in this check, assuming they will | ||
| * eventually be removed from the cluster. | ||
| * This check ignores inflight additions, if includePendingAdd is false, | ||
| * otherwise it will assume they complete ok. | ||
| * | ||
| * @return True if the container is sufficiently replicated and False | ||
| * otherwise. | ||
| */ | ||
| public boolean isSufficientlyReplicated(boolean includePendingAdd) { | ||
| // Positive for under-rep, negative for over-rep | ||
| int delta = redundancyDelta(true, includePendingAdd); | ||
| return delta <= 0; | ||
| } | ||
|
|
||
| /** | ||
| * Return true if the container is over replicated. Decommission and | ||
| * maintenance containers are ignored for this check. | ||
| * The check ignores inflight additions, as they may fail, but it does | ||
| * consider inflight deletes, as they would reduce the over replication when | ||
|
|
@@ -257,7 +274,67 @@ public boolean isSufficientlyReplicated() { | |
| */ | ||
| @Override | ||
| public boolean isOverReplicated() { | ||
| return missingReplicas() + inFlightDel < 0; | ||
| return isOverReplicated(true); | ||
| } | ||
|
|
||
| /** | ||
| * Return true if the container is over replicated. Decommission and | ||
| * maintenance containers are ignored for this check. | ||
| * The check ignores inflight additions, as they may fail, but it does | ||
| * consider inflight deletes if includePendingDelete is true. | ||
| * | ||
| * @return True if the container is over replicated, false otherwise. | ||
| */ | ||
| public boolean isOverReplicated(boolean includePendingDelete) { | ||
|
||
| return getExcessRedundancy(includePendingDelete) > 0; | ||
| } | ||
|
|
||
| /** | ||
| * @return Return Excess Redundancy replica nums. | ||
| */ | ||
| public int getExcessRedundancy(boolean includePendingDelete) { | ||
|
||
| int excessRedundancy = redundancyDelta(includePendingDelete, false); | ||
| if (excessRedundancy >= 0) { | ||
| // either perfectly replicated or under replicated | ||
| return 0; | ||
| } | ||
| return -excessRedundancy; | ||
| } | ||
|
|
||
| /** | ||
| * Return the delta from the expected number of replicas, optionally | ||
| * considering inflight add and deletes. | ||
| * @param includePendingDelete | ||
| * @param includePendingAdd | ||
| * @return zero if perfectly replicated, a negative value for over replication | ||
| * and a positive value for under replication. The magnitude of the | ||
| * return value indicates how many replias the container is over or | ||
| * under replicated by. | ||
| */ | ||
| private int redundancyDelta(boolean includePendingDelete, | ||
| boolean includePendingAdd) { | ||
| int excessRedundancy = missingReplicas(); | ||
| if (includePendingDelete) { | ||
| excessRedundancy += inFlightDel; | ||
| } | ||
| if (includePendingAdd) { | ||
| excessRedundancy -= inFlightAdd; | ||
| } | ||
| return excessRedundancy; | ||
| } | ||
|
|
||
| /** | ||
| * How many more replicas can be lost before the container is | ||
| * unreadable, assuming any infligh deletes will complete. For containers | ||
| * which are under-replicated due to decommission | ||
| * or maintenance only, the remaining redundancy will include those | ||
| * decommissioning or maintenance replicas, as they are technically still | ||
| * available until the datanode processes are stopped. | ||
| * @return Count of remaining redundant replicas. | ||
| */ | ||
| public int getRemainingRedundancy() { | ||
| return Math.max(0, | ||
| healthyCount + decommissionCount + maintenanceCount - inFlightDel - 1); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
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.
Should we have another constructor which initializes the following arguments?
public UnderReplicatedHealthResult(ContainerInfo containerInfo,
int remainingRedundancy, boolean dueToDecommission, boolean replicatedOkWithPending, boolean unrecoverable,boolean dueToMisReplication, boolean isMisReplicated, boolean isMisReplicatedAfterPending)
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.
I don't want to change the existing constructor, as then we need to change it everywhere it is used. Adding a new constructor starts a bad pattern where each new parameter needs a new constructor, and what we really need is a builder.
At the moment I think these 3 parameters have good defaults for the common case and then using the settings when needed is a good compromise.