HADOOP-15548: Randomize local dirs. Contributed by Jim Brennan.
This commit is contained in:
parent
100470140d
commit
d36f6b9e93
|
@ -418,7 +418,12 @@ public class LocalDirAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int dirNum = ctx.getAndIncrDirNumLastAccessed();
|
// Start linear search with random increment if possible
|
||||||
|
int randomInc = 1;
|
||||||
|
if (numDirs > 2) {
|
||||||
|
randomInc += dirIndexRandomizer.nextInt(numDirs - 1);
|
||||||
|
}
|
||||||
|
int dirNum = ctx.getAndIncrDirNumLastAccessed(randomInc);
|
||||||
while (numDirsSearched < numDirs) {
|
while (numDirsSearched < numDirs) {
|
||||||
long capacity = ctx.dirDF[dirNum].getAvailable();
|
long capacity = ctx.dirDF[dirNum].getAvailable();
|
||||||
if (capacity > size) {
|
if (capacity > size) {
|
||||||
|
|
|
@ -265,6 +265,65 @@ public class TestLocalDirAllocator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Five buffer dirs, on read-write disk.
|
||||||
|
*
|
||||||
|
* Try to create a whole bunch of files.
|
||||||
|
* Verify that each successive creation uses a different disk
|
||||||
|
* than the previous one (for sized requests).
|
||||||
|
*
|
||||||
|
* Would ideally check statistical properties of distribution, but
|
||||||
|
* we don't have the nerve to risk false-positives here.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test (timeout = 30000)
|
||||||
|
public void testCreateManyFilesRandom() throws Exception {
|
||||||
|
assumeNotWindows();
|
||||||
|
final int numDirs = 5;
|
||||||
|
final int numTries = 100;
|
||||||
|
String[] dirs = new String[numDirs];
|
||||||
|
for (int d = 0; d < numDirs; ++d) {
|
||||||
|
dirs[d] = buildBufferDir(ROOT, d);
|
||||||
|
}
|
||||||
|
boolean next_dir_not_selected_at_least_once = false;
|
||||||
|
try {
|
||||||
|
conf.set(CONTEXT, dirs[0] + "," + dirs[1] + "," + dirs[2] + ","
|
||||||
|
+ dirs[3] + "," + dirs[4]);
|
||||||
|
Path[] paths = new Path[5];
|
||||||
|
for (int d = 0; d < numDirs; ++d) {
|
||||||
|
paths[d] = new Path(dirs[d]);
|
||||||
|
assertTrue(localFs.mkdirs(paths[d]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int inDir=0;
|
||||||
|
int prevDir = -1;
|
||||||
|
int[] counts = new int[5];
|
||||||
|
for(int i = 0; i < numTries; ++i) {
|
||||||
|
File result = createTempFile(SMALL_FILE_SIZE);
|
||||||
|
for (int d = 0; d < numDirs; ++d) {
|
||||||
|
if (result.getPath().startsWith(paths[d].toUri().getPath())) {
|
||||||
|
inDir = d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Verify we always select a different dir
|
||||||
|
assertNotEquals(prevDir, inDir);
|
||||||
|
// Verify we are not always selecting the next dir - that was the old
|
||||||
|
// algorithm.
|
||||||
|
if ((prevDir != -1) && (inDir != ((prevDir + 1) % numDirs))) {
|
||||||
|
next_dir_not_selected_at_least_once = true;
|
||||||
|
}
|
||||||
|
prevDir = inDir;
|
||||||
|
counts[inDir]++;
|
||||||
|
result.delete();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
rmBufferDirs();
|
||||||
|
}
|
||||||
|
assertTrue(next_dir_not_selected_at_least_once);
|
||||||
|
}
|
||||||
|
|
||||||
/** Two buffer dirs. The first dir does not exist & is on a read-only disk;
|
/** Two buffer dirs. The first dir does not exist & is on a read-only disk;
|
||||||
* The second dir exists & is RW
|
* The second dir exists & is RW
|
||||||
* getLocalPathForWrite with checkAccess set to false should create a parent
|
* getLocalPathForWrite with checkAccess set to false should create a parent
|
||||||
|
|
Loading…
Reference in New Issue