Hadoop入门必看

Hadoop概念知识导图

Hadoop.png

Hadoop集群搭建

基础设施

操作系统、环境、网络、必须软件
centos 6.5
JDK 1.8
Hadoop 2.6.5
1.设置IP及主机名

# vi /etc/sysconfig/network-scripts/ifcfg-eth0
 DEVICE=eth0
 #HWADDR=00:)C:29:42:15:C2
 TYPE=Ethernet
 ONBOOT=yes
 NM_CONTROllED=yes
 BOOTPROTO=static
 IPADDR=192.168.150.11
 NETMASK=255.255.255.0
 GATEWAY=192.168.150.2
 DNS1=223.5.5.5
 DNS2=114.114.114.114
 # vi /etc/sysconfig/network
 NETWORKING=yes
 HOSTNAME=node01

2.关闭防火墙&selinux

service iptables stop
chkconfig iptables off
# vi /etc/selinux/config
SELINUX=disabled

3.设置hosts映射

# vi /etc/hosts
 192.169.150.11 node01
 192.168.150.12 node02

4.时间同步

yum install ntp -y
# vi /etc/ntp.conf
server ntp1.aliyun.com
service ntpd start
chkconfig ntpd on

5.安装jdk

rpm -i <jdk的rpm包>
#有一些软件只认、usr/java/default
vi /etc/profile
export JAVA_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin
source /etc/profile
#或者 . /etc/profile

设置SSH免秘钥

# 1. 验证本机是否免密 2. 被动生成/root/.ssh目录
ssh localhost
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

部署配置

伪分布式: (单一节点)

1.部署路径

mkdir /opt/bigdata
tar xf hadoop-2.6.5.tar.gz
mv hadoop-2.6.5 /opt/bigdata
pwd
    /opt/bigdata/hadoop-2.6.5
vi /etc/profile
export HADOOP_HOME=/opt/bigdata/hadoop-2.6.5
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile

2.配置文件
配置hadoop的角色:

cd $HADOOP_HOME/etc/hadoop
vi hadoop_env.sh

•hadoop-env.sh
配置JAVA_HOME

vi hadoop-env.sh
    export JAVA_HOME=/usr/java/default

•core-site.xml
配置NN的启动入口

<property>
  <name>fs.defaultFS</name>
  <value>hdfs://node01:9000</value>
</property>

•hdfs-site.xml

  1. 配置hdfs,副本数为1
  2. 配置NN元数据存储路径
  3. 配置块数据的存储路径
<property>
  <name>dfs.replication</name>
  <value>1</value>
</property>
<property>
  <name>dfs.namenode.name.dir</name>
  <value>/var/bigdata/hadoop/local/dfs/name</value>
</property>
<property>
  <name>dfs.datanode.data.dir</name>
  <value>/var/bigdata/hadoop/local/dfs/data</value>
</property>
<property>
  <name>dfs.namenode.secondary.http-address</name>
  <value>node01:50090</value>
</property>
<property>
  <name>dfs.namenode.checkpoint.dir</name>
  <value>/var/bigdata/hadoop/local/dfs/secondary</value>
</property>

•slaves

完全分布式: (四节点)

1.部署路径
1)角色在哪里启动
NN: core-site.xml: fs.defaultFS hdfs://node01:9000
DN: slaves: node01
SNN: hadoop-site.xml: dfs.namenode.secondary.http-address
2)角色启动时的细节配置
dfs.namenode.name.dir
dfs.datanode.data.dir
2.配置文件
•hadoop-env.sh
•core-site.xml
•hdfs-site.xml
•slaves
3.分发配置

node02~node04:
		rpm -i jdk....
	node01:
		scp /root/.ssh/id_dsa.pub  node02:/root/.ssh/node01.pub
		scp /root/.ssh/id_dsa.pub  node03:/root/.ssh/node01.pub
		scp /root/.ssh/id_dsa.pub  node04:/root/.ssh/node01.pub
	node02:
		cd ~/.ssh
		cat node01.pub >> authorized_keys
	node03:
		cd ~/.ssh
		cat node01.pub >> authorized_keys
	node04:
		cd ~/.ssh
		cat node01.pub >> authorized_keys
