Skip to content

Commit b7d67dc

Browse files
committed
HBASE-24111 Enable CompactionTool executions on non-HDFS filesystems (#1427)
Signed-off-by: Josh Elser <elserj@apache.org>
1 parent 9d28f2d commit b7d67dc

File tree

2 files changed

+42
-32
lines changed
  • hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/mapreduce
  • hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/regionserver

2 files changed

+42
-32
lines changed

hbase-hadoop2-compat/src/main/java/org/apache/hadoop/hbase/mapreduce/JobUtil.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,20 @@ public static Path getStagingDir(Configuration conf)
5353
throws IOException, InterruptedException {
5454
return JobSubmissionFiles.getStagingDir(new Cluster(conf), conf);
5555
}
56+
57+
/**
58+
* Initializes the staging directory and returns the qualified path.
59+
*
60+
* @param conf conf system configuration
61+
* @return qualified staging directory path
62+
* @throws IOException if the ownership on the staging directory is not as expected
63+
* @throws InterruptedException if the thread getting the staging directory is interrupted
64+
*/
65+
public static Path getQualifiedStagingDir(Configuration conf)
66+
throws IOException, InterruptedException {
67+
Cluster cluster = new Cluster(conf);
68+
Path stagingDir = JobSubmissionFiles.getStagingDir(cluster, conf);
69+
return cluster.getFileSystem().makeQualified(stagingDir);
70+
}
71+
5672
}

hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/regionserver/CompactionTool.java

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker;
4545
import org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController;
4646
import org.apache.hadoop.hbase.util.Bytes;
47+
import org.apache.hadoop.hbase.util.CommonFSUtils;
4748
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
4849
import org.apache.hadoop.hbase.util.FSTableDescriptors;
4950
import org.apache.hadoop.hbase.util.FSUtils;
@@ -57,6 +58,7 @@
5758
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
5859
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
5960
import org.apache.hadoop.mapreduce.lib.output.NullOutputFormat;
61+
import org.apache.hadoop.mapreduce.security.TokenCache;
6062
import org.apache.hadoop.util.LineReader;
6163
import org.apache.hadoop.util.Tool;
6264
import org.apache.hadoop.util.ToolRunner;
@@ -76,7 +78,6 @@
7678
public class CompactionTool extends Configured implements Tool {
7779
private static final Logger LOG = LoggerFactory.getLogger(CompactionTool.class);
7880

79-
private final static String CONF_TMP_DIR = "hbase.tmp.dir";
8081
private final static String CONF_COMPACT_ONCE = "hbase.compactiontool.compact.once";
8182
private final static String CONF_COMPACT_MAJOR = "hbase.compactiontool.compact.major";
8283
private final static String CONF_DELETE_COMPACTED = "hbase.compactiontool.delete";
@@ -89,12 +90,10 @@ private static class CompactionWorker {
8990
private final boolean deleteCompacted;
9091
private final Configuration conf;
9192
private final FileSystem fs;
92-
private final Path tmpDir;
9393

9494
public CompactionWorker(final FileSystem fs, final Configuration conf) {
9595
this.conf = conf;
9696
this.deleteCompacted = conf.getBoolean(CONF_DELETE_COMPACTED, false);
97-
this.tmpDir = new Path(conf.get(CONF_TMP_DIR));
9897
this.fs = fs;
9998
}
10099

@@ -105,7 +104,8 @@ public CompactionWorker(final FileSystem fs, final Configuration conf) {
105104
* @param compactOnce Execute just a single step of compaction.
106105
* @param major Request major compaction.
107106
*/
108-
public void compact(final Path path, final boolean compactOnce, final boolean major) throws IOException {
107+
public void compact(final Path path, final boolean compactOnce, final boolean major)
108+
throws IOException {
109109
if (isFamilyDir(fs, path)) {
110110
Path regionDir = path.getParent();
111111
Path tableDir = regionDir.getParent();
@@ -150,7 +150,7 @@ private void compactRegion(final Path tableDir, final TableDescriptor htd,
150150
private void compactStoreFiles(final Path tableDir, final TableDescriptor htd,
151151
final RegionInfo hri, final String familyName, final boolean compactOnce,
152152
final boolean major) throws IOException {
153-
HStore store = getStore(conf, fs, tableDir, htd, hri, familyName, tmpDir);
153+
HStore store = getStore(conf, fs, tableDir, htd, hri, familyName);
154154
LOG.info("Compact table=" + htd.getTableName() +
155155
" region=" + hri.getRegionNameAsString() +
156156
" family=" + familyName);
@@ -177,19 +177,10 @@ private void compactStoreFiles(final Path tableDir, final TableDescriptor htd,
177177
store.close();
178178
}
179179

180-
/**
181-
* Create a "mock" HStore that uses the tmpDir specified by the user and
182-
* the store dir to compact as source.
183-
*/
184180
private static HStore getStore(final Configuration conf, final FileSystem fs,
185181
final Path tableDir, final TableDescriptor htd, final RegionInfo hri,
186-
final String familyName, final Path tempDir) throws IOException {
187-
HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, hri) {
188-
@Override
189-
public Path getTempDir() {
190-
return tempDir;
191-
}
192-
};
182+
final String familyName) throws IOException {
183+
HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tableDir, hri);
193184
HRegion region = new HRegion(regionFs, null, conf, htd, null);
194185
return new HStore(region, htd.getColumnFamily(Bytes.toBytes(familyName)), conf, false);
195186
}
@@ -221,7 +212,7 @@ public void setup(Context context) {
221212
major = conf.getBoolean(CONF_COMPACT_MAJOR, false);
222213

223214
try {
224-
FileSystem fs = FileSystem.get(conf);
215+
FileSystem fs = CommonFSUtils.getRootDirFileSystem(conf);
225216
this.compactor = new CompactionWorker(fs, conf);
226217
} catch (IOException e) {
227218
throw new RuntimeException("Could not get the input FileSystem", e);
@@ -301,23 +292,19 @@ private static String[] getStoreDirHosts(final FileSystem fs, final Path path)
301292
* The file is a TextFile with each line corrisponding to a
302293
* store files directory to compact.
303294
*/
304-
public static void createInputFile(final FileSystem fs, final Path path,
305-
final Set<Path> toCompactDirs) throws IOException {
295+
public static List<Path> createInputFile(final FileSystem fs, final FileSystem stagingFs,
296+
final Path path, final Set<Path> toCompactDirs) throws IOException {
306297
// Extract the list of store dirs
307298
List<Path> storeDirs = new LinkedList<>();
308299
for (Path compactDir: toCompactDirs) {
309300
if (isFamilyDir(fs, compactDir)) {
310301
storeDirs.add(compactDir);
311302
} else if (isRegionDir(fs, compactDir)) {
312-
for (Path familyDir: FSUtils.getFamilyDirs(fs, compactDir)) {
313-
storeDirs.add(familyDir);
314-
}
303+
storeDirs.addAll(FSUtils.getFamilyDirs(fs, compactDir));
315304
} else if (isTableDir(fs, compactDir)) {
316305
// Lookup regions
317306
for (Path regionDir: FSUtils.getRegionDirs(fs, compactDir)) {
318-
for (Path familyDir: FSUtils.getFamilyDirs(fs, regionDir)) {
319-
storeDirs.add(familyDir);
320-
}
307+
storeDirs.addAll(FSUtils.getFamilyDirs(fs, regionDir));
321308
}
322309
} else {
323310
throw new IOException(
@@ -326,7 +313,7 @@ public static void createInputFile(final FileSystem fs, final Path path,
326313
}
327314

328315
// Write Input File
329-
FSDataOutputStream stream = fs.create(path);
316+
FSDataOutputStream stream = stagingFs.create(path);
330317
LOG.info("Create input file=" + path + " with " + storeDirs.size() + " dirs to compact.");
331318
try {
332319
final byte[] newLine = Bytes.toBytes("\n");
@@ -337,6 +324,7 @@ public static void createInputFile(final FileSystem fs, final Path path,
337324
} finally {
338325
stream.close();
339326
}
327+
return storeDirs;
340328
}
341329
}
342330

@@ -361,15 +349,20 @@ private int doMapReduce(final FileSystem fs, final Set<Path> toCompactDirs,
361349
// add dependencies (including HBase ones)
362350
TableMapReduceUtil.addDependencyJars(job);
363351

364-
Path stagingDir = JobUtil.getStagingDir(conf);
352+
Path stagingDir = JobUtil.getQualifiedStagingDir(conf);
353+
FileSystem stagingFs = stagingDir.getFileSystem(conf);
365354
try {
366355
// Create input file with the store dirs
367356
Path inputPath = new Path(stagingDir, "compact-"+ EnvironmentEdgeManager.currentTime());
368-
CompactionInputFormat.createInputFile(fs, inputPath, toCompactDirs);
357+
List<Path> storeDirs = CompactionInputFormat.createInputFile(fs, stagingFs,
358+
inputPath, toCompactDirs);
369359
CompactionInputFormat.addInputPath(job, inputPath);
370360

371361
// Initialize credential for secure cluster
372362
TableMapReduceUtil.initCredentials(job);
363+
// Despite the method name this will get delegation token for the filesystem
364+
TokenCache.obtainTokensForNamenodes(job.getCredentials(),
365+
storeDirs.toArray(new Path[0]), conf);
373366

374367
// Start the MR Job and wait
375368
return job.waitForCompletion(true) ? 0 : 1;
@@ -398,7 +391,7 @@ public int run(String[] args) throws Exception {
398391
boolean mapred = false;
399392

400393
Configuration conf = getConf();
401-
FileSystem fs = FileSystem.get(conf);
394+
FileSystem fs = CommonFSUtils.getRootDirFileSystem(conf);
402395

403396
try {
404397
for (int i = 0; i < args.length; ++i) {
@@ -458,14 +451,15 @@ private void printUsage(final String message) {
458451
System.err.println("Note: -D properties will be applied to the conf used. ");
459452
System.err.println("For example: ");
460453
System.err.println(" To stop delete of compacted file, pass -D"+CONF_DELETE_COMPACTED+"=false");
461-
System.err.println(" To set tmp dir, pass -D"+CONF_TMP_DIR+"=ALTERNATE_DIR");
462454
System.err.println();
463455
System.err.println("Examples:");
464456
System.err.println(" To compact the full 'TestTable' using MapReduce:");
465-
System.err.println(" $ hbase " + this.getClass().getName() + " -mapred hdfs://hbase/data/default/TestTable");
457+
System.err.println(" $ hbase " + this.getClass().getName() +
458+
" -mapred hdfs://hbase/data/default/TestTable");
466459
System.err.println();
467460
System.err.println(" To compact column family 'x' of the table 'TestTable' region 'abc':");
468-
System.err.println(" $ hbase " + this.getClass().getName() + " hdfs://hbase/data/default/TestTable/abc/x");
461+
System.err.println(" $ hbase " + this.getClass().getName() +
462+
" hdfs://hbase/data/default/TestTable/abc/x");
469463
}
470464

471465
public static void main(String[] args) throws Exception {

0 commit comments

Comments
 (0)