/** * Validates lazy persisted blocks are evicted from RAM_DISK based on LRU. * * @throws IOException * @throws InterruptedException */ @Test public void testRamDiskEvictionIsLru() throws Exception { final int NUM_PATHS = 5; startUpCluster(true, NUM_PATHS + EVICTION_LOW_WATERMARK); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path paths[] = new Path[NUM_PATHS * 2]; for (int i = 0; i < paths.length; i++) { paths[i] = new Path("/" + METHOD_NAME + "." + i + ".dat"); } for (int i = 0; i < NUM_PATHS; i++) { makeTestFile(paths[i], BLOCK_SIZE, true); } // Sleep for a short time to allow the lazy writer thread to do its job. Thread.sleep(3 * LAZY_WRITER_INTERVAL_SEC * 1000); for (int i = 0; i < NUM_PATHS; ++i) { ensureFileReplicasOnStorageType(paths[i], RAM_DISK); } // Open the files for read in a random order. ArrayList<Integer> indexes = new ArrayList<Integer>(NUM_PATHS); for (int i = 0; i < NUM_PATHS; ++i) { indexes.add(i); } Collections.shuffle(indexes); for (int i = 0; i < NUM_PATHS; ++i) { LOG.info("Touching file " + paths[indexes.get(i)]); DFSTestUtil.readFile(fs, paths[indexes.get(i)]); } // Create an equal number of new files ensuring that the previous // files are evicted in the same order they were read. for (int i = 0; i < NUM_PATHS; ++i) { makeTestFile(paths[i + NUM_PATHS], BLOCK_SIZE, true); triggerBlockReport(); Thread.sleep(3000); ensureFileReplicasOnStorageType(paths[i + NUM_PATHS], RAM_DISK); ensureFileReplicasOnStorageType(paths[indexes.get(i)], DEFAULT); for (int j = i + 1; j < NUM_PATHS; ++j) { ensureFileReplicasOnStorageType(paths[indexes.get(j)], RAM_DISK); } } verifyRamDiskJMXMetric("RamDiskBlocksWrite", NUM_PATHS * 2); verifyRamDiskJMXMetric("RamDiskBlocksWriteFallback", 0); verifyRamDiskJMXMetric("RamDiskBytesWrite", BLOCK_SIZE * NUM_PATHS * 2); verifyRamDiskJMXMetric("RamDiskBlocksReadHits", NUM_PATHS); verifyRamDiskJMXMetric("RamDiskBlocksEvicted", NUM_PATHS); verifyRamDiskJMXMetric("RamDiskBlocksEvictedWithoutRead", 0); verifyRamDiskJMXMetric("RamDiskBlocksDeletedBeforeLazyPersisted", 0); }
/** * If the only available storage is RAM_DISK and the LAZY_PERSIST flag is not specified, then * block placement should fail. * * @throws IOException */ @Test public void testRamDiskNotChosenByDefault() throws IOException { startUpCluster(true, -1); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path = new Path("/" + METHOD_NAME + ".dat"); try { makeTestFile(path, BLOCK_SIZE, false); fail("Block placement to RAM_DISK should have failed without lazyPersist flag"); } catch (Throwable t) { LOG.info("Got expected exception ", t); } }
/** * Truncate to lazy persist file is denied. * * @throws IOException */ @Test public void testTruncateIsDenied() throws IOException { startUpCluster(true, -1); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path = new Path("/" + METHOD_NAME + ".dat"); makeTestFile(path, BLOCK_SIZE, true); try { client.truncate(path.toString(), BLOCK_SIZE / 2); fail("Truncate to LazyPersist file did not fail as expected"); } catch (Throwable t) { LOG.info("Got expected exception ", t); } }
public void run() { System.out.println("Writer " + id + " starting... "); int i = 0; try { for (i = 0; i < paths.length; i++) { makeRandomTestFile(paths[i], BLOCK_SIZE, true, seed); // eviction may faiL when all blocks are not persisted yet. // ensureFileReplicasOnStorageType(paths[i], RAM_DISK); } } catch (IOException e) { bFail.set(true); LOG.error( "Writer exception: writer id:" + id + " testfile: " + paths[i].toString() + " " + e); } finally { latch.countDown(); } }
/** * Append to lazy persist file is denied. * * @throws IOException */ @Test public void testAppendIsDenied() throws IOException { startUpCluster(true, -1); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path = new Path("/" + METHOD_NAME + ".dat"); makeTestFile(path, BLOCK_SIZE, true); try { client .append(path.toString(), BUFFER_LENGTH, EnumSet.of(CreateFlag.APPEND), null, null) .close(); fail("Append to LazyPersist file did not fail as expected"); } catch (Throwable t) { LOG.info("Got expected exception ", t); } }
@Test public void testDnRestartWithUnsavedReplicas() throws IOException, InterruptedException { startUpCluster(true, 1); FsDatasetTestUtil.stopLazyWriter(cluster.getDataNodes().get(0)); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path1 = new Path("/" + METHOD_NAME + ".01.dat"); makeTestFile(path1, BLOCK_SIZE, true); ensureFileReplicasOnStorageType(path1, RAM_DISK); LOG.info("Restarting the DataNode"); cluster.restartDataNode(0, true); cluster.waitActive(); // Ensure that the replica is still on transient storage. ensureFileReplicasOnStorageType(path1, RAM_DISK); }
@Test public void testLazyPersistBlocksAreSaved() throws IOException, InterruptedException { startUpCluster(true, -1); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path = new Path("/" + METHOD_NAME + ".dat"); // Create a test file makeTestFile(path, BLOCK_SIZE * 10, true); LocatedBlocks locatedBlocks = ensureFileReplicasOnStorageType(path, RAM_DISK); // Sleep for a short time to allow the lazy writer thread to do its job Thread.sleep(6 * LAZY_WRITER_INTERVAL_SEC * 1000); LOG.info("Verifying copy was saved to lazyPersist/"); // Make sure that there is a saved copy of the replica on persistent // storage. ensureLazyPersistBlocksAreSaved(locatedBlocks); }
@Test public void testDnRestartWithSavedReplicas() throws IOException, InterruptedException { startUpCluster(true, -1); final String METHOD_NAME = GenericTestUtils.getMethodName(); Path path1 = new Path("/" + METHOD_NAME + ".01.dat"); makeTestFile(path1, BLOCK_SIZE, true); ensureFileReplicasOnStorageType(path1, RAM_DISK); // Sleep for a short time to allow the lazy writer thread to do its job. // However the block replica should not be evicted from RAM_DISK yet. Thread.sleep(3 * LAZY_WRITER_INTERVAL_SEC * 1000); ensureFileReplicasOnStorageType(path1, RAM_DISK); LOG.info("Restarting the DataNode"); cluster.restartDataNode(0, true); cluster.waitActive(); triggerBlockReport(); // Ensure that the replica is now on persistent storage. ensureFileReplicasOnStorageType(path1, DEFAULT); }