配置部署:
	node01:
		cd $HADOOP/etc/hadoop
		vi core-site.xml    不需要改
		vi hdfs-site.xml
			  <property>
				<name>dfs.replication</name>
				<value>2</value>
			  </property>
			  <property>
				<name>dfs.namenode.name.dir</name>
				<value>/var/bigdata/hadoop/full/dfs/name</value>
			  </property>
			  <property>
				<name>dfs.datanode.data.dir</name>
				<value>/var/bigdata/hadoop/full/dfs/data</value>
			  </property>
			  <property>
				<name>dfs.namenode.secondary.http-address</name>
				<value>node02:50090</value>
			  </property>
			  <property>
				<name>dfs.namenode.checkpoint.dir</name>
				<value>/var/bigdata/hadoop/full/dfs/secondary</value>
			  </property>
		vi slaves
			node02
			node03
			node04

		分发:
			cd /opt
			scp -r ./bigdata/  node02:`pwd`
			scp -r ./bigdata/  node03:`pwd`
			scp -r ./bigdata/  node04:`pwd`

		格式化启动
			hdfs namenode -format
			start-dfs.sh

初始化运行

# 创建目录
# 并初始化一个空的fsimage
# VERSION
# CID
hdfs namenode -format

# 第一次:datanode和secondary角色会初始化创建自己的数据目录
start-dfs.sh

# 修改windows: C:\Windows\System32\drivers\etc\hosts
        # 192.168.150.11 node01
        # 192.168.150.12 node02
        # 192.168.150.13 node03
        # 192.168.150.14 node04
http://node01:50070

命令行使用

hdfs dfs -mkdir /bigdata
hdfs dfs -mkdir  -p  /user/root
cd   /var/bigdata/hadoop/local/dfs/name/current
    观察 editlog的id是不是再fsimage的后边
cd /var/bigdata/hadoop/local/dfs/secondary/current
    SNN 只需要从NN拷贝最后时点的FSimage和增量的Editlog
hdfs dfs -put hadoop*.tar.gz  /user/root
cd  /var/bigdata/hadoop/local/dfs/data/current/BP-281147636-192.168.150.11-1560691854170/current/finalized/subdir0/subdir0

for i in `seq 100000`;do  echo "hello hadoop $i"  >>  data.txt  ;done
hdfs dfs -D dfs.blocksize=1048576  -put  data.txt 
cd  /var/bigdata/hadoop/local/dfs/data/current/BP-281147636-192.168.150.11-1560691854170/current/finalized/subdir0/subdir0
检查data.txt被切割的块,他们数据什么样子

HDFS-HA

主从集群:结构相对简单,主与从协作
主:单点,数据一致性好掌握
问题:

  • 单点故障,集群整体不可用
  • 压力过大

HDFS解决方案

单点故障:
  • 高可用方案:HA
  • 多个NN,主备切换,主 (Hadoop2.x支持一主一备,Hadoop3.x支持一主多备最大是五台备用节点)
  • CAP原则:Consistency(一致性),Availablity(可用性),Partition Tolerance(分区容忍性)

image.png

  • Paxos算法:
    Paxos算法是莱斯利·兰伯特于1990年提出的一种基于消息传递的一致性算法。
    这个算法被认为是类似算法中最有效的。
    该算法覆盖全部场景的一致性。
    每种技术会根据自己技术的特征选择简化算法实现。
    传递:NN之间通过一个可靠的传输技术,最终数据能同步就可以
    *我们一般假设网络等因素是稳定的
    *类似一种带存储能力的消息队列
    image.pngimage.png
  • 简化思路:

分布式节点是否明确
节点权重是否明确
强一致性破坏可用性
过半通过可以中和一致性和可用性
最简单的自我协调实现:主从
主的选举:明确节点数量和权重
主从的职能:
主:增删改查
从:查询,增删改传递给主
主与从:过半数同步数据

  • HDFS-HA解决方案:

多台NN主备模式,Active和Standby状态
Active对外提供服务
增加journalnode角色(>3台),负责同步NN的editlog
最终一致性
增加zkfc角色(与NN同台),通过zookeeper集群协调NN的主从选举和切换
事件回调机制
DN同时向NNs汇报block清单

