hadoop 文件系统
一、系统启动脚本分析( hdfs+yarn : 五个守护进程 )
-
sbin/start-all.sh (过时了,推荐使用下面的两种方式)
调用 :
start-dfs.sh
start-yarn.sh -
sbin/start-dfs.sh (hdfs相关的进程)
-
启动名称节点
-
启动数据节点
-
启动辅助名称节点
使用:hadoop-daemons.sh 启动名称节点、数据节点、辅助名称节点
-
-
sbin/start-yarn.sh (yarn相关的进程)
-
启动资源管理器
-
节点管理器
使用:yarn-daemon.sh 启动资源管理器 、 节点管理器
-
-
单独启动
hadoop-daemon.sh start/stop namenode /datanode / secondarynamenode yarn-daemon.sh start/stop resourcemanager / nodemanager
-
集群的部署规划( 名称节点 )
master s201 s202 s203 HDFS NameNode SecondaryNameNode DataNode YARN ResourceManager NodeManager
推荐的部署规划:
NameNode配置在一个节点上
SecondaryNameNode配置在一个节点上,建议不要和NameNode在同一个节点上
每个子节点都配置 DataNode ,NodeManager和DataNode的数量一致(不一定在同一个节点上)
ResourceManager 建议不要和NameNode在同一个节点上core-site.xml
配置名称节点HDFS:
hdfs-site.xml
副本数量
hadoop-env.sh
配置JAVA_HOME
slaves
配置子节点yarn:
yarn-site.xml
resourceManager 此属性可以指定resourceManager的部署位置
nodeManager
-
查看详细的配置参数
hadoop/share/common/hadoop-common.xxx.jar --- core-default.xml hadoop/share/hdfs/hadoop-hdfs.xxx.jar--- hdfs.default.xml hadoop/share/mapreduce/hadoop-mapreduce-client-core-xxx.jar---mapreduce-default.xml hadoop/share/yarn/hadoop-yarn-common-xxx.jar---yarn-default.xml
-
时钟同步
-
安装ntp工具
yum -y install ntpxcall.sh yum -y install ntp (给所有的子节点安装)
-
修改配置(时间服务器上的配置文件)
vi /etc/ntp.conf1. 开放本地网络上的主机 将#去掉 (#restrict 192..x....zx.c...) 2. 取消公共的服务器设置 添加注释: server 0 server 1 server 2 ... ... 3. 设置内部的时钟 server 127.127.1.0 fudge 127.127.1.0 stratum 10
vi /etc/sysconfig/ntpd
设置硬件时间和系统时间一致
SYNC_HWCLOCL=yes -
重新启动ntpd
systemctl status ntpd.service
systemctl start ntpd.service
systemctl enable ntpd.service -
配置其他的节点
编写定时任务:
crontab -e
输入:
*/1 * * * * /usr/sbin/ntpdate master -
验证
修改任意一台机器的时间
date -s “2017-1-1 1:2:1”date 查看
-
二、HDFS的常见操作
hdfs dfs -mkdir -p /usr/zhangsan
hdfs dfs -lsr /
hdfs dfs -put linux源文件路径 hdfs文件系统的目标路径
hdfs dfs -get hdfs文件系统的目标和文件路径 linux系统目标路径
hdfs dfs -rm -r -f /usr/zhangsan (-rf 分开写)
hadoop namenode -format
-
-help 帮助命令
hdfs dfs -help 命令
hdfs dfs -help mkdir -
-mkdir 创建目录
hdfs dfs -mkdir -p /home/zhangsan -
-ls 查看目录信息
hdfs dfs -ls -R / -
-put 本地文本路径 hdfs目标路径 (上传文件)
hdfs dfs -put myfile.txt /home/zhangsan/myfile2.txt -
-cat 查看HDFS上的文件内容
hdfs dfs -cat /home/zhangsan/myfile2.txt -
-moveFromLocal 本地文本路径 hdfs目标路径 (上传文件,剪切)
hdfs dfs -moveFromLocal mydir /home/zhangsan -
-copyToLocal hdfs目标路径 本地文本路径 ( 下载: 将hdfs上的数据拷贝到本地系统上)
hdfs dfs -copyToLocal /home/zhangsan/mydir mydir2 -
-copyFromLocal 本地文本路径 hdfs目标路径 (上传文件,复制)
hdfs dfs -copyFromLocal myfile.txt /home/zhangsan/mydir/ -
-getmerge hdfs目标路径 本地文本路径 (下载并合并)
hdfs dfs -getmerge /home/zhangsan/myfile2.txt /home/zhangsan/mydir/* newfile.txt -
-rm 删除HDFS上的数据
hdfs dfs -rm -r -f /home/zhangsan/mydir -
-cp 、 -mv 、 rmdir 、 du 、 df …
-
-chmod 、 -chown 、 -chgrp
hdfs dfs -chmod 777 /home/zhangsan/myfile2.txt
hdfs dfs -chown lisi:lisi /home/zhangsan/myfile2.txt
hdfs dfs -chgrp zhaoliu /home/zhangsan/myfile2.txt -
-setrep 数量 文件
hdfs dfs -setrep 1 /home/zhangsan/myfile2.txt
三、分布式文件系统的介绍
<1>概念
分布式(名称节点、数据节点、辅助名称节点、节点管理器共同构成)文件系统
以树形结构存储大数据集
高效的处理和维护文件系统的数据
<2>特点
存储数据:数据量和数据规模(PB级别)较大
流式数据操作:一次顺序写入,多次读取,不能修改,只能追加数据
高容灾容错:处理软件和硬件故障,保存多个副本(副本数:3)数据的维护和恢复
低成本的主机:节省成本
存储的数据:不适合存储大量小文件,适合存储大文件
不适合存储时效性高的数据
<3>数据块
采用文件切割的方式对数据的进行存储,存储大数据(PB级别的数据)
数据块: 128m
寻道、寻址时间:10m
磁盘io速率:100m/s
读取数据的时间:是寻道和寻址时间段额100倍,消耗1s
数据存储的位置:linux的磁盘上
数据节点:/tmp/hadoop-用户名/dfs/data/current/BP-xxxx/current/finalized/subdir0/subdir1/数据(多个节点上)
名称节点:/tmp/hadoop-用户名/dfs/name/... ...
适合存储大数量的文件
不适合存储小文件(名称节点存储和处理的数据量大),先归档在存储
高可用:99.999% (三分之一的出错概率)
HDFS使用切割的方式的进行数据的存储
64MB
128MB :
寻址时间和寻道时间:10mm
读取数据,io读取: io的读取效率 , 100MB/s
建议:寻址时间和寻道时间 :读取数据 = 1 : 100
###<4>HDFS文件系统的结构
NameNode: 管理数据节点
SecondaryNameNode: 辅助名称节点(不适合做NameNode的即使备份)
DataNode:存储数据
Client: 客户端,操作HDFS文件系统
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wRD6TCpK-1599719879439)(1.png)]
四、HDFS分布式文件系统常见命令
<1>用法
hadoop fs -参数
hdfs dfs -参数
<2>常见命令
1. -help 帮助命令
hdfs dfs -help 命令
hdfs dfs -help mkdir
2. -mkdir 创建目录
hdfs dfs -mkdir -p /home/zhangsan
3. -ls 查看目录信息
hdfs dfs -ls -R /
4. -put 本地文本路径 hdfs目标路径 (上传文件)
hdfs dfs -put myfile.txt /home/zhangsan/myfile2.txt
5. -cat 查看HDFS上的文件内容
hdfs dfs -cat /home/zhangsan/myfile2.txt
6. -moveFromLocal 本地文本路径 hdfs目标路径 (上传文件,剪切)
hdfs dfs -moveFromLocal mydir /home/zhangsan
7. -copyToLocal hdfs目标路径 本地文本路径 ( 下载: 将hdfs上的数据拷贝到本地系统上)
hdfs dfs -copyToLocal /home/zhangsan/mydir mydir2
8. -copyFromLocal 本地文本路径 hdfs目标路径 (上传文件,复制)
hdfs dfs -copyFromLocal myfile.txt /home/zhangsan/mydir/
9. -getmerge hdfs目标路径 本地文本路径 (下载并合并)
hdfs dfs -getmerge /home/zhangsan/myfile2.txt /home/zhangsan/mydir/* newfile.txt
10. -rm 删除HDFS上的数据
hdfs dfs -rm -r -f /home/zhangsan/mydir
11. -cp 、 -mv 、 rmdir 、 du 、 df ...
12. -chmod 、 -chown 、 -chgrp
hdfs dfs -chmod 777 /home/zhangsan/myfile2.txt
hdfs dfs -chown lisi:lisi /home/zhangsan/myfile2.txt
hdfs dfs -chgrp zhaoliu /home/zhangsan/myfile2.txt
13. -setrep 数量 文件
hdfs dfs -setrep 1 /home/zhangsan/myfile2.txt
五、HDFS分布式文件数据操作(ide)
<1>IDE的选择
eclipse/intellj idea(推荐)... ...
运行环境:
windows
linux [ 图形界面 ] ( 不推荐 )
<2>使用jdk中的API实现HDFS数据操作
URL工具类:定位到文件系统
URLConnection工具类:和文件系统的连接对象
InputStream/OutputStream : 数据的传输
<3>使用Hadoop中的API实现HDFS数据操作
3.1 操作的步骤
1. 获取文件系统FileSystem对象
获取配置对象
Configuration conf = new Configuration();
conf.set(key,value);
指定配置参数Configuration对象
FileSystem fs = FileSystem.get(conf)
FileSystem fs = FileSystem.get(url,conf,user)
2. 操作(结构和数据:创建文件夹,更新文件名称,删除文件,列出目录中的所有信息,判断文件类型;上传和下载)
fs.mkdirs();
fs.rename();
fs.delete();
fs.listFiles();
fs.listStatus();
fs.copyToLocalFile();//下载
fs.copyFromLocalFile();//上传
3. 释放资源
fs.close()
3.2 结构操作:
例如:删除HDFS上的文件
注意:权限的问题
解决1://参数三:指定当前用户的访问身份 ( 推荐 )
FileSystem fs = FileSystem.get(url,conf,user)
解决2:在运行时,传递用户名信息给jvm
vm arguments: -DHADOOP_USER_NAME=zhangsan
解决3:给当前windows中的用户添加操作权限
hdfs dfs -chown chmod chgrp
3.3 数据操作
FSDataInputStream fsis = fs.open(new Path("/home/mydir2/hello2.txt"));
FSDataOutputStream fsos = fs.create(new Path("/home/zhangsanfile.txt"));
数据操作,自定义实现
3.4 使用IOUtils工具类实现数据的操作
IOUtils.copyBytes(fis,fsos, conf); # 上传
IOUtils.copyBytes(fsis, bos, conf); # 下载
3.5 配置文件的优先级
代码中使用config配置 > 自定义配置文件 > 配置文件,默认的配置方式
案例1 HadoopHDFSConfigDemo
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class HadoopHDFSConfigDemo {
public static void main(String[] args) throws Exception {
// 1. 获取文件系统对象
Configuration conf = new Configuration();
// 2. 配置
//conf.set("dfs.replication", "5");
FileSystem fs = FileSystem.get(new URI("hdfs://master:8020"), conf, "zhangsan");
// 3. 上传到文件
fs.copyFromLocalFile(new Path("e://nice.txt"), new Path("/home"));
// 4. 释放资源
fs.close();
System.out.println("over");
}
}
案例2. HDFS操作
public class HadoopHDFSDemo {
public static void main(String[] args) throws Exception {
// deleteHdfs2();
// updateFileName();
// mkdirHdfs();
// fileKindHdfs();
// fileStatusHdfs();
copyToLocal();
}
private static void copyToLocal() throws IOException, InterruptedException, Exception {
// 1. 获取文件系统对象
FileSystem fs = getFileSystem();
// 2. 更新文件名称
/*
* 参数三:下载到目标路径
* 参数一:是否删除删除源src
* 参数二:hdfs文件系统中的源文件路径
* 参数四: 是否开启文件校验(有些系统如果不开启,无法下载)
*/
fs.copyToLocalFile(false,new Path("/home/mydir2/hello2.txt"),
new Path("e:/"),true);
//文件的上传
// fs.copyFromLocalFile(delSrc, src, dst);
// 3. 释放资源
fs.close();
System.out.println(" copy over");
}
/**
* 获取文件的详细描述信息
*
*/
private static void fileStatusHdfs() throws Exception {
FileSystem fs = getFileSystem();
// 参数二:是否递归
RemoteIterator<LocatedFileStatus> remoteIter = fs.listFiles(new Path("/"), true);
while (remoteIter.hasNext()) {
// 封装当前文件的所有内容
LocatedFileStatus lfs = remoteIter.next();
// 查看文件的详细信息
System.out.println(lfs.getAccessTime());
System.out.println(lfs.getOwner());
System.out.println(lfs.getBlockSize());
System.out.println(lfs.getLen());
System.out.println(lfs.getGroup());
System.out.println(lfs.getPermission());
// 获取存储数据的块信息
BlockLocation[] bls = lfs.getBlockLocations();
for (BlockLocation blockLocation : bls) {
String[] names = blockLocation.getNames();
String[] hosts = blockLocation.getHosts();
// 数据的存储节点列表
for (String host : hosts) {
System.out.println(host);
}
}
System.out.println("------------------------");
}
// 3. 释放资源
fs.close();
System.out.println("获取文件的详细信息");
}
/**
* 判断的文件的类型
*
* 设置权限
*/
private static void fileKindHdfs() throws Exception {
FileSystem fs = getFileSystem();
FileStatus[] fstu = fs.listStatus(new Path("/home/mydir2/hello2.txt"));
for (FileStatus fileStatus : fstu) {
if (fileStatus.isFile()) {
System.out.println(fileStatus.getPath().getName() + " is a file");
} else {
System.out.println(fileStatus.getPath().getName() + "is a directory");
}
}
// 3. 释放资源
fs.close();
System.out.println("判断文件的类型结束");
}
/**
* 获取文件系统
*
* @return
* @throws IOException
* @throws Exception
* @throws InterruptedException
*/
private static FileSystem getFileSystem() throws IOException, InterruptedException, Exception {
Configuration conf = new Configuration();
// conf.set("fs.defaultFS", "hdfs://master:8020");
// 1. 获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://master:8020"), conf, "zhangsan");
// FileSystem fs = FileSystem.get(conf);
System.out.println(fs);
return fs;
}
/**
* 更新文件的名称
*
* @throws Exception
*/
private static void updateFileName() throws Exception {
// 1. 获取文件系统对象
FileSystem fs = getFileSystem();
// 2. 更新文件名称
fs.rename(new Path("/home/mydir2/hello.txt"), new Path("/home/mydir2/hello2.txt"));
// 3. 释放资源
fs.close();
System.out.println("udpate over");
}
/**
* 删除操作
*
* 设置权限
*/
private static void mkdirHdfs() throws Exception {
FileSystem fs = getFileSystem();
fs.mkdirs(new Path("/home/lisi"));
// 3. 释放资源
fs.close();
System.out.println("创建结束");
}
/**
* 删除操作
*
* 设置权限
*/
private static void deleteHdfs() throws Exception {
FileSystem fs = getFileSystem();
// 注意:权限,程序在windows上运行,
// 此时用户是以windows的用户名访问HDFS
// home/zhangsan
// 以sx用户删除操作,能进入到home中,home的权限生成o+rwx
// 以sx用户删除操作,进入到home中,具有删除权限
fs.delete(new Path("/home/zhangsan"), true);
// 3. 释放资源
fs.close();
System.out.println("删除结束");
}
/**
* 删除操作
*
* 指定访问用户的名称
*
* @throws Exception
* @throws InterruptedException
*/
private static void deleteHdfs2() throws IOException, InterruptedException, Exception {
// 0. 获取配置对象
FileSystem fs = getFileSystem();
// 2. 数据的操作
fs.delete(new Path("/home/mydir2"), true);
// 3. 释放资源
fs.close();
System.out.println("删除结束");
}
}
案例3. Hadoop上传与下载
public class HadoopIOHDFSDemo {
static Configuration conf = new Configuration();
public static void main(String[] args) throws Exception {
// loadFileByIO();
// loadFileByIOUtils();
uploadFileByIOUtils();
}
/**
* 使用IOUtils实现的文件上传
* @throws Exception
*/
private static void uploadFileByIOUtils() throws Exception{
//1. 获取文件系统
FileSystem fs = getFileSystem();
//2. 获取流对象
FileInputStream fis = new FileInputStream("e:/zhangsan.txt");
FSDataOutputStream fsos = fs.create(new Path("/home/zhangsanfile.txt"));
//3. 操作数据
IOUtils.copyBytes(fis,fsos, conf);
//4. 释放资源
fsos.close();
fis.close();
fs.close();
System.out.println("上传 over");
}
/**
* 使用IOUtils实现的文件下载
* @throws Exception
*/
private static void loadFileByIOUtils() throws Exception{
//1. 获取文件系统
FileSystem fs = getFileSystem();
//2. 获取流对象
FSDataInputStream fsis = fs.open(new Path("/home/mydir2/hello2.txt"));
BufferedOutputStream bos =new BufferedOutputStream(
new FileOutputStream("e:/hello4.txt"));
//3. 操作数据
IOUtils.copyBytes(fsis, bos, conf);
//4. 释放资源
fsis.close();
bos.close();
fs.close();
System.out.println("下载 over");
}
/**
* 使用hdfs中提供的流对象FSDataInputStream
* @throws Exception
*/
private static void loadFileByIO() throws Exception{
//1. 获取文件系统
FileSystem fs = getFileSystem();
//2. 获取流对象
FSDataInputStream fsis = fs.open(new Path("/home/mydir2/hello2.txt"));
//3. 操作数据
byte[]bs = new byte[512];
int len = -1;
StringBuilder sb = new StringBuilder();
BufferedOutputStream bos =new BufferedOutputStream(
new FileOutputStream("e:/hello3.txt"));
while((len=fsis.read(bs))!=-1){
//sb.append(new String(bs,0,len));
bos.write(bs, 0, len);
}
//4. 释放资源
fsis.close();
bos.close();
fs.close();
//System.out.println("读取的数据:"+sb.toString());
}
/**
* 获取文件系统
* @return
* @throws IOException
* @throws Exception
* @throws InterruptedException
*/
private static FileSystem getFileSystem() throws IOException, InterruptedException, Exception {
// conf.set("fs.defaultFS", "hdfs://master:8020");
// 1. 获取文件系统
FileSystem fs = FileSystem.get(new URI("hdfs://master:8020"), conf, "zhangsan");
// FileSystem fs = FileSystem.get(conf);
System.out.println(fs);
return fs;
}
}