hadoop3.1.3记录

官网文档

https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html

下载hadoop-3.1.3.tar.gz

https://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-3.1.3/hadoop-3.1.3.tar.gz

hadoop组成

yarn架构

ResourceManager (由多个nodeManager组成),可以理解为内存,cpu的集合。运行多个客户端提交的任务。这些任务运行在独立的容器(container)中。 每个nodeManager可以运行多个container

MapReduce

分为map和reduce两个过程。map将任务划分为多个子任务,分给多台机器执行;reduce是一个汇总结果的过程

HDFS

Hadoop Distribute File System.

HDFS,yarn,MapReduce三者的关系

有一个任务:比如从100T文件中找出xx.avi文件。

如何实现任务:MapReduce先向ResourceManager申请资源,Map到多个NodeManager。然后多个MapTask执行后将结果提交到DataNode最终汇总到HDFS。hadoop由NameNode和SecondryNameNode组成,主从架构。

推荐系统项目框架

安装hadoop

配置环境

vim /etc/profile

export HADOOP_HOME=/opt/hadoop_soft/hadoop-3.1.3
export PATH=$PATH:$HADOOP_HOME/bin

source /etc/profile

机器之间发送文件

scp -r hadoop-3.1.3 root@slave1:/opt/hadoop_soft/

scp 发送的文件 用户@机器:目的文件路径 (推模式)

scp -r root@slave1:/tmp/ ./test (master拉取slave1机器文件,拉模式)

集群

vim etc/hadoop/workers (master结点)

slave1
slave3

同理配置 slave1 的workers文件内容->

master
slave3 

slave2 的workers文件 ->

master
slave1

xsync集群分发脚本

1)需求:循环复制文件到所有节点的相同目录下

2)需求分析:

a) rsync命令原始拷贝:

rsync   -av  /opt/hadoop_soft/hadoop         root@slave1:/opt/hadoop_soft/

b) 期望脚本:

xsync 要同步的文件名称

c) 期望脚本在任何路径都能使用(脚本放在了全局环境变量的路径)