压力过大,内存受限:
  • 联邦机制:Federation(元数据分片)
  • 多个NN,管理不同的元数据
  • HDFS- Federation解决方案:
    NN的压力过大,内存受限问题:
    元数据分治,复用DN存储
    元数据访问隔离性
    DN目录隔离block

image.png


#core-site.xml
<property>
  <name>fs.defaultFS</name>
  <value>hdfs://mycluster</value>
</property>

<property>
  <name>ha.zookeeper.quorum</name>
  <value>node02:2181,node03:2181,node04:2181</value>
</property>

hdfs-site.xml
#以下是  一对多,逻辑到物理节点的映射
<property>
  <name>dfs.nameservices</name>
  <value>mycluster</value>
</property>
<property>
  <name>dfs.ha.namenodes.mycluster</name>
  <value>nn1,nn2</value>
</property>
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  <value>node01:8020</value>
</property>
<property>
  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  <value>node02:8020</value>
</property>
<property>
  <name>dfs.namenode.http-address.mycluster.nn1</name>
  <value>node01:50070</value>
</property>
<property>
  <name>dfs.namenode.http-address.mycluster.nn2</name>
  <value>node02:50070</value>
</property>

#以下是JN在哪里启动,数据存那个磁盘
<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
</property>
<property>
  <name>dfs.journalnode.edits.dir</name>
  <value>/var/bigdata/hadoop/ha/dfs/jn</value>
</property>

#HA角色切换的代理类和实现方法,我们用的ssh免密
<property>
  <name>dfs.client.failover.proxy.provider.mycluster</name>
  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<property>
  <name>dfs.ha.fencing.methods</name>
  <value>sshfence</value>
</property>
<property>
  <name>dfs.ha.fencing.ssh.private-key-files</name>
  <value>/root/.ssh/id_dsa</value>
</property>

#开启自动化: 启动zkfc
<property>
  <name>dfs.ha.automatic-failover.enabled</name>
  <value>true</value>
</property>


基础设施
ssh免密:
1)启动start-dfs.sh脚本的机器需要将公钥分发给别的节点
2)在HA模式下,每一个NN身边会启动ZKFC,ZKFC会用免密的方式控制自己和其他NN节点的NN状态
应用搭建
HA 依赖 ZK 搭建ZK集群
修改hadoop的配置文件,并集群同步
初始化启动
1)先启动JN hadoop-daemon.sh start journalnode
2)选择一个NN 做格式化:hdfs namenode -format <只有第一次搭建做,以后不用做>
3)启动这个格式化的NN ,以备另外一台同步 hadoop-daemon.sh start namenode
4)在另外一台机器中: hdfs namenode -bootstrapStandby
5)格式化zk: hdfs zkfc -formatZK <只有第一次搭建做,以后不用做>
6) start-dfs.sh
使用
------实操:
1)停止之前的集群
2)免密:node01,node02

cd ~/.ssh
ssh-keygen -t dsa -P '' -f ./id_dsa
cat id_dsa.pub >> authorized_keys
scp ./id_dsa.pub  node01:`pwd`/node02.pub
cd ~/.ssh
cat node02.pub >> authorized_keys
3)zookeeper 集群搭建  java语言开发  需要jdk  部署在2,3,4
tar xf zook....tar.gz
mv zoo...    /opt/bigdata
cd /opt/bigdata/zoo....
cd conf
cp zoo_sample.cfg  zoo.cfg
vi zoo.cfg
'''
datadir=/var/bigdata/hadoop/zk
server.1=node02:2888:3888
server.2=node03:2888:3888
server.3=node04:2888:3888
'''
mkdir /var/bigdata/hadoop/zk
echo 1 >  /var/bigdata/hadoop/zk/myid 
vi /etc/profile
'''
export ZOOKEEPER_HOME=/opt/bigdata/zookeeper-3.4.6
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin
'''
. /etc/profile
cd /opt/bigdata
scp -r ./zookeeper-3.4.6  node03:`pwd`
scp -r ./zookeeper-3.4.6  node04:`pwd`
mkdir /var/bigdata/hadoop/zk
echo 2 >  /var/bigdata/hadoop/zk/myid
*环境变量
. /etc/profile
mkdir /var/bigdata/hadoop/zk
echo 3 >  /var/bigdata/hadoop/zk/myid
*环境变量
. /etc/profile
zkServer.sh start
4)配置hadoop的core和hdfs
5)分发配置
	给每一台都分发
