本文是慕课网大数据学习的笔记加总结:
目录:
一、HDFS环境搭建—伪分布式搭建
二、HDFS的shell命令
三、java操作HDFS开发环境搭建
四、java API操作HDFS文件系统
一、HDFS环境搭建—伪分布式搭建
1.安装java,
1.配置到系统环境变量中
vim /etc/profile
export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79 export PATH=$JAVA_HOME/bin:$PATH
2.使环境变量生效:
source /etc/profile
3.验证java是否配置成功:
java —version
4.查找JAVA_HOME中配置的java路径
echo $JAVA_HOME
2.安装ssh
1.安装ssh:
sudo yum install ssh
2.生成公钥和私钥
ssh-keygen -t rsa
3.查看生成时候的记录找到 key存放的目录
4.将生成的公钥拷贝到 authorized_keys里
先进入到公钥所在目录
ssh-copy-id hadoop000
2.安装hadoop
hadoop目录结构
bin:客户端访问的一些脚本 如 hadoop map hdfs
etc->hadoop:配置文件
sbin:启动集群的,启动dfs的,启动yarn
share->hadoop->mapreduce:example包带有案例,到时候直接使用就好
1.hadoop配置文件的修改
进入到/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/etc/hadoop
打开
vim hadoop-env.sh 设置JAVA_HOME
export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79
2.配置HDFS默认文件地址
etc/hadoop/core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop000:8020</value> </property> <!--设置hadoop的存储位置--> <!--如果使用默认的设置将保存在临时文件夹,每次重启都会重置该文件夹--> <property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/app/tmp</value> </property> </configuration>
3.设置副本系数:为1 就说每一个block只有一个副本
etc/hadoop/hdfs-site.xml
configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration>
4.将hadoop的bin目录配置到环境变量中
vim /etc/profile
export HADOOP_HOME=/home/hadoop/app/hadoop-2.6.0-cdh5.7.0 export PATH=$HADOOP_HOME/bin:$PATH
让配置生效
source /etc/profile
检验是否配对
echo $HADOOP_HOME
3启动HDFS
1.格式化文件系统(仅第一次执行即可,不要重复执行)
hdfs namenode -format
2.启动namenod和dataNode
在/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/sbin目录下
./start-dfs.sh
3.验证是否启动成功
输入jps
应当有:
NameNode SecondaryNameNode
DataNode
如果有误,可以查看日志
/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/logs/hadoop-hadoop-datanode-hadoop000.log
通过浏览器方式
(需要在windows上配置映射关系)http://hadoop000:50070
4.停止hdfs
在/home/hadoop/app/hadoop-2.6.0-cdh5.7.0/sbin目录下
./stop-dfs.sh
5.HDFS伪分布式搭建出现的问题:
Connection reset by peer; Host Details : local host is: "hadoop000/192.168.199.111"; destination host is: "hadoop000":8020;
解决:将core-site.xml中的端口号去掉
<property> <name>fs.defaultFS</name> <value>hdfs://hadoop000</value> </property>
二、HDFS SHELL
hdfs dfs 等价 hadoop fs
hadoop fs -ls / 查看根目录的所有文件
hadoop fs -put 文件名 目标路径 将文件传到hdfs上
hadoop fs -cat 文件路径 查看文件中的内容
hadoop fs -text 文件路径 查看文件中的内容
hadoop fs -mkdir /test 创建目录
hadoop fs -mkdir -p /test/a/b 递归创建文件夹
hadoop fs -ls -R / 显示文件,文件夹,及文件夹下的文件。
hadoop fs -get /test/a/b/h.text 将文件复制到本地
hadoop fs -rm /hello.text 删除文件
hadoop fs -rm -R /test 删除文件夹
hadoop fs -mv /1.text /test/ 将1.text移动到test下
三、java操作HDFS开发环境搭建
1.创建maven工程
2.导入依赖
<!--添加hadoop的依赖--> <!--添加cdh仓库--> <repositories> <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url> </repository> </repositories> <properties> <hadoop.version>2.6.0-cdh5.7.0</hadoop.version> </properties> <dependencies> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>${hadoop.version}</version> </dependency> </dependencies>
问题:
Missing artifact org.apache.hadoop:hadoop-client:jar:2.6.0-cdh5.7.0
<!--没有添加cdh仓库--> <repositories> <repository> <id>cloudera</id> <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url> </repository> </repositories>
四、java API操作HDFS文件系统
1.Hadoop HDFS Java API 操作
public class HDFSApp{ public static final String HDFS_PATH ="hdfs://hadoop000:8020"; FileSystem fileSystem=null; Configuration configuration =null; //创建hdfs目录 @Test public void mkdir() throws Exception{ fileSystem.mkdirs(new Path(pathString:"/hdfsapi/test")); } //创建文件 @Test public void mkFile() throws Exception{ FSDataOutPutStream output=fileSystem.create(new Path(pathString:"/hdfsapi/test/a.txt")); output.write("hello hadoop".getBytes()); output.flush(); output.close(); } //查看HDFS文件上的内容 @Test public void cat() throws Exception{ FSDataInPutStream in=fileSystem.open(newPath(pathString:"/hdfsapi/test/a.txt")); IOUtils.copyBytes(in,System.out,buffSize:1024); in.close(); } //给文件重命名 public void rename() throws Exception{ Path oldPath=new Path(pathString:"/hdfsapi/test/a.txt"); Path newPath=new Path(pathString:"/hdfsapi/test/b.txt"); fileSystem.rename(oldPath,newPath); } //从本地拷贝文件到HDFS @Test public void copyFromLocal() throws Excpetion{ Path localPath=new Path(pathString:"d:/1.txt"); Path hdfsPath=new Path(pathString:"/hdfsapi/test"); fileSystem.copyFromLocalFile(localPath.hdfsPath).; } //从本地拷贝文件到HDFS上带有进度条 @Test public void copyFromLocalWithProgress() throws Exception { Configuration configuration=new Configuration(); FileSystem fileSystem2 = FileSystem.get(new URI("hdfs://hadoop000:8020"), configuration, "hadoop"); Path dst=new Path("/testApp2/feiq.tar"); BufferedInputStream in=new BufferedInputStream(new FileInputStream(new File("D:\\\\BaiduYunDownload\\\\FeiQ.exe"))); FSDataOutputStream fsDataOutputStream = fileSystem2.create(dst, new Progressable() { @Override public void progress() { System.out.print(".\t"); } }); IOUtils.copyBytes(in, fsDataOutputStream, 4096); fsDataOutputStream.close(); in.close(); fileSystem2.close(); } //从HDFS拷贝文件到本地 @Test public void copyToLocalFile() throws Exception{ Path localPath=new Path(pathString:""); Path hdfsPath=new Path(pathString:""); fileSystem.copyToLocalFile(hdfsPath,localPath); } //查看某个目录下的所有文件 @Test public void listFiles() throws Exception{ FileStatus[] fileStatuses=fileSystem.listStatus(new Path(pathString:"/hdfsapi/test")); for(FileStatus fileStatus:fileStatuses){ String idDir=fielStatus.isDirectory()?"文件夹":"文件"; //得到一个文件的副本因子 short replication=fileStatus.getReplication(); //得到文件的大小 long len=fileStatus.getLen(); //得到文件的路径 String path=fileStatus.getPath().toString(); System.out.println(isDir+"\t"+replication+"\t"+len+"t"+path): } } //删除 @Test public void delete() throws Exception{ //是否递归删除 fileSystem.delte(new Path(pathString:"/hdfsapi/test/")recursive:true); } @Before public void setUp() throws Exception{ System.out.println("HDFSApp.setUp"); configuration =new Configuration(); fileSystem =FileSystem.get(new URI(HDFS_PATH),configuration,user:"hadoop") } @After public void tearDown() throws Exception{ configuration =null; fileSystem =null; System.out.println("HDFSApp.tearDown"); } }
2.注意:
如果通过java上传到HDFS上副本将是3,因为在java上并没有设置副本系数
如果同HDFS shell 的put命令将文件上传到HDFS上 副本将是1,因为在linux中已经配置了副本系数了。
3.HDFS读写数据流程
1.写数据的流程(重点,需要画图)
2.读数据流程
4.HDFS优缺点
1.优点:
数据冗余,硬件容错:多副本,保证一台机坏掉还有其他的副本在别的机器上。
处理流式的数据访问:一次写入多次读取。
适合存储大文件
可构建在廉价的机器上
2.缺点
低延迟的数据访问
不适合小文件存储:小文件的存储也必须占用namenode来记录元数据,如果小文件过多,就相当于一个小文件就对应一个namenode,性价比不高