Hadoop概述

Hadoop2.X组成

Hadoop包括Common、HDFS、Yarn、MapReduce

  • Common辅助工具
  • HDFS数据存储

    • NameNode:存储文件元数据,可以理解为目录
    • DataNode:本地文件系统存储文件块数据,即实实在在的数据
    • SecondaryNameNode:监控HDFS状态的辅助后台程序
  • Yarn资源调度

    • ResourceManager(RM):处理客户端请求,监控NodeManager,监控ApplicationMaster,资源调度与分配
    • NodeManager(NM):管理单个节点上的资源,处理RM、ApplicationMaster的命令
    • ApplicationMaster(AM):
    • Container:资源抽象,封装
  • MapReduce计算

    • Map阶段:并行处理输入数据
    • Reduce阶段:对Map结果汇总

虚拟机环境配置

CentOS7中,如果选择GNOME桌面,无法自定义安装程序,因此系统会安装openjdk 1.7和1.8两个版本,默认是1.8-u102,我们需要删除这两个。

先查看

  1. [root@hadoop101 ~]# rpm -qa|grep java

再删除对应的版本号

  1. [root@hadoop101 ~]# rpm -e --nodeps java-1.8.0-openjdk-1.8.0.242.b08-1.el7.x86_64
  2. [root@hadoop101 ~]# rpm -e --nodeps java-1.7.0-openjdk-1.7.0.251-2.6.21.1.el7.x86_64

接着,配置网络

  1. vim /etc/sysconfig/network-scripts/ifcfg-ens33
  1. TYPE="Ethernet"
  2. PROXY_METHOD="none"
  3. BROWSER_ONLY="no"
  4. BOOTPROTO="static"
  5. DEFROUTE="yes"
  6. IPV4_FAILURE_FATAL="no"
  7. IPV6INIT="yes"
  8. IPV6_AUTOCONF="yes"
  9. IPV6_DEFROUTE="yes"
  10. IPV6_FAILURE_FATAL="no"
  11. IPV6_ADDR_GEN_MODE="stable-privacy"
  12. NAME="ens33"
  13. DEVICE="ens33"
  14. ONBOOT="yes"
  15. IPV6_PRIVACY="no"
  16. IPADDR=192.168.133.130
  17. GATEWAY=192.168.133.2
  18. NETMASK=255.255.255.0
  19. DNS1=192.168.133.2

关闭防火墙

  1. [root@hadoop101 ~]# systemctl stop firewalld.service

防火墙开机禁用

  1. [root@hadoop101 ~]# systemctl disable firewalld.service

接着,开启虚拟机ip和名称的映射,进入/etc/hosts修改

  1. [root@hadoop104 opt]# vim /etc/hosts

添加下面内容

  1. 192.168.133.131 hadoop102
  2. 192.168.133.132 hadoop103
  3. 192.168.133.133 hadoop104

然后可以克隆另一台虚拟机。

克隆完成后只要改ip和hostname,其他的不用改。

