svn merge -c 1350825 from trunk for HDFS-3518. Add a utility method HdfsUtils.isHealthy(uri) for checking if he given HDFS is healthy.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1350826 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
94a5971872
commit
2106c8bec8
|
@ -11,6 +11,9 @@ Release 2.0.1-alpha - UNRELEASED
|
|||
HDFS-3042. Automatic failover support for NameNode HA (todd)
|
||||
(see dedicated section below for breakdown of subtasks)
|
||||
|
||||
HDFS-3518. Add a utility method HdfsUtils.isHealthy(uri) for checking if
|
||||
the given HDFS is healthy. (szetszwo)
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
HDFS-3390. DFSAdmin should print full stack traces of errors when DEBUG
|
||||
|
|
|
@ -96,7 +96,7 @@ public class DistributedFileSystem extends FileSystem {
|
|||
*/
|
||||
@Override
|
||||
public String getScheme() {
|
||||
return "hdfs";
|
||||
return HdfsConstants.HDFS_URI_SCHEME;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hdfs.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.hadoop.classification.InterfaceAudience;
|
||||
import org.apache.hadoop.classification.InterfaceStability;
|
||||
import org.apache.hadoop.conf.Configuration;
|
||||
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
|
||||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
||||
import org.apache.hadoop.hdfs.DistributedFileSystem;
|
||||
import org.apache.hadoop.hdfs.protocol.HdfsConstants;
|
||||
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
|
||||
import org.apache.hadoop.io.IOUtils;
|
||||
|
||||
/**
|
||||
* The public utility API for HDFS.
|
||||
*/
|
||||
@InterfaceAudience.Public
|
||||
@InterfaceStability.Evolving
|
||||
public class HdfsUtils {
|
||||
private static final Log LOG = LogFactory.getLog(HdfsUtils.class);
|
||||
|
||||
/**
|
||||
* Is the HDFS healthy?
|
||||
* HDFS is considered as healthy if it is up and not in safemode.
|
||||
*
|
||||
* @param uri the HDFS URI. Note that the URI path is ignored.
|
||||
* @return true if HDFS is healthy; false, otherwise.
|
||||
*/
|
||||
public static boolean isHealthy(URI uri) {
|
||||
//check scheme
|
||||
final String scheme = uri.getScheme();
|
||||
if (!HdfsConstants.HDFS_URI_SCHEME.equalsIgnoreCase(scheme)) {
|
||||
throw new IllegalArgumentException("The scheme is not "
|
||||
+ HdfsConstants.HDFS_URI_SCHEME + ", uri=" + uri);
|
||||
}
|
||||
|
||||
final Configuration conf = new Configuration();
|
||||
//disable FileSystem cache
|
||||
conf.setBoolean(String.format("fs.%s.impl.disable.cache", scheme), true);
|
||||
//disable client retry for rpc connection and rpc calls
|
||||
conf.setBoolean(DFSConfigKeys.DFS_CLIENT_RETRY_POLICY_ENABLED_KEY, false);
|
||||
conf.setInt(
|
||||
CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 0);
|
||||
|
||||
DistributedFileSystem fs = null;
|
||||
try {
|
||||
fs = (DistributedFileSystem)FileSystem.get(uri, conf);
|
||||
final boolean safemode = fs.setSafeMode(SafeModeAction.SAFEMODE_GET);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Is namenode in safemode? " + safemode + "; uri=" + uri);
|
||||
}
|
||||
|
||||
fs.close();
|
||||
fs = null;
|
||||
return !safemode;
|
||||
} catch(IOException e) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Got an exception for uri=" + uri, e);
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
IOUtils.cleanup(LOG, fs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URI;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -50,6 +51,7 @@ import org.apache.hadoop.fs.FileStatus;
|
|||
import org.apache.hadoop.fs.FileSystem;
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.fs.permission.FsPermission;
|
||||
import org.apache.hadoop.hdfs.client.HdfsUtils;
|
||||
import org.apache.hadoop.hdfs.protocol.Block;
|
||||
import org.apache.hadoop.hdfs.protocol.ClientDatanodeProtocol;
|
||||
import org.apache.hadoop.hdfs.protocol.DatanodeID;
|
||||
|
@ -769,9 +771,11 @@ public class TestDFSClientRetries extends TestCase {
|
|||
.build();
|
||||
try {
|
||||
cluster.waitActive();
|
||||
final DistributedFileSystem dfs = cluster.getFileSystem();
|
||||
final URI uri = dfs.getUri();
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
|
||||
//create a file
|
||||
final DistributedFileSystem dfs = cluster.getFileSystem();
|
||||
final long length = 1L << 20;
|
||||
final Path file1 = new Path(dir, "foo");
|
||||
DFSTestUtil.createFile(dfs, file1, length, numDatanodes, 20120406L);
|
||||
|
@ -781,7 +785,9 @@ public class TestDFSClientRetries extends TestCase {
|
|||
assertEquals(length, s1.getLen());
|
||||
|
||||
//shutdown namenode
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
cluster.shutdownNameNode(0);
|
||||
assertFalse(HdfsUtils.isHealthy(uri));
|
||||
|
||||
//namenode is down, create another file in a thread
|
||||
final Path file3 = new Path(dir, "file");
|
||||
|
@ -806,8 +812,10 @@ public class TestDFSClientRetries extends TestCase {
|
|||
try {
|
||||
//sleep, restart, and then wait active
|
||||
TimeUnit.SECONDS.sleep(30);
|
||||
assertFalse(HdfsUtils.isHealthy(uri));
|
||||
cluster.restartNameNode(0, false);
|
||||
cluster.waitActive();
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
} catch (Exception e) {
|
||||
exceptions.add(e);
|
||||
}
|
||||
|
@ -823,7 +831,9 @@ public class TestDFSClientRetries extends TestCase {
|
|||
assertEquals(dfs.getFileChecksum(file1), dfs.getFileChecksum(file3));
|
||||
|
||||
//enter safe mode
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
dfs.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
|
||||
assertFalse(HdfsUtils.isHealthy(uri));
|
||||
|
||||
//leave safe mode in a new thread
|
||||
new Thread(new Runnable() {
|
||||
|
@ -832,7 +842,9 @@ public class TestDFSClientRetries extends TestCase {
|
|||
try {
|
||||
//sleep and then leave safe mode
|
||||
TimeUnit.SECONDS.sleep(30);
|
||||
assertFalse(HdfsUtils.isHealthy(uri));
|
||||
dfs.setSafeMode(SafeModeAction.SAFEMODE_LEAVE);
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
} catch (Exception e) {
|
||||
exceptions.add(e);
|
||||
}
|
||||
|
@ -844,6 +856,8 @@ public class TestDFSClientRetries extends TestCase {
|
|||
DFSTestUtil.createFile(dfs, file2, length, numDatanodes, 20120406L);
|
||||
assertEquals(dfs.getFileChecksum(file1), dfs.getFileChecksum(file2));
|
||||
|
||||
assertTrue(HdfsUtils.isHealthy(uri));
|
||||
|
||||
//make sure it won't retry on exceptions like FileNotFoundException
|
||||
final Path nonExisting = new Path(dir, "nonExisting");
|
||||
LOG.info("setPermission: " + nonExisting);
|
||||
|
|
Loading…
Reference in New Issue