Java操作HDFS、HDFS相关命令、Hadoop安全模式
最近写的一个项目想集成Hadoop的HDFS文件系统,于是,我又去温习了一遍Hadoop。
环境
首先在windows环境下安装hadoop并配置环境变量。
windows下配置java jdk。
下载winutils:https://github.com/steveloughran/winutils
按照自己hadoop版本选择hadoop.dll
winutils.exe
放到hadoop bin目录下(Windows安装的Hadoop的bin目录)。
官方文档
http://hadoop.apache.org/docs/stable
举个栗子
package com.lzhpo.aurora.hadoop;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.fs.Path;
import org.junit.Before;
import org.junit.Test;
import java.io.*;
import java.net.URI;
/**
* @Author:lzhpo
* @Date:2019/6/20
* @Description:
*
* HDFS的Java访问接口
* 1)org.apache.hadoop.fs.FileSystem
* 是一个通用的文件系统API,提供了不同文件系统的统一访问方式。
* 2)org.apache.hadoop.fs.Path
* 是Hadoop文件系统中统一的文件或目录描述,类似于java.io.File对本地文件系统的文件或目录描述。
* 3)org.apache.hadoop.conf.Configuration
* 读取、解析配置文件(如core-site.xml/hdfs-default.xml/hdfs-site.xml等),或添加配置的工具类
* 4)org.apache.hadoop.fs.FSDataOutputStream
* 对Hadoop中数据输出流的统一封装
* 5)org.apache.hadoop.fs.FSDataInputStream
* 对Hadoop中数据输入流的统一封装
*
* FileSystem的API:https://hadoop.apache.org/docs/current/api/org/apache/hadoop/fs/FileSystem.html
*/
public class TestHDFS {
private static String hdfsUrl = "hdfs://192.168.200.111:9000";
private static Configuration conf;
private static FileSystem fs;
/**
* 初始化连接HDFS
* @throws Exception
*/
@Before
public void initConnection() throws Exception{
conf = new Configuration();
fs = FileSystem.get(URI.create(hdfsUrl), conf, "root"); //root为hadoop用户名称,我使用的是root用户
}
/**
* 列出指定目录下的文件(不包含取出目录下的所有文件)
* @throws Exception
*/
@Test
public void testListFIles() throws Exception {
Path dst = new Path("/");
FileStatus[] files = fs.listStatus(dst);
System.out.println("================================================");
for (FileStatus file : files) {
System.out.println(file.getPath().toString());
}
System.out.println("================================================");
}
/**
* 获取指定目录下的所有对象信息
*
* 格式:FileStatus{path=hdfs://192.168.200.111:9000/CodeTest; isDirectory=true; modification_time=1546875772083; access_time=0; owner=dr.who; group=supergroup; permission=rwxr-xr-x; isSymlink=false}
* @throws Exception
*/
@Test
public void testListAll() throws Exception{
FileStatus[] listStatus = fs.listStatus(new Path("/"));
System.out.println("================================================");
for (FileStatus fileStatus : listStatus){
System.out.println(fileStatus);
}
System.out.println("================================================");
}
/**
* 读取指定文件
* 注意:
* 它会判断你的这个是否是文件
* 如果是文件夹:org.apache.hadoop.ipc.RemoteException: Path is not a file: /
* @throws Exception
*/
@Test
public void testReadFile() throws Exception{
/**
* 乱码
*/
// FSDataInputStream open = fs.open(new Path("/Aurora/test1.txt"));
// IOUtils.copyBytes(open, System.out, conf ,true);
/**
* 不乱码
*/
// FSDataInputStream fileInputStream = fs.open(new Path("/Aurora/test1.txt"));
String filePath = "/test1/d.txt";
FSDataInputStream fileInputStream = fs.open(new Path(filePath));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "gbk"); //设置gbk格式,防止读取到中文乱码
char[] chars = new char[1024];
int len = inputStreamReader.read(chars);
System.out.println("================================================");
System.out.println(new String(chars,0,len)); //0,:开始读取位置,从0开始。 len:读取长度。
System.out.println("================================================");
fileInputStream.close();
inputStreamReader.close();
}
/**
* 创建一个文件夹
* @throws Exception
*/
@Test
public void testHDFSMkdir() throws Exception {
//一般url只认识http协议
//URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());//保证url也认识hdfs协议,这样就可以解析HDFS_PATH了
Path path = new Path("/test1");
fs.mkdirs(path);
}
/**
* 创建一个文件
* @throws Exception
*/
@Test
public void testCreateFile() throws Exception {
Path path = new Path("/test1/d.txt");
FSDataOutputStream out = fs.create(path);
out.write("会打篮球的程序猿!".getBytes("gbk"));
out.close();
}
/**
* 重命名
* @throws Exception
*/
@Test
public void testRenameFile() throws Exception {
Path path = new Path("/test1/b.txt");
Path newPath = new Path("/test1/bb.txt");
System.out.println(fs.rename(path, newPath)); //返回true为改名成功,false为失败。
}
/**
* 上传文件
* @throws Exception
*/
@Test
public void testUploadLocalFile() throws Exception {
Path src = new Path("E:/picture/lzhpo.png");
Path dst = new Path("/test1");
fs.copyFromLocalFile(src, dst);
}
/**
* 查找文件所在的数据块
* @throws Exception
*/
@Test
public void testGetBlockInfo() throws Exception { // list block info of file
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(hdfsUrl), conf);
Path dst = new Path("/test1/lzhpo.png");
FileStatus fileStatus = fs.getFileStatus(dst);
BlockLocation[] blkloc = fs.getFileBlockLocations(fileStatus, 0, fileStatus.getLen()); // 查找文件所在数据块
System.out.println("================================================");
for (BlockLocation loc : blkloc) {
for (int i = 0; i < loc.getHosts().length; i++)
System.out.println(loc.getHosts()[i]);
}
System.out.println("================================================");
}
/**
* 删除文件、文件夹
* @throws Exception
*/
@Test
public void testRemoveFile () throws Exception {
FileSystem fs = FileSystem.get(URI.create(hdfsUrl), new Configuration());
fs.delete(new Path("/test2"), true);//是否递归删除
}
}
HDFS相关操作命令
官方文档命令(2.9.2):http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSCommands.html
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/FileSystemShell.html
老版本(0.18):https://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html
FS Shell常用操作命令
调用文件系统(FS)Shell命令应使用 bin/hadoop fs
的形式。 所有的的FS shell命令使用URI路径作为参数。URI格式是scheme://authority/path。对HDFS文件系统,scheme是hdfs,对本地文件系统,scheme是file。其中scheme和authority参数都是可选的,如果未加指定,就会使用配置中指定的默认scheme。一个HDFS文件或目录比如/parent/child可以表示成hdfs://namenode:namenodeport/parent/child,或者更简单的/parent/child(假设你配置文件中的默认值是namenode:namenodeport)。大多数FS Shell命令的行为和对应的Unix Shell命令类似,不同之处会在下面介绍各命令使用详情时指出。出错信息会输出到stderr,其他信息输出到stdout。
cat
查看HDFS的文件。
用法:hadoop fs -cat [-ignoreCrc] URI [URI ...]
参数:-ignore选项禁用校验和验证。
举个栗子:hadoop fs -cat /test1/c.txt
checksum
返回文件的校验和信息。
用法:hadoop fs -checksum URI
举个栗子:
[root@bigdata ~]# hadoop fs -checksum /test1/c.txt
/test1/c.txt MD5-of-0MD5-of-512CRC32C 000002000000000000000000c76902108ba59943f44c5ae78847a17f
chmod
更改文件的权限。使用-R,通过目录结构递归更改。用户必须是文件的所有者,否则必须是超级用户。
用法:hadoop fs -chmod [-R] <MODE [,MODE] ... | OCTALMODE> URI [URI ...]
chown
更改文件的所有者。用户必须是超级用户。
用法:hadoop fs -chown [-R] [OWNER] [:[GROUP]] URI [URI]
cp
复制。
用法:hadoop fs -cp [-f] [-p | -p[topax]] URI [URI ...] <dest>
举个栗子:
[root@bigdata ~]# hadoop fs -cp /file/hdfs-site.xml /
get
将文件复制到本地文件系统。注意和cp
区分。
用法:hadoop fs -get [-ignorecrc] [-crc] [-p] [-f] <src> <localdst>
举个栗子:
hadoop fs -get hdfs://nn.example.com/user/hadoop/file localfile
ls
列出文件。
举个栗子:
hadoop fs -ls /
lsr
递归列出文件。
举个栗子:
hadoop fs -lsr /
mkdir
创建文件夹。
举个栗子:
hadoop fs -mkdir -p /test2
还有很多,例如mv、rm....这些都是和Linux差不多的,就不一一列举了。
mv
移动文件。
举个栗子:
hadoop fs -mv /test1/a.txt /test2
rm
删除文件。
举个栗子:
# 递归删除文件夹
hadoop fs -rm -r /test1
# 删除文件
hadoop fs -rm /test1.txt
df
显示可用空间。
举个栗子:
[root@bigdata ~]# hadoop fs -df /
Filesystem Size Used Available Use%
hdfs://192.168.200.111:9000 37558423552 21427215 27929939968 0%
选项:
- 如果目标已存在,则-f选项将覆盖目标。
- -p选项将保留文件属性[topx](时间戳,所有权,权限,ACL,XAttr)。如果指定了-p且没有arg,则保留时间戳,所有权和权限。如果指定了-pa,则还保留权限,因为ACL是一组超级权限。确定是否保留原始命名空间扩展属性与-p标志无关。
Hadoop管理员操作命令
命令
1、查看正在运行的 Job。
hadoop job -list
2、关闭正在运行的 Job。
hadoop job -kill job_1432108212572_0001
3、检查 HDFS 块状态,查看是否损坏。
hadoop fsck /
4、检查 HDFS 块状态,并删除损坏的块。
hadoop fsck / -delete
5、检查 HDFS 状态,包括 DataNode 信息。
hadoop dfsadmin -report
6、Hadoop 进入安全模式。
hadoop dfsadmin -safemode enter
7、Hadoop 离开安全模式。
hadoop dfsadmin -safemode leave
8、平衡集群中的文件
sbin/start-balancer.sh
踩个我前几年的坑?
问题描述
Cannot create directory /Aurora. Name node is in safe mode. The reported blocks 117 needs additional 3 blocks to reach the threshold 0.9990 of total blocks 121. The number of live datanodes 1 has reached the minimum number 0. Safe mode will be turned off automatically once the thresholds have been reached. NamenodeHostName:bigdata
原因分析
开启了安全模式状态下是不能创建文件夹的。
由于系统断电,内存不足等原因导致dataNode丢失超过设置的丢失百分比,系统自动进入安全模式。
解决办法
1.执行命令退出安全模式:hdfs dfsadmin -safemode leave
2.执行健康检查
hdfs fsck / -files
3.删除损坏掉的block。
hdfs fsck / -delete
Hadoop安全模式
安全模式是HDFS所处的一种特殊状态,在这种状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。在NameNode主节点启动时,HDFS首先进入安全模式,DataNode在启动的时候会向namenode汇报可用的block等状态,当整个系统达到安全标准时,HDFS自动离开安全模式。如果HDFS出于安全模式下,则文件block不能进行任何的副本复制操作,因此达到最小的副本数量要求是基于datanode启动时的状态来判定的,启动时不会再做任何复制(从而达到最小副本数量要求)。
- 本文标签: Java Hadoop
- 本文链接: http://www.lzhpo.com/article/40
- 版权声明: 本文由lzhpo原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权