3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 package org
.apache
.hadoop
.hbase
.util
;
21 import java
.io
.IOException
;
22 import java
.util
.HashMap
;
25 import java
.util
.concurrent
.atomic
.AtomicInteger
;
26 import org
.apache
.commons
.logging
.Log
;
27 import org
.apache
.commons
.logging
.LogFactory
;
28 import org
.apache
.hadoop
.hbase
.classification
.InterfaceAudience
;
29 import org
.apache
.hadoop
.fs
.BlockLocation
;
30 import org
.apache
.hadoop
.fs
.FileStatus
;
31 import org
.apache
.hadoop
.fs
.FileSystem
;
32 import org
.apache
.hadoop
.fs
.Path
;
33 import org
.apache
.hadoop
.hbase
.util
.FSUtils
;
36 * Thread that walks over the filesystem, and computes the mappings
37 * Region -> BestHost and Region -> {@code Map<HostName, fractional-locality-of-region>}
40 @InterfaceAudience.Private
41 class FSRegionScanner
implements Runnable
{
42 static private final Log LOG
= LogFactory
.getLog(FSRegionScanner
.class);
44 private Path regionPath
;
47 * The file system used
49 private FileSystem fs
;
52 * Maps each region to the RS with highest locality for that region.
54 private Map
<String
,String
> regionToBestLocalityRSMapping
;
57 * Maps region encoded names to maps of hostnames to fractional locality of
58 * that region on that host.
60 private Map
<String
, Map
<String
, Float
>> regionDegreeLocalityMapping
;
62 FSRegionScanner(FileSystem fs
, Path regionPath
,
63 Map
<String
, String
> regionToBestLocalityRSMapping
,
64 Map
<String
, Map
<String
, Float
>> regionDegreeLocalityMapping
) {
66 this.regionPath
= regionPath
;
67 this.regionToBestLocalityRSMapping
= regionToBestLocalityRSMapping
;
68 this.regionDegreeLocalityMapping
= regionDegreeLocalityMapping
;
74 // empty the map for each region
75 Map
<String
, AtomicInteger
> blockCountMap
= new HashMap
<>();
78 String tableName
= regionPath
.getParent().getName();
79 int totalBlkCount
= 0;
82 FileStatus
[] cfList
= fs
.listStatus(regionPath
, new FSUtils
.FamilyDirFilter(fs
));
87 // for each cf, get all the blocks information
88 for (FileStatus cfStatus
: cfList
) {
89 if (!cfStatus
.isDirectory()) {
90 // skip because this is not a CF directory
94 FileStatus
[] storeFileLists
= fs
.listStatus(cfStatus
.getPath());
95 if (null == storeFileLists
) {
99 for (FileStatus storeFile
: storeFileLists
) {
100 BlockLocation
[] blkLocations
=
101 fs
.getFileBlockLocations(storeFile
, 0, storeFile
.getLen());
102 if (null == blkLocations
) {
106 totalBlkCount
+= blkLocations
.length
;
107 for(BlockLocation blk
: blkLocations
) {
108 for (String host
: blk
.getHosts()) {
109 AtomicInteger count
= blockCountMap
.get(host
);
111 count
= new AtomicInteger(0);
112 blockCountMap
.put(host
, count
);
114 count
.incrementAndGet();
120 if (regionToBestLocalityRSMapping
!= null) {
121 int largestBlkCount
= 0;
122 String hostToRun
= null;
123 for (Map
.Entry
<String
, AtomicInteger
> entry
: blockCountMap
.entrySet()) {
124 String host
= entry
.getKey();
126 int tmp
= entry
.getValue().get();
127 if (tmp
> largestBlkCount
) {
128 largestBlkCount
= tmp
;
133 // empty regions could make this null
134 if (null == hostToRun
) {
138 if (hostToRun
.endsWith(".")) {
139 hostToRun
= hostToRun
.substring(0, hostToRun
.length()-1);
141 String name
= tableName
+ ":" + regionPath
.getName();
142 synchronized (regionToBestLocalityRSMapping
) {
143 regionToBestLocalityRSMapping
.put(name
, hostToRun
);
147 if (regionDegreeLocalityMapping
!= null && totalBlkCount
> 0) {
148 Map
<String
, Float
> hostLocalityMap
= new HashMap
<>();
149 for (Map
.Entry
<String
, AtomicInteger
> entry
: blockCountMap
.entrySet()) {
150 String host
= entry
.getKey();
151 if (host
.endsWith(".")) {
152 host
= host
.substring(0, host
.length() - 1);
154 // Locality is fraction of blocks local to this host.
155 float locality
= ((float)entry
.getValue().get()) / totalBlkCount
;
156 hostLocalityMap
.put(host
, locality
);
158 // Put the locality map into the result map, keyed by the encoded name
160 regionDegreeLocalityMapping
.put(regionPath
.getName(), hostLocalityMap
);
162 } catch (IOException e
) {
163 LOG
.warn("Problem scanning file system", e
);
164 } catch (RuntimeException e
) {
165 LOG
.warn("Problem scanning file system", e
);