protected void setupMocksForNormalizer(Map<byte[], Integer> regionSizes, List<HRegionInfo> hris) { masterServices = Mockito.mock(MasterServices.class, RETURNS_DEEP_STUBS); // for simplicity all regions are assumed to be on one server; doesn't matter to us ServerName sn = ServerName.valueOf("localhost", -1, 1L); when(masterServices.getAssignmentManager().getRegionStates(). getRegionsOfTable(any(TableName.class))).thenReturn(hris); when(masterServices.getAssignmentManager().getRegionStates(). getRegionServerOfRegion(any(HRegionInfo.class))).thenReturn(sn); for (Map.Entry<byte[], Integer> region : regionSizes.entrySet()) { RegionLoad regionLoad = Mockito.mock(RegionLoad.class); when(regionLoad.getName()).thenReturn(region.getKey()); when(regionLoad.getStorefileSizeMB()).thenReturn(region.getValue()); when(masterServices.getServerManager().getLoad(sn). getRegionsLoad().get(region.getKey())).thenReturn(regionLoad); } normalizer.setMasterServices(masterServices); }
/** * return the subset of all regionservers * (actually returns set of ServerLoads) * which host some region in a given table. * used by assertAllRegionServers() below to * test reporting of loaded coprocessors. * @param tableName : given table. * @return subset of all servers. */ Map<ServerName, ServerLoad> serversForTable(String tableName) { Map<ServerName, ServerLoad> serverLoadHashMap = new HashMap<ServerName, ServerLoad>(); for(Map.Entry<ServerName,ServerLoad> server: TEST_UTIL.getMiniHBaseCluster().getMaster().getServerManager(). getOnlineServers().entrySet()) { for( Map.Entry<byte[], RegionLoad> region: server.getValue().getRegionsLoad().entrySet()) { if (region.getValue().getNameAsString().equals(tableName)) { // this server hosts a region of tableName: add this server.. serverLoadHashMap.put(server.getKey(),server.getValue()); // .. and skip the rest of the regions that it hosts. break; } } } return serverLoadHashMap; }
/** * Updates last flushed sequence Ids for the regions on server sn * @param sn * @param hsl */ private void updateLastFlushedSequenceIds(ServerName sn, ServerLoad hsl) { Map<byte[], RegionLoad> regionsLoad = hsl.getRegionsLoad(); for (Entry<byte[], RegionLoad> entry : regionsLoad.entrySet()) { byte[] encodedRegionName = Bytes.toBytes(HRegionInfo.encodeRegionName(entry.getKey())); Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName); long l = entry.getValue().getCompleteSequenceId(); if (existingValue != null) { if (l != -1 && l < existingValue) { LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + entry.getValue() + ") that is less than the previous last flushed sequence id (" + existingValue + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring."); continue; // Don't let smaller sequence ids override greater sequence ids. } } flushedSequenceIdByRegion.put(encodedRegionName, l); } }
/** * Updates last flushed sequence Ids for the regions on server sn * @param sn * @param hsl */ private void updateLastFlushedSequenceIds(ServerName sn, ServerLoad hsl) { Map<byte[], RegionLoad> regionsLoad = hsl.getRegionsLoad(); for (Entry<byte[], RegionLoad> entry : regionsLoad.entrySet()) { Long existingValue = flushedSequenceIdByRegion.get(entry.getKey()); long l = entry.getValue().getCompleteSequenceId(); if (existingValue != null) { if (l != -1 && l < existingValue) { if (LOG.isDebugEnabled()) { LOG.debug("RegionServer " + sn + " indicates a last flushed sequence id (" + entry.getValue() + ") that is less than the previous last flushed sequence id (" + existingValue + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring."); } continue; // Don't let smaller sequence ids override greater // sequence ids. } } flushedSequenceIdByRegion.put(entry.getKey(), l); } }
/** * return the subset of all regionservers * (actually returns set of ServerLoads) * which host some region in a given table. * used by assertAllRegionServers() below to * test reporting of loaded coprocessors. * @param tableName : given table. * @return subset of all servers. */ Map<ServerName, ServerLoad> serversForTable(String tableName) { Map<ServerName, ServerLoad> serverLoadHashMap = new HashMap<>(); for(Map.Entry<ServerName,ServerLoad> server: TEST_UTIL.getMiniHBaseCluster().getMaster().getServerManager(). getOnlineServers().entrySet()) { for( Map.Entry<byte[], RegionLoad> region: server.getValue().getRegionsLoad().entrySet()) { if (region.getValue().getNameAsString().equals(tableName)) { // this server hosts a region of tableName: add this server.. serverLoadHashMap.put(server.getKey(),server.getValue()); // .. and skip the rest of the regions that it hosts. break; } } } return serverLoadHashMap; }
public ServerLoad(HBaseProtos.ServerLoad serverLoad) { this.serverLoad = serverLoad; for (HBaseProtos.RegionLoad rl: serverLoad.getRegionLoadsList()) { stores += rl.getStores(); storefiles += rl.getStorefiles(); storeUncompressedSizeMB += rl.getStoreUncompressedSizeMB(); storefileSizeMB += rl.getStorefileSizeMB(); memstoreSizeMB += rl.getMemstoreSizeMB(); storefileIndexSizeMB += rl.getStorefileIndexSizeMB(); readRequestsCount += rl.getReadRequestsCount(); writeRequestsCount += rl.getWriteRequestsCount(); rootIndexSizeKB += rl.getRootIndexSizeKB(); totalStaticIndexSizeKB += rl.getTotalStaticIndexSizeKB(); totalStaticBloomSizeKB += rl.getTotalStaticBloomSizeKB(); totalCompactingKVs += rl.getTotalCompactingKVs(); currentCompactedKVs += rl.getCurrentCompactedKVs(); } }
/** * Store the current region loads. */ private synchronized void updateRegionLoad() { // We create a new hashmap so that regions that are no longer there are removed. // However we temporarily need the old loads so we can use them to keep the rolling average. Map<String, Deque<RegionLoad>> oldLoads = loads; loads = new HashMap<String, Deque<RegionLoad>>(); for (ServerName sn : clusterStatus.getServers()) { ServerLoad sl = clusterStatus.getLoad(sn); if (sl == null) { continue; } for (Entry<byte[], RegionLoad> entry : sl.getRegionsLoad().entrySet()) { Deque<RegionLoad> rLoads = oldLoads.get(Bytes.toString(entry.getKey())); if (rLoads == null) { // There was nothing there rLoads = new ArrayDeque<RegionLoad>(); } else if (rLoads.size() >= numRegionLoadsToRemember) { rLoads.remove(); } rLoads.add(entry.getValue()); loads.put(Bytes.toString(entry.getKey()), rLoads); } } for(CostFromRegionLoadFunction cost : regionLoadFunctions) { cost.setLoads(loads); } }
protected double getRegionLoadCost(Collection<RegionLoad> regionLoadList) { double cost = 0; for (RegionLoad rl : regionLoadList) { double toAdd = getCostFromRl(rl); if (cost == 0) { cost = toAdd; } else { cost = (.5 * cost) + (.5 * toAdd); } } return cost; }
protected Cluster( Map<ServerName, List<HRegionInfo>> clusterState, Map<String, Deque<RegionLoad>> loads, RegionLocationFinder regionFinder, RackManager rackManager) { this(null, clusterState, loads, regionFinder, rackManager); }
/** Helper for Cluster constructor to handle a region */ private void registerRegion(HRegionInfo region, int regionIndex, int serverIndex, Map<String, Deque<RegionLoad>> loads, RegionLocationFinder regionFinder) { String tableName = region.getTable().getNameAsString(); if (!tablesToIndex.containsKey(tableName)) { tables.add(tableName); tablesToIndex.put(tableName, tablesToIndex.size()); } int tableIndex = tablesToIndex.get(tableName); regionsToIndex.put(region, regionIndex); regions[regionIndex] = region; regionIndexToServerIndex[regionIndex] = serverIndex; initialRegionIndexToServerIndex[regionIndex] = serverIndex; regionIndexToTableIndex[regionIndex] = tableIndex; // region load if (loads != null) { Deque<RegionLoad> rl = loads.get(region.getRegionNameAsString()); // That could have failed if the RegionLoad is using the other regionName if (rl == null) { // Try getting the region load using encoded name. rl = loads.get(region.getEncodedName()); } regionLoads[regionIndex] = rl; } if (regionFinder != null) { //region location List<ServerName> loc = regionFinder.getTopBlockLocations(region); regionLocations[regionIndex] = new int[loc.size()]; for (int i=0; i < loc.size(); i++) { regionLocations[regionIndex][i] = loc.get(i) == null ? -1 : (serversToIndex.get(loc.get(i).getHostAndPort()) == null ? -1 : serversToIndex.get(loc.get(i).getHostAndPort())); } } }
private long getRegionSize(HRegionInfo hri) { ServerName sn = masterServices.getAssignmentManager().getRegionStates(). getRegionServerOfRegion(hri); RegionLoad regionLoad = masterServices.getServerManager().getLoad(sn). getRegionsLoad().get(hri.getRegionName()); return regionLoad.getStorefileSizeMB(); }
/** * Updates last flushed sequence Ids for the regions on server sn * @param sn * @param hsl */ private void updateLastFlushedSequenceIds(ServerName sn, ServerLoad hsl) { Map<byte[], RegionLoad> regionsLoad = hsl.getRegionsLoad(); for (Entry<byte[], RegionLoad> entry : regionsLoad.entrySet()) { byte[] encodedRegionName = Bytes.toBytes(HRegionInfo.encodeRegionName(entry.getKey())); Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName); long l = entry.getValue().getCompleteSequenceId(); // Don't let smaller sequence ids override greater sequence ids. if (LOG.isTraceEnabled()) { LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue + ", completeSequenceId=" + l); } if (existingValue == null || (l != HConstants.NO_SEQNUM && l > existingValue)) { flushedSequenceIdByRegion.put(encodedRegionName, l); } else if (l != HConstants.NO_SEQNUM && l < existingValue) { LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l + ") that is less than the previous last flushed sequence id (" + existingValue + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring."); } ConcurrentNavigableMap<byte[], Long> storeFlushedSequenceId = getOrCreateStoreFlushedSequenceId(encodedRegionName); for (StoreSequenceId storeSeqId : entry.getValue().getStoreCompleteSequenceId()) { byte[] family = storeSeqId.getFamilyName().toByteArray(); existingValue = storeFlushedSequenceId.get(family); l = storeSeqId.getSequenceId(); if (LOG.isTraceEnabled()) { LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family) + ", existingValue=" + existingValue + ", completeSequenceId=" + l); } // Don't let smaller sequence ids override greater sequence ids. if (existingValue == null || (l != HConstants.NO_SEQNUM && l > existingValue.longValue())) { storeFlushedSequenceId.put(family, l); } } } }
private RegionLoad getRegionLoad(ServerName sn, HRegionInfo hri) { ServerManager serverManager = masterServices.getServerManager(); ServerLoad load = serverManager.getLoad(sn); if (load != null) { Map<byte[], RegionLoad> regionsLoad = load.getRegionsLoad(); if (regionsLoad != null) { return regionsLoad.get(hri.getRegionName()); } } return null; }
private void init(RegionLocator regionLocator, Admin admin) throws IOException { if (!enabled(admin.getConfiguration())) { LOG.info("Region size calculation disabled."); return; } LOG.info("Calculating region sizes for table \"" + regionLocator.getName() + "\"."); //get regions for table List<HRegionLocation> tableRegionInfos = regionLocator.getAllRegionLocations(); Set<byte[]> tableRegions = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR); for (HRegionLocation regionInfo : tableRegionInfos) { tableRegions.add(regionInfo.getRegionInfo().getRegionName()); } ClusterStatus clusterStatus = admin.getClusterStatus(); Collection<ServerName> servers = clusterStatus.getServers(); final long megaByte = 1024L * 1024L; //iterate all cluster regions, filter regions from our table and compute their size for (ServerName serverName: servers) { ServerLoad serverLoad = clusterStatus.getLoad(serverName); for (RegionLoad regionLoad: serverLoad.getRegionsLoad().values()) { byte[] regionId = regionLoad.getName(); if (tableRegions.contains(regionId)) { long regionSizeBytes = regionLoad.getStorefileSizeMB() * megaByte; sizeMap.put(regionId, regionSizeBytes); if (LOG.isDebugEnabled()) { LOG.debug("Region " + regionLoad.getNameAsString() + " has size " + regionSizeBytes); } } } } LOG.debug("Region sizes calculated"); }
/** * Creates mock of region with given name and size. * * @param fileSizeMb number of megabytes occupied by region in file store in megabytes * */ private RegionLoad mockRegion(String regionName, int fileSizeMb) { RegionLoad region = Mockito.mock(RegionLoad.class); when(region.getName()).thenReturn(regionName.getBytes()); when(region.getNameAsString()).thenReturn(regionName); when(region.getStorefileSizeMB()).thenReturn(fileSizeMb); return region; }
/** Creates mock of region server with given regions*/ private ServerLoad mockServer(RegionLoad... regions) { ServerLoad serverLoad = Mockito.mock(ServerLoad.class); Map<byte[], RegionLoad> regionMap = new TreeMap<byte[], RegionLoad>(Bytes.BYTES_COMPARATOR); for (RegionLoad regionName : regions) { regionMap.put(regionName.getName(), regionName); } when(serverLoad.getRegionsLoad()).thenReturn(regionMap); return serverLoad; }
/** * Store the current region loads. */ private synchronized void updateRegionLoad() { // We create a new hashmap so that regions that are no longer there are removed. // However we temporarily need the old loads so we can use them to keep the rolling average. Map<String, Deque<RegionLoad>> oldLoads = loads; loads = new HashMap<String, Deque<RegionLoad>>(); for (ServerName sn : clusterStatus.getServers()) { ServerLoad sl = clusterStatus.getLoad(sn); if (sl == null) { continue; } for (Entry<byte[], RegionLoad> entry : sl.getRegionsLoad().entrySet()) { Deque<RegionLoad> rLoads = oldLoads.get(Bytes.toString(entry.getKey())); if (rLoads == null) { // There was nothing there rLoads = new ArrayDeque<RegionLoad>(); } else if (rLoads.size() >= 15) { rLoads.remove(); } rLoads.add(entry.getValue()); loads.put(Bytes.toString(entry.getKey()), rLoads); } } for(CostFromRegionLoadFunction cost : regionLoadFunctions) { cost.setLoads(loads); } }
private void init(RegionLocator regionLocator, Admin admin) throws IOException { if (!enabled(admin.getConfiguration())) { LOG.info("Region size calculation disabled."); return; } LOG.info("Calculating region sizes for table \"" + regionLocator.getName() + "\"."); //get regions for table List<HRegionLocation> tableRegionInfos = regionLocator.getAllRegionLocations(); Set<byte[]> tableRegions = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR); for (HRegionLocation regionInfo : tableRegionInfos) { tableRegions.add(regionInfo.getRegionInfo().getRegionName()); } ClusterStatus clusterStatus = admin.getClusterStatus(); Collection<ServerName> servers = clusterStatus.getServers(); final long megaByte = 1024L * 1024L; //iterate all cluster regions, filter regions from our table and compute their size for (ServerName serverName: servers) { ServerLoad serverLoad = clusterStatus.getLoad(serverName); for (RegionLoad regionLoad: serverLoad.getRegionsLoad().values()) { byte[] regionId = regionLoad.getName(); if (tableRegions.contains(regionId)) { long regionSizeBytes = (regionLoad.getStorefileSizeMB() + regionLoad.getMemStoreSizeMB()) * megaByte; sizeMap.put(regionId, regionSizeBytes); if (LOG.isDebugEnabled()) { LOG.debug("Region " + regionLoad.getNameAsString() + " has size " + regionSizeBytes); } } } } LOG.debug("Region sizes calculated"); }
private long getRegionSize(RegionInfo hri) { ServerName sn = masterServices.getAssignmentManager().getRegionStates(). getRegionServerOfRegion(hri); RegionLoad regionLoad = masterServices.getServerManager().getLoad(sn). getRegionsLoad().get(hri.getRegionName()); if (regionLoad == null) { LOG.debug(hri.getRegionNameAsString() + " was not found in RegionsLoad"); return -1; } return regionLoad.getStorefileSizeMB(); }
/** * Updates last flushed sequence Ids for the regions on server sn * @param sn * @param hsl */ private void updateLastFlushedSequenceIds(ServerName sn, ServerLoad hsl) { Map<byte[], RegionLoad> regionsLoad = hsl.getRegionsLoad(); for (Entry<byte[], RegionLoad> entry : regionsLoad.entrySet()) { byte[] encodedRegionName = Bytes.toBytes(RegionInfo.encodeRegionName(entry.getKey())); Long existingValue = flushedSequenceIdByRegion.get(encodedRegionName); long l = entry.getValue().getCompleteSequenceId(); // Don't let smaller sequence ids override greater sequence ids. if (LOG.isTraceEnabled()) { LOG.trace(Bytes.toString(encodedRegionName) + ", existingValue=" + existingValue + ", completeSequenceId=" + l); } if (existingValue == null || (l != HConstants.NO_SEQNUM && l > existingValue)) { flushedSequenceIdByRegion.put(encodedRegionName, l); } else if (l != HConstants.NO_SEQNUM && l < existingValue) { LOG.warn("RegionServer " + sn + " indicates a last flushed sequence id (" + l + ") that is less than the previous last flushed sequence id (" + existingValue + ") for region " + Bytes.toString(entry.getKey()) + " Ignoring."); } ConcurrentNavigableMap<byte[], Long> storeFlushedSequenceId = computeIfAbsent(storeFlushedSequenceIdsByRegion, encodedRegionName, () -> new ConcurrentSkipListMap<>(Bytes.BYTES_COMPARATOR)); for (StoreSequenceId storeSeqId : entry.getValue().getStoreCompleteSequenceId()) { byte[] family = storeSeqId.getFamilyName().toByteArray(); existingValue = storeFlushedSequenceId.get(family); l = storeSeqId.getSequenceId(); if (LOG.isTraceEnabled()) { LOG.trace(Bytes.toString(encodedRegionName) + ", family=" + Bytes.toString(family) + ", existingValue=" + existingValue + ", completeSequenceId=" + l); } // Don't let smaller sequence ids override greater sequence ids. if (existingValue == null || (l != HConstants.NO_SEQNUM && l > existingValue.longValue())) { storeFlushedSequenceId.put(family, l); } } } }