[root@master ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:。。。。。。。。。。。。。/root/bin

我打算把脚本放在/root/bin目录下。首先得创建一个/root/bin目录

然后cd /root/bin,新建一个脚本,名字随意取。

vim xsync

#!/bin/bash

# 1, 判断参数个数
if [ $# -lt 1 ]
then 
	echo Not Enough Arguement!
	exit
fi

# 2, 遍历集群所有机器
for host in master slave1 slave3
do
	echo ==== $host ====
	# 3, 遍历所有目录,挨个发送.比如xsync a.txt b.txt  遍历a.txt和b.txt
	for file in $@
	do 
		# 4,判断文件是否存在
		if [ -e $file ]
        then
			# 5, 获取父目录, -P适用于获取软链接的父目录
			pdir=$(cd -P $(dirname $file); pwd)
				
			# 6.获取当前文件名称
			fname=$(basename $file)
            ssh $host "mkdir -p $pdir"
			rsync -av $pdir/$fname $host:$pdir
		else
	    	echo $file does not exists!
		fi
	done
done

赋予脚本权限 chmod 777 /root/bin/xsync

测试 (以下命令意思是将文件同步到其他节点, 其他节点存在该文件就覆写)

xsync   xxfile1   xxfile2 ...

hadoop配置

启动dfs

sbin/start-dfs.sh

报错

Starting namenodes on [namenode] ERROR: Attempting to operate on hdfs namenode as root ERROR: but there is no HDFS_NAMENODE_USER defined ...

解决办法:

注意: 是在文件开始空白处!

在start-dfs.sh中

HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root

修改stop-dfs.sh

[root@master sbin]# vi stop-dfs.sh
添加:

HDFS_DATANODE_USER=root
HDFS_DATANODE_SECURE_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root

在start-yarn.sh中

YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root

修改stop-yarn.sh

[root@master sbin]# vi stop-yarn.sh
添加:

YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root

core-site.xml

<configuration>
<!-- 指定hdfs的nameservice为ns1 -->
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://master:9000</value>
        </property>
        <!-- Size of read/write buffer used in SequenceFiles. -->
        <property>
         <name>io.file.buffer.size</name>
         <value>131072</value>
       </property>
        <!-- 指定hadoop临时目录,自行创建 -->
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/opt/hadoop_soft/hadoop-3.1.3/tmp</value>
        </property>
</configuration>

fs.defaultFS为NameNode的地址。

hadoop.tmp.dir为hadoop临时目录的地址,默认情况下,NameNode和DataNode的数据文件都会存在这个目录下的对应子目录下。应该保证此目录是存在的,如果不存在,先创建。

hdfs-site.xml

<configuration>
    <property>
      <name> dfs.namenode.http-address </name>
      <value>master:9870</value>
    </property>
    <property>
      <name>dfs.replication</name>
      <value>2</value>
    </property>
    <property>
      <name>dfs.namenode.name.dir</name>
      <value>file:/opt/hadoop_soft/hadoop-3.1.3/hdfs/name</value>
    </property>
    <property>
      <name>dfs.datanode.data.dir</name>
      <value>file:/opt/hadoop_soft/hadoop-3.1.3/hdfs/data</value>
    </property>
</configuration>

mapred-site.xml

<configuration>

 <property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
  </property>

</configuration>

mapreduce.framework.name设置mapreduce任务运行在yarn上。

### yarn-site.xml

<configuration>

     <property>
          <name>yarn.nodemanager.aux-services</name>
          <value>mapreduce_shuffle</value>
     </property>
       <property>
            <name>yarn.resourcemanager.webapp.address</name>
            <value>master:8088</value>
        </property>
        
        <property>
            <name>yarn.resourcemanager.hostname</name>
            <value>master</value>
    </property>

</configuration>

hadoop-env.sh

export JAVA_HOME=/opt/jdk1.8.0_161 

vi /etc/hosts
文件内,添加如下内容(具体还要看你的三台虚拟机的主机名和ip地址对应分别为,下面的只是我自己的)

192.168.109.11 master
192.168.109.22 slave1
192.168.109.33 slave3

初始化namenode

清理环境: 对三台机器处理:

删除hdfs目录及logs目录,清理历史数据。还有/tmp目录下的hadoop相关文件
如果配置了${hadoop_home}/tmp目录,还要删除该目录下(tmp/*)所有文件。

注意 用netstat -tlnp查看是否有hadoop相关端口未关闭

bin/hdfs namenode -format

启动master

sbin/start-all.sh (only master结点)

在master机器上启动datanode

hdfs --daemon start datanode //seems no necessary !

//扩容启动nodemanager yarn --daemon start nodemanager

关闭 sbin/stop-all.sh

查看状态

[root@master hadoop-3.1.4]# jps
7857 Jps
6934 DataNode
7158 SecondaryNameNode
7558 NodeManager
6796 NameNode
7421 ResourceManager

解决master ssh到slave1节点问题

$ ssh-copy-id -i slave1

访问 http://192.168.109.11:8088

访问 192.168.109.11:9870

查看文件状态

http://192.168.109.11:9870/explorer.html#/

当在该网站删除文件时 报错: Permission denied: user=dr.who, access=WRITE, inode="/":root:supergroup:drwxr-xr-x

vim core-site.xml

       <property>          
            <name>hadoop.http.staticuser.user</name>
                <value>root</value>
        </property>

添加完成后分发给其他结点。然后重启集群

创建hdfs目录处理MapReduce任务

hdfs dfs -mkdir -p /user/root/input

复制文件到分布式系统

bin/hdfs dfs -put etc/hadoop/*.xml input

查看是否复制成功

hadoop fs -ls /user/root/input

执行任务:

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar grep input output ‘dfs[a-z.]+’

复制结果到本地,并检测

bin/hdfs dfs -get output output
cat output/*

结果错误Exit code: 127 Stack trace: ExitCodeException exitCode=127:

解决:创建软链接

ln -s $JAVA_HOME/bin/java /bin/java

验证 /bin/java -version

分别给slave1,slave3创建软连接

Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster

Please check whether your etc/hadoop/mapred-site.xml contains the below configuration:

解决:vim etc/hadoop/mapred-site.xml

<property>
  <name>yarn.app.mapreduce.am.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
  <name>mapreduce.map.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
<property>
  <name>mapreduce.reduce.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>

发现是虚拟内存不足。由于我的物理内存为1个G,默认的虚拟内存率为2.1 .即虚拟内存为2.1G。任务需要的虚拟内存2.5G>2.1G,执行失败。

我将默认的虚拟内存率调到了3.1

vim etc/hadoop/mapred.site.xml

<property>
    <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>3.1</value>  
    <source>yarn-default.xml</source>
</property>

分发给slave1,slave3

配置历史服务器

vim etc/hadoop/mapred-site.xml

mapreduce.jobhistory.address master:10020 mapreduce.jobhistory.webapp.address master:19888

分发

一种更加精细化的启动

sbin/start-dfs.sh

sbin/start-yarn.sh

在master启动历史服务器

bin/mapred --daemon start historyserver

查看历史服务器是否启动 jps

发现多了一个JobHistoryserver进程

查看JobHistory

http://master:19888/jobhistory

日志聚集

<!--开启日志聚集-->

 <property>
        <name>yarn.log-aggregation-enable</name>
        <value>true</value>
</property>

<!--设置日志聚集服务器地址-->

<property>
        <name>yarn.log.server.url</name>
        <value>http://master:19888/jobhistory/logs</value>
</property>

<!--日志保留7天-->

<property>
        <name>yarn.log-aggregation.retain-seconds</name>
        <value>604800</value>
</property>

分发

关闭HistoryServer

mapred --daemon stop historyserver

由于修改了yarn配置,关闭yarn 然后重启yarn

sbin/stop-yarn.sh ; sbin/start-yarn.sh

然后重启 HistoryServer : mapred --daemon start historyserver

验证日志是否生效

需要重新启动一个mapReduce任务

启动方式总结

1 整体启动/停止HDFS

start-dfs.hs/stop-dfs.sh

2 整体启动/停止YARN

start-yarn.sh/stop-yarn.sh

各个服务组件逐一启动/停止

1 启动,停止HDFS组件

hdfs --daemon start/stop namenode/datanode/secondarynamenode

2 启动,停止YARN

yarn --daemon start/stop resourcemanager/nodemanager

启动停止脚本

vim bin/myhadoop.sh

#!/bin/bash

if [ $# -lt 1 ]
then
    echo "No Args input ...use 'start' or 'stop'"
    exit;
fi

case $1 in
"start")
        echo "---启动hadoop集群----"
        echo "---启动hdfs---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/sbin/start-dfs.sh"
        echo "---启动yarn---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/sbin/start-yarn.sh"
        echo "---启动historyserver---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/bin/mapred --daemon start historyserver"
;;

"stop")
        echo  "---关闭hadoop集群---"
        echo "---关闭hdfs---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/sbin/stop-dfs.sh"
        echo "---关闭yarn---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/sbin/stop-yarn.sh"
        echo "---关闭historyserver---"
        ssh master "/opt/hadoop_soft/hadoop-3.1.3/bin/mapred --daemon stop historyserver"
;;
*)
       echo "input Args Error...use 'start' or 'stop'" 
;;
esac

配置时间服务器(集群不能连接外网时)

我没有配置,因为我机器能连网

1 主机器配置(必须root用户)

查看ntpd是否启动 systemctl status ntpd

修改ntpd.conf文件 vim /etc/ntp.conf . 内容变更如下

# 允许内网其他机器同步时间  (取消注释)
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

#   (注释掉)
#server 0.centos.pool.ntp.org iburst   
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst

# 外部时间服务器不可用时,以本地时间作为时间服务(添加)
 server  127.127.1.0     # local clock
 fudge   127.127.1.0 stratum 10

修改master的/etc/sysconfig/ntpd文件 vim /etc/sysconfig/ntpd

增加内容如下(让硬件时间与系统时间同步)

SYNC_HWCLOCK=yes

重启ntpd systemctl start ntpd

设置开机自启 systemctl enable ntpd

从机器配置 (必须root用户)

1 关闭所有从节点上ntp服务和自启动(slave1,slave3分别执行以下2条命令)

systemctl stop ntpd

systemctl disable ntpd

2 配置1分钟与时间服务器同步一次

crontab -e

编写定时任务如下:

*/1 * * * * /usr/sbin/ntpdate master

3 修改任意机器时间

date -s “2021-9-11 11:11:11”

4 1分钟后查看机器是否与时间服务器同步

date

hdfs客户端操作

一、下载winutils

winutils.exe主要用于模拟linux下的目录环境。当Hadoop在windows下运行或调用远程Hadoop集群的时候,需要该辅助程序才能运行

下载 https://github.com/s911415/apache-hadoop-3.1.0-winutils

二, 下载hadoop3.1.0.tar.gz解压到D:\hadoop\hadoop-3.1.0

解压hadoop3.1.0.tar.gz 过程出错。

解决:在C:\Program Files\WinRAR下右键点击winrar.exe,选择属性->兼容性,点击勾选以管理员身份运行框,再次解压。

1 将hadoop-3.1.0-winutils 目录下的bin目录copy到hadoop3.1.0.tar.gz解压后的bin目录,选择覆盖。这样winutils.exe等文件就在D:\hadoop\hadoop-3.1.0\bin目录了。

2 配置HADOOP_HOME环境变量

新建HADOOP_HOME变量,然后将HADOOP_HOME加入到PATH

点击PATH选项,新增一项 %HADOOP_HOME%\bin

三,来到HADOOP_HOME\bin目录,双击winutils.exe.如果没有报错,环境就配成功了。

windows本地运行mapReduce任务

linux集群运行mapreduce任务

1 打出jar包放到linux上

2 启动jar

hadoop jar xxx.jar org.yh.wordcount.WordCount /input /output

org.yh.wordcount.WordCount对应一个main函数入口类WordCount.java

/*
 * @Description:  如果在linux上运行,将jar包发送。
 *                 运行命令: hadoop jar xx.jar org.yh.wordcount.WordCount /input /output
 *                 这里org.yh.wordcount.WordCount指定了main函数入口
 */


public class WordCount {
//    static {
//        try {
//            // 加载库文件
//            //解决启动错误 org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
//            System.load("D:\\hadoop\\hadoop-3.1.0\\bin\\hadoop.dll");
//        } catch (UnsatisfiedLinkError e) {
//            System.err.println("Native code library failed to load.\n" + e);
//            System.exit(1);
//        }
//    }

    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf);
        job.setJarByClass(WordCount.class);
        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);
        //设置输出的key,value类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        //注意导包,使用MapReduce的FileInputFormat
        FileInputFormat.setInputPaths(job,
//                new Path("E:\\tmp\\hello.txt")
                new Path(args[0])
        );
        FileOutputFormat.setOutputPath(job,
//                new Path("E:\\tmp\\res")
                new Path(args[1])
        );
        //提交job
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }

    /**
     * LongWritable:  input key type    固定
     * Text  :        input value type  固定
     * Text  :        output key type   相当于java基本类型中的String
     * IntWritable :  output value type  相当于int
     */
    public static class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
        private static Text word = new Text();
        private static final IntWritable one = new IntWritable(1);

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] words = line.split(" ");

            for (String w : words) {
                word.set(w);
                context.write(word, one);
            }
        }
    }

    /**
     * Reducer<Text, IntWritable, Text, IntWritable>
     *     输入kv和输出kv类型对应一致,Text IntWritable->Text  IntWritable
     */
    public static class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
        private static IntWritable result = new IntWritable();

        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable val : values) {
                sum += val.get();
            }
            result.set(sum);
            context.write(key, result);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值