6)初始化:
	1)先启动JN   hadoop-daemon.sh start journalnode 
	2)选择一个NN 做格式化:hdfs namenode -format   <只有第一次搭建做,以后不用做>
	3)启动这个格式化的NN ,以备另外一台同步  hadoop-daemon.sh start namenode 
	4)在另外一台机器中: hdfs namenode -bootstrapStandby
	5)格式化zk:   hdfs zkfc  -formatZK     <只有第一次搭建做,以后不用做>
	6) start-dfs.sh	

使用验证:
1)去看jn的日志和目录变化:
2)node04
zkCli.sh
ls /
启动之后可以看到锁:
get /hadoop-ha/mycluster/ActiveStandbyElectorLock
3)杀死namenode 杀死zkfc
kill -9 xxx
a)杀死active NN
b)杀死active NN身边的zkfc
c)shutdown activeNN 主机的网卡 : ifconfig eth0 down
2节点一直阻塞降级
如果恢复1上的网卡 ifconfig eth0 up
最终 2编程active

HDFS权限

hdfs是一个文件系统

  • 类unix、linux
  • 有用户概念
  • 有权限概念
    hdfs的权限是自己控制的,来自于其超级用户
  • 但没有相关的命令和接口创建用户,信任客户端,默认情况使用的是操作系统提供的用户,可以拓展kerberos LDAP或者其他第三方用户认证系统
  • 有超级用户的概念
    linux系统中的超级用户:root
    hdfs系统中的超级用户:是namanode的启动用户

一般再企业中不会用root做什么事情

  • 面向操作系统:root是管理员,其他用户都叫做普通用户
  • 面向操作系统的软件:谁启动,管理这个进程,那么这个用户叫做这个软件的管理员

实操

切换我们用root搭建的HDFS,用god这个用户来启动
node01~node04

stop-dfs.sh
# 添加用户:root
useraadd god
passwd god
# 将资源与用户绑定(安装部署程序;数据存放目录)
chown -R god src
chown -R god /opt/bigdata/hadoop-2.6.5
chown -R god /var/bigdata/hadoop
# 切换到god去启动 start-dfs.sh(需要免密)给god做免密
ssh localhost -> 为了拿到.ssh目录
node01~node02:
	cd /home/god/.ssh
	ssh-keygen -t dsa -P '' -f ./id_dsa
node01:
  ssh-copy-id -i id_dsa node01
  ssh-copy-id -i id_dsa node02
  ssh-copy-id -i id_dsa node03
  ssh-copy-id -i id_dsa node04
node02:
	ssh-copy-id -i id_dsa node01
	ssh-copy-id -i id_dsa node02
# hdfs-site.xml
<property>
  <name>dfs.ha.fencing.ssh.private-key-files</name>
  <value>/home/god/.ssh/id_dsa</value>
</property>
分发给node02~node04
# god: start-dfs.sh

用户权限验证实操

#node01:
su god
hdfs dfs -mkdir /temp
hdfs dfs -chown god:ooxx /temp
hdfs dfs -chmod 770 /temp

#node04
#@root
user add good 
groupadd ooxx
usermode -a -G ooxx good
id good
su good 
hdfs dfs -mkdir /temp/abc
hdfs groups -> good: (因为hdfs已经启动,不知道操作系统又偷偷创建了用户和组)

#node01:
#@root
user add good 
groupadd ooxx
usermode -a -G ooxx good
su god
#必须在namenode执行才会生效
hdfs dfs -refreshUserToGroupsMappings

#node04:
su good
hdfs groups -> good: good ooxx

HDFS api