修改ip,进入文件修改

  1. [root@hadoop101 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33

修改hostname,先查看当前hostname,和前一台机器一样是叫hadoop101

  1. [root@hadoop101 ~]# hostname

这里改成hadoop102

  1. [root@hadoop101 ~]# hostnamectl set-hostname hadoop102

然后重启虚拟机。

安装JDK和Hadoop

进入/opt/目录,创建两个文件夹software、module,并且删除无用的rh/文件夹

  1. [root@hadoop102 /]# cd /opt/
  2. [root@hadoop102 opt]# mkdir software
  3. [root@hadoop102 opt]# mkdir module
  4. [root@hadoop102 opt]# rm -rf rh/

这里software存放安装包,module是安装目录。

现在可以看看opt/文件夹下的内容

  1. [root@hadoop102 opt]# ll
  2. 总用量 0
  3. drwxr-xr-x. 2 root root 6 10 21 14:22 module
  4. drwxr-xr-x. 2 root root 6 10 21 14:21 software

再将JDK和Hadoop的tar包放进software目录

software目录内容

  1. [root@hadoop102 opt]# cd software/
  2. [root@hadoop102 software]# ll
  3. 总用量 377944
  4. -rw-r--r--. 1 root root 243900138 10 21 14:28 hadoop-2.8.2.tar.gz
  5. -rw-r--r--. 1 root root 143111803 10 21 14:28 jdk-8u261-linux-x64.tar.gz

将tar包解压到module目录

  1. [root@hadoop102 software]# tar -zxvf jdk-8u261-linux-x64.tar.gz -C /opt/module/
  2. [root@hadoop102 software]# tar -zxvf hadoop-2.8.2.tar.gz -C /opt/module/

查看module目录

  1. [root@hadoop102 software]# cd ..
  2. [root@hadoop102 opt]# cd module/
  3. [root@hadoop102 module]# ll
  4. 总用量 0
  5. drwxr-xr-x. 9 502 dialout 149 10 20 2017 hadoop-2.8.2
  6. drwxr-xr-x. 8 10143 10143 273 6 18 14:59 jdk1.8.0_261

配置环境变量,编辑profile文件

  1. [root@hadoop102 jdk1.8.0_261]# vim /etc/profile

在文件末尾插入

  1. ##JAVA_HOME
  2. export JAVA_HOME=/opt/module/jdk1.8.0_261
  3. export PATH=$PATH:$JAVA_HOME/bin
  4. ##HADOOP_HOME
  5. export HADOOP_HOME=/opt/module/hadoop-2.8.2
  6. export PATH=$PATH:$HADOOP_HOME/bin
  7. export PATH=$PATH:$HADOOP_HOME/sbin

然后

  1. [root@hadoop102 hadoop-2.8.2]# source /etc/profile

这样Java和Hadoop就可以用了,通过java -version和hadoop命令查看是否安装完成。

也可以用scp或rsync命令去拷贝。scp是直接拷贝,rsync是拷贝差异文件速度更快。

除此之外,还有xsync命令,循环复制文件到所有节点的相同目录下。

虚拟机的相关配置

在虚拟机上安装完Java和Hadoop并配置好环境变量之后,先创建input文件夹# mkdir input,在/opt/module/hadoop-2.8.2目录下创建该文件夹,。/opt/software/文件夹下存放Java和Hadoop的安装包,/opt/module/是存放Java和Hadoop安装的位置,这里Hadoop是2.8.2、JDK是1.8 。

将.xml文件拷贝到input文件夹下

  1. [root@hadoop-1 hadoop-2.8.2]# cp etc/hadoop/*.xml input/

查看拷贝结果

  1. [root@hadoop-1 hadoop-2.8.2]# ls input/
  2. capacity-scheduler.xml core-site.xml hadoop-policy.xml hdfs-site.xml httpfs-site.xml kms-acls.xml kms-site.xml yarn-site.xml

运行jar包

  1. [root@hadoop-1 hadoop-2.8.2]# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.2.jar grep input/ output 'dfs[a-z.]+'

注意:这里是把输入放在input文件夹,把输出放在output问价夹,input文件夹是前面创建的,output不能自己创建待会程序自己创建。

接着查看output是不是创建了

  1. [root@hadoop-1 hadoop-2.8.2]# ll
  2. 总用量 124
  3. drwxr-xr-x. 2 502 dialout 194 10 20 2017 bin
  4. drwxr-xr-x. 3 502 dialout 20 10 20 2017 etc
  5. drwxr-xr-x. 2 502 dialout 106 10 20 2017 include
  6. drwxr-xr-x. 2 root root 187 10 21 09:31 input
  7. drwxr-xr-x. 3 502 dialout 20 10 20 2017 lib
  8. drwxr-xr-x. 2 502 dialout 239 10 20 2017 libexec
  9. -rw-r--r--. 1 502 dialout 99253 10 20 2017 LICENSE.txt
  10. -rw-r--r--. 1 502 dialout 15915 10 20 2017 NOTICE.txt
  11. drwxr-xr-x. 2 root root 88 10 21 09:44 output
  12. -rw-r--r--. 1 502 dialout 1366 10 20 2017 README.txt
  13. drwxr-xr-x. 2 502 dialout 4096 10 20 2017 sbin
  14. drwxr-xr-x. 4 502 dialout 31 10 20 2017 share

再进入output文件夹,

  1. [root@hadoop-1 hadoop-2.8.2]# cd output/
  2. [root@hadoop-1 output]# ll
  3. 总用量 4
  4. -rw-r--r--. 1 root root 11 10 21 09:44 part-r-00000
  5. -rw-r--r--. 1 root root 0 10 21 09:44 _SUCCESS

查看part-r-00000文件的内容

  1. [root@hadoop-1 output]# cat part-r-00000
  2. 1 dfsadmin

如果内容是这样,就表示成功。

Word Count案例

hadoop目录下创建wcinput文件夹,创建wc.input文件,并在文件里面写入任意字母文本

  1. [root@hadoop-1 hadoop-2.8.2]# mkdir wcinput
  2. [root@hadoop-1 hadoop-2.8.2]# cd wcinput/
  3. [root@hadoop-1 wcinput]# ll
  4. 总用量 0
  5. [root@hadoop-1 wcinput]# touch wc.input
  6. [root@hadoop-1 wcinput]# vim wc.input

接着,运行

  1. [root@hadoop-1 hadoop-2.8.2]# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.8.2.jar wordcount wcinput/ wcoutput

类似上面的wcinput/是已经创建好的,作为输入;wcoutput是未创建的作为输出位置

进入wcoutput查看

  1. [root@hadoop-1 hadoop-2.8.2]# cd wcoutput/
  2. [root@hadoop-1 wcoutput]# ll
  3. 总用量 4
  4. -rw-r--r--. 1 root root 131 10 21 10:27 part-r-00000
  5. -rw-r--r--. 1 root root 0 10 21 10:27 _SUCCESS

查看part-r-00000文件,里面是计数结果

  1. [root@hadoop-1 wcoutput]# cat part-r-00000

集群配置

该集群有102、103、104三台机器。

hadoop102 hadoop103 hadoop104
HDFS NameNode、DataNode DataNode SecondaryNameNode、DataNode
YARN NodeManager ResourceManager、NodeManager NodeManager

xsync脚本

先创建文件,放在bin目录下

  1. [root@hadoop102 ~]# mkdir bin
  2. [root@hadoop102 bin]# touch xsync

文件如下

  1. [root@hadoop102 bin]# vim xsync
  1. #!/bin/bash
  2. #1 获取输入参数个数,如果没有参数,直接退出
  3. pcount=$#
  4. if((pcount==0)); then
  5. echo no args;
  6. exit;
  7. fi
  8. #2 获取文件名称
  9. p1=$1
  10. fname=`basename $p1`
  11. echo fname=$fname
  12. #3 获取上级目录到绝对路径
  13. pdir=`cd -P $(dirname $p1); pwd`
  14. echo pdir=$pdir
  15. #4 获取当前用户名称
  16. user=`whoami`
  17. #5 循环
  18. for((host=103; host<105; host++)); do
  19. echo ------------------- cdh$host --------------
  20. rsync -rvl $pdir/$fname $user@cdh$host:$pdir
  21. done

给权限

  1. [root@hadoop102 bin]# chmod 777 xsync

配置102

首先每个机器的名称和ip匹配,进入/etc/hosts输入ip和服务名称。每台机器都要写。

  1. [root@hadoop102 ~]# vim /etc/hosts
  2. 192.168.133.131 hadoop102
  3. 192.168.133.132 hadoop103
  4. 192.168.133.133 hadoop104

先配置hadoop102,进入hadoop

  1. [root@hadoop102 /]# cd /opt/module/hadoop-2.8.2/
  2. [root@hadoop102 hadoop-2.8.2]# cd etc/hadoop/

配置HDFS

修改hadoop-env.sh,改JAVA_HOME位置,先获取位置

  1. [root@hadoop102 ~]# echo $JAVA_HOME
  2. /opt/module/jdk1.8.0_261

再修改

  1. [root@hadoop102 hadoop]# vim hadoop-env.sh
  1. export JAVA_HOME=/opt/module/jdk1.8.0_261

接着修改core-site.xml文件

  1. [root@hadoop102 hadoop]# vim core-site.xml

添加

  1. <configuration>
  2. <!--指定HDFS中NameNode地址-->
  3. <property>
  4. <name>fs.defaultFS</name>
  5. <value>hdfs://hadoop102:9000</value>
  6. </property>
  7. <!--指定Hadoop运行时产生文件的存储目录-->
  8. <property>
  9. <name>hadoop.tmp.dir</name>
  10. <value>/opt/module/hadoop-2.8.2/data/tmp</value>
  11. </property>
  12. </configuration>

修改HDFS配置文件hdfs-site.xml

  1. [root@hadoop102 hadoop]# vim hdfs-site.xml
  1. <configuration>
  2. <!--<property>
  3. <name>dfs.replication</name>
  4. <value>1</value>
  5. </property>-->
  6. <!--指定Hadoop辅助名称节点主机配置-->
  7. <property>
  8. <name>dfs.namenode.secondary.http-address</name>
  9. <value>hadoop104:50090</value>
  10. </property>
  11. </configuration>

配置yarn

修改yarn-env.sh文件

  1. [root@hadoop102 hadoop]# vim yarn-env.sh
  1. export JAVA_HOME=/opt/module/jdk1.8.0_261

修改yarn-site.xml

  1. [root@hadoop102 hadoop]# vim yarn-site.xml
  1. <configuration>
  2. <!--Reducer获取数据的方式-->
  3. <property>
  4. <name>yarn.nodemanager.aux-services</name>
  5. <value>mapreduce_shuffle</value>
  6. </property>
  7. <!--指定yarn的ResourceManager的地址-->
  8. <property>
  9. <name>yarn.resourcemanager.hostname</name>
  10. <value>hadoop103</value>
  11. </property>
  12. <!--<!--日志聚集功能--
  13. <property>
  14. <name>yarn.log-aggregation-enable</name>
  15. <value>true</value>
  16. </property>
  17. <!--日志保留7天--
  18. <property>
  19. <name>yarn.log-aggregation.retain-seconds</name>
  20. <value>604800</value>
  21. </property>-->
  22. </configuration>

配置MapReduce

修改mapred-env.sh文件

  1. [root@hadoop102 hadoop]# vim mapred-env.sh
  1. export JAVA_HOME=/opt/module/jdk1.8.0_261

修改mapred-site.xml,先把mapred-site.xml.template复制到mapred-site.xml再修改

  1. [root@hadoop102 hadoop]# cp mapred-site.xml.template mapred-site.xml
  2. [root@hadoop102 hadoop]# vim mapred-site.xml
  1. <configuration>
  2. <!--指定MR运行在yarn上-->
  3. <property>
  4. <name>mapreduce.framework.name</name>
  5. <value>yarn</value>
  6. </property>
  7. <!--历史服务器端地址
  8. <property>
  9. <name>mapreduce.jobhistory.address</name>
  10. <value>hadoop102:10020</value>
  11. </property>
  12. <!--历史服务器Web端地址
  13. <property>
  14. <name>mapreduce.jobhistory.webapp.address</name>
  15. <value>hadoop102:19888</value>
  16. </property>-->
  17. </configuration>

将上述配置同步到103、104,xsync是前面编写的脚本。

  1. [root@hadoop102 hadoop]# cd ..
  2. [root@hadoop102 etc]# xsync hadoop/

启动HDFS

先格式化,删除文件,102\103\104里面都要删(如果已经启动了,要先停止节点再删除文件)

  1. [root@hadoop102 hadoop-2.8.2]# rm -rf data/ logs/
  1. [root@hadoop102 hadoop-2.8.2]# bin/hdfs namenode -format

102上启动

  1. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh start namenode
  2. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh start datanode

103上启动

  1. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh start datanode

104上启动

  1. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh start datanode

然后本机浏览器上访问http://hadoop102:50070成功。

配置ssh

102上有NameNode,所以它需要访问其他机器,要配置免密登录。

在102进入ssh文件

  1. [root@hadoop102 ~]# ls -all
  2. [root@hadoop102 ~]# cd .ssh/

获取秘钥

  1. [root@hadoop102 .ssh]# ssh-keygen -t rsa

回车后,三次回车

这时.ssh/下面多了两个文件,id_rsa存放私钥,id_rsa.pub存放公钥,known_hosts存放授权过的无密码登录服务器公钥。

  1. [root@hadoop102 .ssh]# ll
  2. 总用量 12
  3. -rw-------. 1 root root 1679 10 22 08:57 id_rsa
  4. -rw-r--r--. 1 root root 396 10 22 08:57 id_rsa.pub
  5. -rw-r--r--. 1 root root 374 10 21 17:42 known_hosts

拷贝至103

  1. [root@hadoop102 .ssh]# ssh-copy-id hadoop103

回车后第一次需要输入103的密码

此时,发现103的.ssh/下多了文件authorized_keys,里面存放的是102的公钥

  1. [root@hadoop103 .ssh]# ll
  2. 总用量 4
  3. -rw-------. 1 root root 396 10 22 09:02 authorized_keys

同样的做法拷贝到102(自身也需要拷贝)、104 。

现在102访问103和104就不需要密码了,实现免密通信。

此外,103上面有ResourceManager,也需要配置ssh。

群起集群

配置slaves

进入102,修改slaves

  1. [root@hadoop103 .ssh]# cd /opt/module/hadoop-2.8.2/etc/hadoop/
  2. [root@hadoop103 hadoop]# vim slaves
  1. hadoop102
  2. hadoop103
  3. hadoop104

删除文件里其他内容,添加机器名称(这里不能有多余的空格)。

先查看运行的进程

  1. [root@hadoop102 hadoop-2.8.2]# jps
  2. 56437 NameNode
  3. 67051 Jps
  4. 56543 DataNode

把DataNode、NameNode退出

  1. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh stop datanode
  2. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh stop namenode

进入103、104,退出DataNode

  1. [root@hadoop102 hadoop-2.8.2]# sbin/hadoop-daemon.sh stop datanode

这样所有的节点就都正常退出了。

启动HDFS

在102群起

  1. [root@hadoop102 hadoop-2.8.2]# sbin/start-dfs.sh

启动yarn

在103上启动yarn,在另外两个上启动会直接挂,因为ResourceManager配在103上。

  1. [root@hadoop103 hadoop-2.8.2]# sbin/start-yarn.sh

集群测试

传文件测试,将README.txt上传到/目录下

  1. [root@hadoop102 hadoop-2.8.2]# bin/hdfs dfs -put README.txt /

查看

  1. [root@hadoop102 hadoop-2.8.2]# hadoop fs -ls /

这里数据其实是存储在Linux上的,在下面的目录blk_1073741825文件

  1. [root@hadoop102 subdir0]# pwd
  2. /opt/module/hadoop-2.8.2/data/tmp/dfs/data/current/BP-1924141108-192.168.133.131-1603273870979/current/finalized/subdir0/subdir0

上传文件授权(不然删不掉)

  1. [root@hadoop102 hadoop-2.8.2]# hadoop fs -chmod -R 777 /

定时任务

每隔一分钟向/opt/module/hadoop-2.8.2/bailong.txt中追加一个+号。

  1. [root@hadoop102 hadoop-2.8.2]# crontab -e
  1. */1 * * * * /bin/echo "+" >> /opt/module/hadoop-2.8.2/bailong.txt

启动服务

  1. [root@hadoop102 hadoop-2.8.2]# service crond restart

查看文件

  1. [root@hadoop102 hadoop-2.8.2]# tail bailong.txt

也可以查看脚本

  1. [root@hadoop102 hadoop-2.8.2]# crontab -l
  2. */1 * * * * /bin/echo "+" >> /opt/module/hadoop-2.8.2/bailong.txt

不需要了可以删除掉

  1. [root@hadoop102 hadoop-2.8.2]# crontab -r

集群时间同步

以102机器为时间服务器,其他所有机器与102进行时间同步。比如,每隔10分钟同步一次时间。此操作需要root权限。

查询机器是否安装ntp,ntp是网络时间协议,通过这个协议同步时间

  1. [root@hadoop102 hadoop-2.8.2]# rpm -qa | grep ntp

修改ntp配置文件

  1. [root@hadoop102 hadoop-2.8.2]# vim /etc/ntp.conf

修改网段上的所有机器可以访问;注释掉其他网络,集群在局域网中;末尾加入本机节点,当网络丢失时依然可以采用本地时间作为时间服务器;

  1. restrict 192.168.133.0 mask 255.255.255.0 nomodify notrap
  2. #server 0.centos.pool.ntp.org iburst
  3. #server 1.centos.pool.ntp.org iburst
  4. #server 2.centos.pool.ntp.org iburst
  5. #server 3.centos.pool.ntp.org iburst
  6. server 127.127.1.0
  7. fudge 127.127.1.0 stratum 10

修改/etc/sysconfig/ntpd文件,让硬件时间与系统时间一致

  1. [root@hadoop102 hadoop-2.8.2]# vim /etc/sysconfig/ntpd
  1. SYNC_HWCLOCK=yes

查看ntpd状态,启动ntpd服务

  1. [root@hadoop102 hadoop-2.8.2]# service ntpd statu
  2. [root@hadoop102 hadoop-2.8.2]# service ntpd start

设置ntpd开机启动

  1. [root@hadoop102 hadoop-2.8.2]# chkconfig ntpd on

这样102就运行其他网段访问了。

其他机器的配置也需要root权限

  1. [root@hadoop103 hadoop-2.8.2]# crontab -e

编写,表示每一小时同步一次时间

  1. * */1 * * * /usr/sbin/ntpdate hadoop102

添加白名单

102上创建dfs.hosts文件

  1. [root@hadoop102 hadoop]# pwd
  2. /opt/module/hadoop-2.8.2/etc/hadoop
  3. [root@hadoop102 hadoop]# touch dfs.hosts
  4. [root@hadoop102 hadoop]# vi dfs.hosts

添加白名单机器名称

  1. hadoop102
  2. hadoop103
  3. hadoop104

修改hdfs-site.xml,使白名单生效

  1. [root@hadoop102 hadoop]# vi hdfs-site.xml
  1. <property>
  2. <name>dfs.hosts</name>
  3. <value>/opt/module/hadoop-2.8.2/etc/hadoop/dfs.hosts</value>
  4. </property>

配置分发

  1. [root@hadoop102 hadoop]# xsync hdfs-site.xml

刷新NameNode

  1. [root@hadoop102 hadoop]# hdfs dfsadmin -refreshNodes

更新ResourceManager

  1. [root@hadoop102 hadoop]# yarn rmadmin -refreshNodes

如果数据不平衡,可以用命令实现集群再平衡

  1. [root@hadoop102 sbin]# start-balancer.sh

黑名单

102上创建dfs.hosts.exclude文件,添加退役的机器名称

  1. [root@hadoop102 hadoop-2.8.2]# cd etc/hadoop/
  2. [root@hadoop102 hadoop]# touch dfs.hosts.exclude
  3. [root@hadoop102 hadoop]# vi dfs.hosts.exclude
  1. hadoopexit

修改hdfs-site.xml,使黑名单生效

  1. [root@hadoop102 hadoop]# vi hdfs-site.xml
  1. <property>
  2. <name>dfs.hosts.exclude</name>
  3. <value>/opt/module/hadoop-2.8.2/etc/hadoop/dfs.hosts.exclude</value>
  4. </property>

刷新NameNode、ResourceManager,然后把退役的机器上节点正常退出。

环境编译

  • hadoop-2.8.2-src.tar.gz
  • jdk-8u261-linux-x64.gz
  • apache-ant-1.9.9-bin.tar.gz
  • apache-maven-3.0.5-bin.tar.gz
  • protobuf-2.5.0.tar.gz

HDFS

常用命令

  • 启动集群hdfs:sbin/start-dfs.sh
  • 启动集群yarn:sbin/start-yarn.sh
  • help:hadoop fs -help rm
  • 显示目录信息:hadoop fs -ls /
  • 在HDFS上创建目录:hadoop fs -mkdir -p /user
  • 本地剪切到HDFS:hadoop fs -moveFromLocal x.txt /user
  • 追加文件到另一个已存在文件的末尾:hadoop fs -appendToFile x.txt /user/xx.txt
  • 显示:hadoop fs -cat x.txt
  • 移动文件:hadoop fs -mv x.txt /user
  • 下载到本地:hadoop fs -copyToLocal x.txt /local或者hadoop fs -get x.txt /local
  • 删除文件或文件夹:hadoop fs -rm x.txt
  • 删除空目录:hadoop fs -rmdir /user
  • 设置HDFS文件副本数量:hadoop fs -setrep num x.txt

集成IDEA

首先配置好环境变量,新建Maven工程。

添加pom依赖,这里注意对应的hadoop版本

  1. <dependencies>
  2. <dependency>
  3. <groupId>junit</groupId>
  4. <artifactId>junit</artifactId>
  5. <version>4.13</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.logging.log4j</groupId>
  9. <artifactId>log4j-core</artifactId>
  10. <version>2.12.1</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.projectlombok</groupId>
  14. <artifactId>lombok</artifactId>
  15. <version>1.16.18</version>
  16. </dependency>
  17. <!--hadoop-->
  18. <dependency>
  19. <groupId>org.apache.hadoop</groupId>
  20. <artifactId>hadoop-common</artifactId>
  21. <version>2.8.2</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.apache.hadoop</groupId>
  25. <artifactId>hadoop-client</artifactId>
  26. <version>2.8.2</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.apache.hadoop</groupId>
  30. <artifactId>hadoop-hdfs</artifactId>
  31. <version>2.8.2</version>
  32. </dependency>
  33. </dependencies>

还可以配置个日志属性log4j.properties,在resources下面新建

  1. ### 设置###
  2. log4j.rootLogger = debug,stdout,D,E
  3. ### 输出信息到控制抬 ###
  4. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.Target = System.out
  6. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  7. log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
  8. ### 输出DEBUG 级别以上的日志到=E://logs/debug.log ###
  9. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  10. log4j.appender.D.File = E://logs/debug.log
  11. log4j.appender.D.Append = true
  12. log4j.appender.D.Threshold = DEBUG
  13. log4j.appender.D.layout = org.apache.log4j.PatternLayout
  14. log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
  15. ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
  16. log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
  17. log4j.appender.E.File =E://logs/error.log
  18. log4j.appender.E.Append = true
  19. log4j.appender.E.Threshold = ERROR
  20. log4j.appender.E.layout = org.apache.log4j.PatternLayout
  21. log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

测试一下向hdfs新建目录,类HdfsClient.java

  1. package hdfs;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.fs.FileSystem;
  5. import org.apache.hadoop.fs.Path;
  6. import java.io.IOException;
  7. import java.net.URI;
  8. import java.net.URISyntaxException;
  9. /**
  10. * @author Administrator
  11. */
  12. @Slf4j
  13. public class HdfsClient {
  14. public static void main(String[] args) throws IOException, URISyntaxException, InterruptedException {
  15. Configuration conf = new Configuration();
  16. //获取hdfs客户端对象
  17. URI uri = new URI("hdfs://hadoop102:9000");
  18. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  19. //在hdfs上创建路径
  20. Path path = new Path("/man");
  21. fileSystem.mkdirs(path);
  22. //关闭资源
  23. fileSystem.close();
  24. log.info("over");
  25. }
  26. }

此外还有其他的基本文件操作

  1. /**
  2. * 创建目录
  3. */
  4. public static void createDir() throws URISyntaxException, IOException, InterruptedException {
  5. Configuration conf = new Configuration();
  6. //获取hdfs客户端对象
  7. URI uri = new URI("hdfs://hadoop102:9000");
  8. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  9. //在hdfs上创建路径
  10. Path path = new Path("/man");
  11. fileSystem.mkdirs(path);
  12. //关闭资源
  13. fileSystem.close();
  14. }
  15. /**
  16. * 上传文件到HDFS
  17. */
  18. public static void copyFromLocal() throws URISyntaxException, IOException, InterruptedException {
  19. Configuration conf = new Configuration();
  20. //获取hdfs客户端对象
  21. URI uri = new URI("hdfs://hadoop102:9000");
  22. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  23. Path localPath = new Path("C:/Users/Administrator/Desktop/songjiang.txt");
  24. Path hdfsPath = new Path("/man/songjiang.txt");
  25. fileSystem.copyFromLocalFile(localPath,hdfsPath);
  26. fileSystem.close();
  27. }
  28. /**
  29. * 将文件从hdfs拷贝到本地
  30. */
  31. public static void copyToLocal() throws IOException, InterruptedException, URISyntaxException {
  32. Configuration conf = new Configuration();
  33. //获取hdfs客户端对象
  34. URI uri = new URI("hdfs://hadoop102:9000");
  35. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  36. Path localPath = new Path("C:/Users/Administrator/Desktop/down.txt");
  37. Path hdfsPath = new Path("/man/songjiang.txt");
  38. fileSystem.copyToLocalFile(false,hdfsPath,localPath,true);
  39. fileSystem.close();
  40. }
  41. /**
  42. * 文件更名
  43. */
  44. public static void reName() throws URISyntaxException, IOException, InterruptedException {
  45. Configuration conf = new Configuration();
  46. //获取hdfs客户端对象
  47. URI uri = new URI("hdfs://hadoop102:9000");
  48. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  49. Path hdfsOldPath = new Path("/man/songjiang.txt");
  50. Path hdfsNewPath = new Path("/man/shuihu.txt");
  51. fileSystem.rename(hdfsOldPath,hdfsNewPath);
  52. fileSystem.close();
  53. }
  54. /**
  55. * 查看文件详情
  56. */
  57. public static void listFile() throws URISyntaxException, IOException, InterruptedException {
  58. Configuration conf = new Configuration();
  59. //获取hdfs客户端对象
  60. URI uri = new URI("hdfs://hadoop102:9000");
  61. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  62. RemoteIterator<LocatedFileStatus> listFiles = fileSystem.listFiles(new Path("/"), true);
  63. while (listFiles.hasNext()){
  64. LocatedFileStatus fileStatus = listFiles.next();
  65. System.out.println("============="+fileStatus.getPath().getName()+"=============");
  66. System.out.println("文件名称:"+fileStatus.getPath().getName()+"\n文件路径:"+fileStatus.getPath()+"\n文件权限:"+fileStatus.getPermission()+"\n文件大小:"+fileStatus.getLen()
  67. +"\n分区大小:"+fileStatus.getBlockSize()+"\n文件分组:"+fileStatus.getGroup()+"\n文件所有者:"+fileStatus.getOwner());
  68. BlockLocation[] blockLocations = fileStatus.getBlockLocations();
  69. for (BlockLocation blockLocation:blockLocations){
  70. String[] hosts = blockLocation.getHosts();
  71. System.out.printf("所在区间:");
  72. for (String host:hosts){
  73. System.out.printf(host+"\t");
  74. }
  75. System.out.println();
  76. }
  77. }
  78. fileSystem.close();
  79. }
  80. /**
  81. * 判断是文件还是文件夹
  82. */
  83. public static void listStatus() throws URISyntaxException, IOException, InterruptedException {
  84. Configuration conf = new Configuration();
  85. //获取hdfs客户端对象
  86. URI uri = new URI("hdfs://hadoop102:9000");
  87. FileSystem fileSystem = FileSystem.get(uri, conf, "root");
  88. FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/man"));
  89. for (FileStatus fileStatuse:fileStatuses){
  90. if (fileStatuse.isFile()){
  91. System.out.println("文件:"+fileStatuse.getPath().getName());
  92. }else {
  93. System.out.println("文件夹:"+fileStatuse.getPath().getName());
  94. }
  95. }
  96. fileSystem.close();
  97. }

MapReduce

这块程序分成三个部分:Mapper、Reducer、Driver。