HBASE-23737 [Flakey Tests] TestFavoredNodeTableImport fails 30% of the time; AMENDMENT
This is actual fix; previous added debug to test.
This commit is contained in:
parent
1690414263
commit
d82c3a5ebd
|
@ -1,5 +1,4 @@
|
||||||
/**
|
/*
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
* distributed with this work for additional information
|
* distributed with this work for additional information
|
||||||
|
@ -23,7 +22,6 @@ import static org.apache.hadoop.hbase.favored.FavoredNodeAssignmentHelper.FAVORE
|
||||||
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.PRIMARY;
|
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.PRIMARY;
|
||||||
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.SECONDARY;
|
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.SECONDARY;
|
||||||
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.TERTIARY;
|
import static org.apache.hadoop.hbase.favored.FavoredNodesPlan.Position.TERTIARY;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -31,9 +29,8 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hbase.HBaseIOException;
|
|
||||||
import org.apache.hadoop.hbase.ServerName;
|
import org.apache.hadoop.hbase.ServerName;
|
||||||
import org.apache.hadoop.hbase.client.RegionInfo;
|
import org.apache.hadoop.hbase.client.RegionInfo;
|
||||||
import org.apache.hadoop.hbase.master.MasterServices;
|
import org.apache.hadoop.hbase.master.MasterServices;
|
||||||
|
@ -56,22 +53,21 @@ import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
|
||||||
* should be done through this class. There should only be one instance of
|
* should be done through this class. There should only be one instance of
|
||||||
* {@link FavoredNodesManager} in Master. {@link FavoredNodesPlan} and favored node information
|
* {@link FavoredNodesManager} in Master. {@link FavoredNodesPlan} and favored node information
|
||||||
* from {@link SnapshotOfRegionAssignmentFromMeta} should not be used outside this class (except
|
* from {@link SnapshotOfRegionAssignmentFromMeta} should not be used outside this class (except
|
||||||
* for may be tools that only read or test cases). All other classes including Favored balancers
|
* for tools that only read or fortest cases). All other classes including Favored balancers
|
||||||
* and {@link FavoredNodeAssignmentHelper} should use {@link FavoredNodesManager} for any
|
* and {@link FavoredNodeAssignmentHelper} should use {@link FavoredNodesManager} for any
|
||||||
* read/write/deletes to favored nodes.
|
* read/write/deletes to favored nodes.
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class FavoredNodesManager {
|
public class FavoredNodesManager {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(FavoredNodesManager.class);
|
private static final Logger LOG = LoggerFactory.getLogger(FavoredNodesManager.class);
|
||||||
|
|
||||||
private FavoredNodesPlan globalFavoredNodesAssignmentPlan;
|
private final FavoredNodesPlan globalFavoredNodesAssignmentPlan;
|
||||||
private Map<ServerName, List<RegionInfo>> primaryRSToRegionMap;
|
private final Map<ServerName, List<RegionInfo>> primaryRSToRegionMap;
|
||||||
private Map<ServerName, List<RegionInfo>> secondaryRSToRegionMap;
|
private final Map<ServerName, List<RegionInfo>> secondaryRSToRegionMap;
|
||||||
private Map<ServerName, List<RegionInfo>> teritiaryRSToRegionMap;
|
private final Map<ServerName, List<RegionInfo>> teritiaryRSToRegionMap;
|
||||||
|
|
||||||
private MasterServices masterServices;
|
private final MasterServices masterServices;
|
||||||
private RackManager rackManager;
|
private final RackManager rackManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Datanode port to be used for Favored Nodes.
|
* Datanode port to be used for Favored Nodes.
|
||||||
|
@ -87,15 +83,19 @@ public class FavoredNodesManager {
|
||||||
this.rackManager = new RackManager(masterServices.getConfiguration());
|
this.rackManager = new RackManager(masterServices.getConfiguration());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(SnapshotOfRegionAssignmentFromMeta snapshotOfRegionAssignment)
|
public synchronized void initialize(SnapshotOfRegionAssignmentFromMeta snapshot) {
|
||||||
throws HBaseIOException {
|
// Add snapshot to structures made on creation. Current structures may have picked
|
||||||
globalFavoredNodesAssignmentPlan = snapshotOfRegionAssignment.getExistingAssignmentPlan();
|
// up data between construction and the scan of meta needed before this method
|
||||||
primaryRSToRegionMap = snapshotOfRegionAssignment.getPrimaryToRegionInfoMap();
|
// is called. See HBASE-23737 "[Flakey Tests] TestFavoredNodeTableImport fails 30% of the time"
|
||||||
secondaryRSToRegionMap = snapshotOfRegionAssignment.getSecondaryToRegionInfoMap();
|
this.globalFavoredNodesAssignmentPlan.
|
||||||
teritiaryRSToRegionMap = snapshotOfRegionAssignment.getTertiaryToRegionInfoMap();
|
updateFavoredNodesMap(snapshot.getExistingAssignmentPlan());
|
||||||
datanodeDataTransferPort = getDataNodePort();
|
primaryRSToRegionMap.putAll(snapshot.getPrimaryToRegionInfoMap());
|
||||||
|
secondaryRSToRegionMap.putAll(snapshot.getSecondaryToRegionInfoMap());
|
||||||
|
teritiaryRSToRegionMap.putAll(snapshot.getTertiaryToRegionInfoMap());
|
||||||
|
datanodeDataTransferPort= getDataNodePort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public int getDataNodePort() {
|
public int getDataNodePort() {
|
||||||
HdfsConfiguration.init();
|
HdfsConfiguration.init();
|
||||||
|
|
||||||
|
@ -122,18 +122,10 @@ public class FavoredNodesManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter and return regions for which favored nodes is not applicable.
|
* Filter and return regions for which favored nodes is not applicable.
|
||||||
*
|
|
||||||
* @param regions - collection of regions
|
|
||||||
* @return set of regions for which favored nodes is not applicable
|
* @return set of regions for which favored nodes is not applicable
|
||||||
*/
|
*/
|
||||||
public static Set<RegionInfo> filterNonFNApplicableRegions(Collection<RegionInfo> regions) {
|
public static Set<RegionInfo> filterNonFNApplicableRegions(Collection<RegionInfo> regions) {
|
||||||
Set<RegionInfo> fnRegions = Sets.newHashSet();
|
return regions.stream().filter(r -> !isFavoredNodeApplicable(r)).collect(Collectors.toSet());
|
||||||
for (RegionInfo regionInfo : regions) {
|
|
||||||
if (!isFavoredNodeApplicable(regionInfo)) {
|
|
||||||
fnRegions.add(regionInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fnRegions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -194,8 +186,7 @@ public class FavoredNodesManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lets do a bulk update to meta since that reduces the RPC's
|
// Lets do a bulk update to meta since that reduces the RPC's
|
||||||
FavoredNodeAssignmentHelper.updateMetaWithFavoredNodesInfo(
|
FavoredNodeAssignmentHelper.updateMetaWithFavoredNodesInfo(regionToFavoredNodes,
|
||||||
regionToFavoredNodes,
|
|
||||||
masterServices.getConnection());
|
masterServices.getConnection());
|
||||||
deleteFavoredNodesForRegions(regionToFavoredNodes.keySet());
|
deleteFavoredNodesForRegions(regionToFavoredNodes.keySet());
|
||||||
|
|
||||||
|
@ -208,8 +199,8 @@ public class FavoredNodesManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void addToReplicaLoad(RegionInfo hri, List<ServerName> servers) {
|
private synchronized void addToReplicaLoad(RegionInfo hri, List<ServerName> servers) {
|
||||||
ServerName serverToUse = ServerName.valueOf(servers.get(PRIMARY.ordinal()).getHostAndPort(),
|
ServerName serverToUse =
|
||||||
NON_STARTCODE);
|
ServerName.valueOf(servers.get(PRIMARY.ordinal()).getAddress().toString(), NON_STARTCODE);
|
||||||
List<RegionInfo> regionList = primaryRSToRegionMap.get(serverToUse);
|
List<RegionInfo> regionList = primaryRSToRegionMap.get(serverToUse);
|
||||||
if (regionList == null) {
|
if (regionList == null) {
|
||||||
regionList = new ArrayList<>();
|
regionList = new ArrayList<>();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/**
|
/*
|
||||||
*
|
*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
@ -18,10 +18,11 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hbase.favored;
|
package org.apache.hadoop.hbase.favored;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import org.apache.hadoop.hbase.ServerName;
|
import org.apache.hadoop.hbase.ServerName;
|
||||||
import org.apache.hadoop.hbase.client.RegionInfo;
|
import org.apache.hadoop.hbase.client.RegionInfo;
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
@ -35,9 +36,8 @@ import org.apache.yetus.audience.InterfaceAudience;
|
||||||
*/
|
*/
|
||||||
@InterfaceAudience.Private
|
@InterfaceAudience.Private
|
||||||
public class FavoredNodesPlan {
|
public class FavoredNodesPlan {
|
||||||
|
/** The map between each region name and its favored region server list */
|
||||||
/** the map between each region name and its favored region server list */
|
private final Map<String, List<ServerName>> favoredNodesMap;
|
||||||
private Map<String, List<ServerName>> favoredNodesMap;
|
|
||||||
|
|
||||||
public static enum Position {
|
public static enum Position {
|
||||||
PRIMARY,
|
PRIMARY,
|
||||||
|
@ -46,13 +46,18 @@ public class FavoredNodesPlan {
|
||||||
}
|
}
|
||||||
|
|
||||||
public FavoredNodesPlan() {
|
public FavoredNodesPlan() {
|
||||||
favoredNodesMap = new ConcurrentHashMap<>();
|
this.favoredNodesMap = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add to existing Map of FavoredNodes.
|
||||||
|
*/
|
||||||
|
void updateFavoredNodesMap(FavoredNodesPlan fnp) {
|
||||||
|
this.favoredNodesMap.putAll(fnp.favoredNodesMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an assignment to the plan
|
* Update an assignment to the plan
|
||||||
* @param region
|
|
||||||
* @param servers
|
|
||||||
*/
|
*/
|
||||||
public void updateFavoredNodesMap(RegionInfo region, List<ServerName> servers) {
|
public void updateFavoredNodesMap(RegionInfo region, List<ServerName> servers) {
|
||||||
if (region == null || servers == null || servers.isEmpty()) {
|
if (region == null || servers == null || servers.isEmpty()) {
|
||||||
|
@ -63,15 +68,13 @@ public class FavoredNodesPlan {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a favored node assignment
|
* Remove a favored node assignment
|
||||||
* @param region region
|
|
||||||
* @return the list of favored region server for this region based on the plan
|
* @return the list of favored region server for this region based on the plan
|
||||||
*/
|
*/
|
||||||
public List<ServerName> removeFavoredNodes(RegionInfo region) {
|
List<ServerName> removeFavoredNodes(RegionInfo region) {
|
||||||
return favoredNodesMap.remove(region.getRegionNameAsString());
|
return favoredNodesMap.remove(region.getRegionNameAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param region
|
|
||||||
* @return the list of favored region server for this region based on the plan
|
* @return the list of favored region server for this region based on the plan
|
||||||
*/
|
*/
|
||||||
public List<ServerName> getFavoredNodes(RegionInfo region) {
|
public List<ServerName> getFavoredNodes(RegionInfo region) {
|
||||||
|
@ -81,8 +84,6 @@ public class FavoredNodesPlan {
|
||||||
/**
|
/**
|
||||||
* Return the position of the server in the favoredNodes list. Assumes the
|
* Return the position of the server in the favoredNodes list. Assumes the
|
||||||
* favoredNodes list is of size 3.
|
* favoredNodes list is of size 3.
|
||||||
* @param favoredNodes
|
|
||||||
* @param server
|
|
||||||
* @return position
|
* @return position
|
||||||
*/
|
*/
|
||||||
public static Position getFavoredServerPosition(
|
public static Position getFavoredServerPosition(
|
||||||
|
@ -103,7 +104,13 @@ public class FavoredNodesPlan {
|
||||||
* @return the mapping between each region to its favored region server list
|
* @return the mapping between each region to its favored region server list
|
||||||
*/
|
*/
|
||||||
public Map<String, List<ServerName>> getAssignmentMap() {
|
public Map<String, List<ServerName>> getAssignmentMap() {
|
||||||
return favoredNodesMap;
|
// Make a deep copy so changes don't harm our copy of favoredNodesMap.
|
||||||
|
return this.favoredNodesMap.entrySet().stream().
|
||||||
|
collect(Collectors.toMap(k -> k.getKey(), v -> new ArrayList<ServerName>(v.getValue())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return this.favoredNodesMap.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -117,12 +124,13 @@ public class FavoredNodesPlan {
|
||||||
if (getClass() != o.getClass()) {
|
if (getClass() != o.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// To compare the map from objec o is identical to current assignment map.
|
// To compare the map from object o is identical to current assignment map.
|
||||||
Map<String, List<ServerName>> comparedMap = ((FavoredNodesPlan)o).getAssignmentMap();
|
Map<String, List<ServerName>> comparedMap = ((FavoredNodesPlan)o).favoredNodesMap;
|
||||||
|
|
||||||
// compare the size
|
// compare the size
|
||||||
if (comparedMap.size() != this.favoredNodesMap.size())
|
if (comparedMap.size() != this.favoredNodesMap.size()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// compare each element in the assignment map
|
// compare each element in the assignment map
|
||||||
for (Map.Entry<String, List<ServerName>> entry :
|
for (Map.Entry<String, List<ServerName>> entry :
|
||||||
|
|
|
@ -697,7 +697,7 @@ public class RegionPlacementMaintainer implements Closeable {
|
||||||
FutureUtils.get(rsAdmin.getServerInfo(RequestConverter.buildGetServerInfoRequest()))
|
FutureUtils.get(rsAdmin.getServerInfo(RequestConverter.buildGetServerInfoRequest()))
|
||||||
.getServerInfo() +
|
.getServerInfo() +
|
||||||
" has updated " + updateFavoredNodesResponse.getResponse() + " / " +
|
" has updated " + updateFavoredNodesResponse.getResponse() + " / " +
|
||||||
singleServerPlan.getAssignmentMap().size() + " regions with the assignment plan");
|
singleServerPlan.size() + " regions with the assignment plan");
|
||||||
succeededNum++;
|
succeededNum++;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
Loading…
Reference in New Issue