语义: 开发HDFS的client
权限:1) 参考系统登录用户名 2)参考环境变量 3)代码中给出:
HADOOP_USER_NAME god
这一步操作优先于启动IDEA
jdk版本:集群和开发环境jdk版本需一致
maven: 构件工具,包含了很多依赖管理pom),jar包有仓库的概念,可以打包、测试、清楚、构建项目目录等。GAV定位(坐标)MAVEN库
hdfs的pom:
hadoop:common、hdfs、yarn、mapreduce
构建HDFS工程

  1. pom引入相关依赖
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.6.5</version>
</dependency>
  1. resources 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://mycluster</value>
    </property>
		 <property>
		   <name>ha.zookeeper.quorum</name>
		   <value>node02:2181,node03:2181,node04:2181</value>
		 </property>
</configuration>

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/var/bigdata/hadoop/ha/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/var/bigdata/hadoop/ha/dfs/data</value>
    </property>

<property>
		  <name>dfs.nameservices</name>
		  <value>mycluster</value>
		</property>
		<property>
		  <name>dfs.ha.namenodes.mycluster</name>
		  <value>nn1,nn2</value>
		</property>
		<property>
		  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
		  <value>node01:8020</value>
		</property>
		<property>
		  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
		  <value>node02:8020</value>
		</property>
		<property>
		  <name>dfs.namenode.http-address.mycluster.nn1</name>
		  <value>node01:50070</value>
		</property>
		<property>
		  <name>dfs.namenode.http-address.mycluster.nn2</name>
		  <value>node02:50070</value>
		</property>




<property>
		  <name>dfs.namenode.shared.edits.dir</name>
		  <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
		</property>
		<property>
		  <name>dfs.journalnode.edits.dir</name>
		  <value>/var/bigdata/hadoop/ha/dfs/jn</value>
		</property>


<property>
		  <name>dfs.client.failover.proxy.provider.mycluster</name>
		  <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
		</property>
		<property>
		  <name>dfs.ha.fencing.methods</name>
		  <value>sshfence</value>
		</property>
		<property>
		  <name>dfs.ha.fencing.ssh.private-key-files</name>
		  <value>/home/god/.ssh/id_dsa</value>
		</property>


		 <property>
		   <name>dfs.ha.automatic-failover.enabled</name>
		   <value>true</value>
		 </property>

</configuration>

  1. 编写代码
package com.msb.bigdata.hadoop.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.URI;

public class TestHDFS {

    public Configuration conf = null;
    public FileSystem fs = null;

    //C/S
    @Before
    public void conn() throws Exception {
        conf = new Configuration(true);//true
        //        fs = FileSystem.get(conf);
        //       <property>
        //        <name>fs.defaultFS</name>
        //        <value>hdfs://mycluster</value>
        //       </property>
        //去环境变量 HADOOP_USER_NAME  god
        fs = FileSystem.get(URI.create("hdfs://mycluster/"),conf,"god");
    }

    @Test
    public void mkdir() throws Exception {

        Path dir = new Path("/msb01");
        if(fs.exists(dir)){
            fs.delete(dir,true);
        }
        fs.mkdirs(dir);

    }

    @Test
    public void upload() throws Exception {

        BufferedInputStream input = new BufferedInputStream(new FileInputStream(new File("./data/hello.txt")));
        Path outfile   = new Path("/msb/out.txt");
        FSDataOutputStream output = fs.create(outfile);

        IOUtils.copyBytes(input,output,conf,true);
    }

    @Test
    public void blocks() throws Exception {

        Path file = new Path("/user/god/data.txt");
        FileStatus fss = fs.getFileStatus(file);
        BlockLocation[] blks = fs.getFileBlockLocations(fss, 0, fss.getLen());
        for (BlockLocation b : blks) {
            System.out.println(b);
        }
        //        0,        1048576,        node04,node02  A
        //        1048576,  540319,         node04,node03  B
        //计算向数据移动~!
        //其实用户和程序读取的是文件这个级别~!并不知道有块的概念~!
        FSDataInputStream in = fs.open(file);  //面向文件打开的输入流  无论怎么读都是从文件开始读起~!

        //        blk01: he
        //        blk02: llo msb 66231

        in.seek(1048576);
        //计算向数据移动后,期望的是分治,只读取自己关心(通过seek实现),同时,具备距离的概念(优先和本地的DN获取数据--框架的默认机制)
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
        System.out.println((char)in.readByte());
    }

    @After
    public void close() throws Exception {
        fs.close();
    }

}

bigdata-hadoop.zip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值