HDFS-17198. RBF: fix bug of getRepresentativeQuorum when records have same dateModified (#6096)

This commit is contained in:
Jian Zhang 2023-09-21 01:04:29 +08:00 committed by GitHub
parent 5512c9f924
commit d273c13ab5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 71 additions and 0 deletions

View File

@ -358,4 +358,23 @@ public long getDeletionMs() {
public static void setDeletionMs(long time) {
MembershipState.deletionMs = time;
}
/**
* First use the comparator of the BaseRecord to compare the date modified.
* If they are equal, compare their primary keys to ensure that MembershipStates
* with the same date modified but reported by different routers will not be judged as equal.
*
* @param record the MembershipState object to be compared.
* @return a negative integer, zero, or a positive integer as this object
* is less than, equal to, or greater than the specified object.
*/
@Override
public int compareTo(BaseRecord record) {
int order = super.compareTo(record);
if (order == 0) {
MembershipState other = (MembershipState) record;
return this.getPrimaryKey().compareTo(other.getPrimaryKey());
}
return order;
}
}

View File

@ -223,6 +223,58 @@ public void testRegistrationMajorityQuorum()
assertEquals(quorumEntry.getRouterId(), ROUTERS[3]);
}
/**
* Fix getRepresentativeQuorum when records have same date modified time.
*/
@Test
public void testRegistrationMajorityQuorumEqDateModified()
throws IOException {
// Populate the state store with a set of non-matching elements
// 1) ns0:nn0 - Standby (newest)
// 2) ns0:nn0 - Active
// 3) ns0:nn0 - Active
// 4) ns0:nn0 - Active
// (2), (3), (4) have the same date modified time
// Verify the selected entry is the newest majority opinion (4)
String ns = "ns0";
String nn = "nn0";
long dateModified = Time.now();
// Active - oldest
MembershipState report = createRegistration(
ns, nn, ROUTERS[1], FederationNamenodeServiceState.ACTIVE);
report.setDateModified(dateModified);
assertTrue(namenodeHeartbeat(report));
// Active - 2nd oldest
report = createRegistration(
ns, nn, ROUTERS[2], FederationNamenodeServiceState.ACTIVE);
report.setDateModified(dateModified);
assertTrue(namenodeHeartbeat(report));
// Active - 3rd oldest
report = createRegistration(
ns, nn, ROUTERS[3], FederationNamenodeServiceState.ACTIVE);
report.setDateModified(dateModified);
assertTrue(namenodeHeartbeat(report));
// standby - newest overall
report = createRegistration(
ns, nn, ROUTERS[0], FederationNamenodeServiceState.STANDBY);
assertTrue(namenodeHeartbeat(report));
// Load and calculate quorum
assertTrue(getStateStore().loadCache(MembershipStore.class, true));
// Verify quorum entry
MembershipState quorumEntry = getNamenodeRegistration(
report.getNameserviceId(), report.getNamenodeId());
assertNotNull(quorumEntry);
// The name node status should be active
assertEquals(FederationNamenodeServiceState.ACTIVE, quorumEntry.getState());
}
@Test
public void testRegistrationQuorumExcludesExpired()
throws InterruptedException, IOException {