一、Hadoop框架
- Hadoop概述
Hadoop是一个apache组织开源的一个顶级项目,现在大数据技术的基石
Doug Cutting 仿照Google大数据领域的3篇论文开发Hadoop
GFS(Google File System) --> HDFS(Hadoop Distributed File System)
MapReduce --> MapReduce
BigTable – HBase
Hadoop组成
- Hadoop核心:Hadoop Common、HDFS、MapReduce、Yarn(Hadoop2.x);
- Hadoop生态圈:Hive、HBase、Zookeeper;
- Hadoop辅助工具:Flume、Sqoop、Hue、Oozie;
注意:
- HDFS不适合存储大量的小文件,会占用大量的namenode内存
- HDFS集群存储的文件,适用一次写入,多次操作的场景
-
Hadoop发行版
厂商 是否收费 实用性 Apache 免费 复杂,同时会有 Bug Cloudera(CDH) 4000美元(一个节点) 简单,修复 Apache 的 Bug 作者加入,CDH首席架构师 Hortonworks 12000美元(十个节点) 简单,修复 Apache 的 Bug 2020年和CDH合并 飞天(阿里) 阿里云 PAAS
- Hadoop核心架构分析
- 存储 (HDFS Hadoop Distributed File System)
- 操作 (MapReduce)
二、搭建Hadoop伪分布式集群
在通一台物理机器上启动
NameNode、DataNode、ResourceManager、NodeMagager
四大进程
- 准备工作
# 虚拟机:CentOS 6.x
# JDK1.8安装,上传并解压安装包,并配置环境变量
vi /root/.bashrc
export JAVA_HOME=
export PATH=$PATH:$JAVA_HOME/bin
# 关闭防火墙
service iptables stop
chkconfig iptables off
# 关闭selinux
vi /etc/selinux/config
SELINUX=disabled
# 设置主机名
vi /etc/sysconfig/network
HOSTNAME=hbase1.baizhi.com
# 主机映射
vi /etc/hosts
192.168.222.30 hadoop
# ssh免密登录
# 生成公私钥对
ssh-keygen -t rsa
# 复制公钥给远端机
ssh-copy-id hostname
- 安装
# 上传并解压安装包,并配置环境变量
vi /root/.bashrc
export HADOOP_HOME=
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
1. core-site.xml
位置:HADOOP_HOME/etc/hadoop/core-site.xml
<configuration>
<!--namenode访问入口-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hostname:9000</value>
</property>
<!--hdfs工作基础目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/hadoop-2.9.2/hadoop-${user.name}</value>
</property>
<!--垃圾箱时长-->
<property>
<name>fs.trash.interval</name>
<value>30</value>
</property>
</configuration>
2. hdfs-xite.xml
位置:HADOOP_HOME/etc/hadoop/hdfs-site.xml
<configuration>
<!--block副本因子-->
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<!--配置Sencondary namenode所在物理主机-->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>hostname:50090</value>
</property>
<!--设置datanode最大文件操作数-->
<property>
<name>dfs.datanode.max.xcievers</name>
<value>4096</value>
</property>
<!--设置datanode并行处理能力-->
<property>
<name>dfs.datanode.handler.count</name>
<value>6</value>
</property>
</configuration>
3. yarn-site.xml
位置:HADOOP_HOME/etc/hadoop/yarn-site.xml
<configuration>
<!--配置MapReduce计算框架的核心实现Shuffle-洗牌-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--配置资源管理器所在的目标主机-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hostname</value>
</property>
<!--关闭物理内存检查-->
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<!--关闭虚拟内存检查-->
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
</configuration>
4. mapred-site.xml
位置:HADOOP_HOME/etc/hadoop/mapred-site.xml
原文件为mapred-site.xml.template需要自己复制为mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
5. slaves
位置:HADOOP_HOME/etc/hadoop/slaves
hostname
6. 启动
位置:HADOOP_HOME
# 启动HDFS
# 第一次启动的时候需格式化namenode
bin/hdfs namenode -format
# 单节点启动 | 全部启动
sbin/hadoop-daemon.sh start namenode | start-dfs.sh
sbin/hadoop-daemon.sh start datanode
# 网页访问
hostname:50070
# 进程
SecondaryNameNode
DataNode
NameNode
# 启动Yarn
# 单节点启动 | 全部启动
sbin/yarn-daemon.sh start resourcemanager | start-yarn.sh
sbin/yarn-daemon.sh start nodemanager
# 网页访问
hostname:8088
# 进程
NodeManager
ResourceManager
- windows下配置Hadoop环境
- 解压Hadoop到任意目录
- 将winutil.exe和hadoop.dll拷贝到win下的hadoop的bin目录下面
- win下配置hadoop环境变量
- 在win下配置主机名和IP的映射关系
三、Hadoop使用注意
-
查看日志
- 日志位置 hadoop_home/logs 查看日志最后的信息,使用 tail -n 100 文件 重新构建集群或者调错时,可以删除原有logs文件内容,生成新的便于查找
-
NameNode格式化操作
只能做一次,如果做了多次,会导致namenode的clusterid与datanode的clusterid出现不匹配 如果想多次格式化,必须删除hadoop_home/data/tmp文件夹下全部内容 # hadoop_home/data/tmp 中的内容 dfs |- data 存放的是 datanode 中的块数据 |- name 存放的是namenode的持久化数据
-
Hadoop伪分布式的启停脚本
# 定义启停脚本,hadoop-start.sh hadoop-stop.sh #!/bin/bash sbin/hadoop-daemon.sh start namenode sbin/hadoop-daemon.sh start datanode sbin/yarn-daemon.sh start resourcemanager sbin/yarn-daemon.sh start nodemanager
#!/bin/bash sbin/hadoop-daemon.sh stop namenode sbin/hadoop-daemon.sh stop datanode sbin/yarn-daemon.sh stop resourcemanager sbin/yarn-daemon.sh stop nodemanager
修改执行权限
chmod 744 hadoop-start.sh
四、Hadoop相关配置文件
-
Hadoop核心的4大模块
Hadoop-Common # Hadoop底层封装的工具,不会直接使用 Hadoop-HDFS # Hadoop分布式文件存储 * 存储数据 Hadoop-yarn # Hadoop资源管理,任务监控,伴随着MapReduce进行应用 Hadoop-MapReduce # Hadoop MR运算模型 * 完成计算操作
-
Hadoop核心的配置文件
*-default.xml
配置文件 :配置的是 hadoop 4大模块中 所有的默认配置信息*-site.xml
配置文件:覆盖 *-default.xml 配置文件中需要修改的内容模块 *-default 优先级低 * site.xml 优先级高 java代码中设置 优先级更高 Hadoop-Common core-default.xml core-site.xml Configuration.set() Hadoop-HDFS hdfs-default.xml hdfs-site.xml Configuration.set() Hadoop-Yarn yarn-default.xml yarn-site.xml Configuration.set() Hadoop-MapReduce mapred-default.xml mapred-site.xml Configuration.set()
五、HDFS的使用
HDFS(Hadoop Distributed File System)的Client访问主要完成数据的存取以及查询等,例如:上传文件、创建文件、下载文件、删除文件、创建目录等
操作方式:shell 命令访问 || java 代码访问
- shell命令访问
bin/hdfs dfs -命令
# hdfs的目录结构是从 / 开始
# 查看目录结构
bin/hdfs dfs -ls 目录
# 创建目录
bin/hdfs dfs -mkdir -p 目录
# 上传文件,所上传的⽂件内容以块的形式存储,既存储了块的数据,同时也存储了块的指纹,存储的位置是HADOOP_HOME/data/tmp/dfs/data/current/BP-1426933542-10.211.55.12-1582563664584/current/finalized
bin/hdfs dfs -put localhost_path hdfs_path # localhost是指linix系统
# 下载文件
bin/hdfs dfs -get hdfs_path local_path
#查看hdfs上文件的内容
bin/hdfs dfs -test
bin/hdfs dfs -cat
# mv cp rm
#修改DataNode存储数据的物理位置
hdfs-site.xml
<property>
<name>dfs.datanode.data.dir v</name>
<value>/root/dfs/data</value>
</property>
#修改垃圾箱的保存时间
core-site.xml
<property>
<name>fs.trash.interval</name>
<value>10</value>
</property>
#垃圾箱位置
/user/root/.Trash/xxx时间戳/删除的文件
- java代码进行访问
- Configuration 对配置信息的封装
- FileSystem 对HDFS分布式操作系统的封装 open() creat()
- Path 对HDFS路径的封装
1. 依赖
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.5.2</version>
</dependency>
2. 打开HDFS的访问权限
-
方案1
通过System.setProperty设置用户名为root
System.setProperty("HADOOP_USER_NAME","root");
-
方案2
在IDEA中
Edit Configurations
配置VM options
程序启动的时候传入对应的参数-DHADOOP_USER_NAME=root
-
方案3
将权限检查机制关闭
配置 hdfs-site.xml
<property> <name>dfs.permissions.enabled</name> <value>false</value> </property>
3. 代码
public class HDFSUtils {
private static FileSystem fileSystem;
static{
try {
Configuration configuraton = new Configuration();
configuraton.set("fs.default.name", "hdfs://10.211.55.12:8020");
fileSystem = FileSystem.get(configuraton);
} catch (IOException e) {
e.printStackTrace();
}
}
public static FileSystem getFileSystem(){
return fileSystem;
}
}
public class TestHDFS {
@Test
public void test1() throws IOException {
FileSystem fileSystem = HDFSUtils.getFileSystem();
FSDataInputStream inputStream = fileSystem.open(new Path("/data/suns"));
IOUtils.copyBytes(inputStream, System.out, 1024, true);
}
@Test
public void test2() throws Exception{
FileSystem fileSystem = HDFSUtils.getFileSystem();
//hdfs中创建目录的
//fileSystem.mkdirs(new Path("/xiaohei"));
fileSystem.mkdirs(new Path("/xiaojr/xiaowb"));
//删除文件
fileSystem.delete(new Path(""),true);
//判断一个文件是否存在
fileSystem.exists(new Path(""));
//判断这个路径是不是文件
fileSystem.isFile(new Path(""));
//判断这个路径是不是文件夹
fileSystem.isDirectory(new Path(""));
//把当前的路径中所有的文件 显示 ,后面参数 是否递归
RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator =
fileSystem.listFiles(new Path(""), true);
while(locatedFileStatusRemoteIterator.hasNext()){
}
}
@Test
public void test3()throws Exception{
FileSystem fileSystem = HDFSUtils.getFileSystem();
FSDataInputStream inputStream = fileSystem.open(new Path("/data/suns"));
FileOutputStream fileOutputStream = new FileOutputStream("/Users/test");
IOUtils.copyBytes(inputStream, fileOutputStream, 1024, true);
}
@Test
public void test4()throws Exception{
FileSystem fileSystem = HDFSUtils.getFileSystem();
FileInputStream fileInputStream = new FileInputStream("/Users/test");
FSDataOutputStream outputStream = fileSystem.create(new Path("/xi/su"));
IOUtils.copyBytes(fileInputStream, outputStream, 1024, true);
}
}
六、HDFS架构
HDFS是一种能够运行在商业硬件上的分布式文件系统,与目前的市面上的文件系统有很多相似之处,但又是不同的软件系统。HDFS 中,使用的架构是主从架构(Active|Standby),针对的是实现NameNode的高可用。
- NameNode
管理文件系统的命名空间和控制外界客户端对文件系统的访问;
存储元数据(用于描述数据的数据,比如块到DataNode的映射的数据),负责管理DataNode
- DataNode
负责管理在每一个节点上存储的文件;
用于存储块数据的节点,负责响应客户端对块的读写请求,向NameNode 汇报块信息。
- SecondaryNameNode
是Namenode 的帮手(秘书|小弟),具体帮NN做什么 后面详解;
NameNode 集群中主节点 内存 | DataNode 硬盘 |
---|---|
1.维护了全局的树状结构 | 1. 块形式存储数据 128M |
2.记录了文件的基本信息 | 2. 副本3个 机架感知 |
3.存储了块数据与DataNode的关系 | 3. 校验和 |
- 块(block)
HDFS中对文件拆分的最小单元,Hadoop2.x以后默认大小为128MB,副本因子为3
<!-- 块数据的默认拆分大小 -->
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
<description>
The default block size for new files, in bytes.
You can use the following suffix (case insensitive):
k(kilo), m(mega), g(giga), t(tera), p(peta), e(exa) to specify the size (such as 128k, 512m, 1g, etc.),
Or provide complete size in bytes (such as 134217728 for 128 MB).
</description>
</property>
<!-- 块数据的默认副本因子 -->
<property>
<name>dfs.replication</name>
<value>3</value>
<description>Default block replication.
The actual number of replications can be specified when the file is created.
The default is used if replication is not specified in create time.
</description>
</property>
- SecondaryNameNode
主要有两个任务:
- 定期合并FSImage和EditsLog
合并时机:(1) 默认每一小时合并一次;(2) 100万事务数(每分钟检查一次);
- 部分还原namenode数据
在namenode进程出现问题,同时FSImage和EditsLog硬盘出现问题后,SecondaryNameNode可以部分还原NameNode数据;
-
FSImage、EditsLog
-
FSImage 文件系统镜像
某一个时刻前,NameNode元数据的镜像备份;
默认存储位置:
dfs.namenode.name.dir
file://${hadoop.tmp.dir}/dfs/name
-
EditsLog 可编辑日志
某一时刻后,用户对NameNode进行的增加和更新操作信息
默认存储位置:
dfs.namenode.edits.dir
${dfs.namenode.name.dir}
设置
FSImage, EditsLog
的存储位置 ,在hdfs-site.xml
配置文件中进行修改<property> <name>dfs.namenode.name.dir</name> <value>file:///xxx/xxxx</value> </property> <property> <name>dfs.namenode.edits.dir</name> <value>file:///xxx/xxxx</value> </property>
-
- 检查点 (CheckPoint)
检查点机制决定NameNode启动后
FSImage
和EditsLog
文件合并的时机
相关配置
-
SecondaryNameNode 每隔一小时执行一次
<property> <name>dfs.namenode.checkpoint.period</name> <value>3600</value> <description>The number of seconds between two periodic checkpoints. </description> </property>
-
一分钟检查一次操作数 当操作数达到100W 的时候 SecondaryNameNode执行一次
<property> <name>dfs.namenode.checkpoint.txns</name> <value>1000000</value> <description>操作动作次数 </description> </property> <property> <name>dfs.namenode.checkpoint.check.period</name> <value>60</value> <description>一分钟检查一次操作数 </description> </property>
- 安全模式 (SafeMode)
每一次重新启动NameNode时,HDFS会进行FSImage和EditsLog的合并,此时通过安全模式,保证client只能进行读操作,避免namenode持久化数据不一致的情况发生,当合并完成后,安全模式会自动退出
# 手工进行安全模式 操作的方法
# 手工进入安全模式
bin/hdfs dfsadmin -safemode enter
# 手工关闭安全模式
bin/hdfs dfsadmin -safemode leave
# 查看当前安全模式的状态
bin/hdfs dfsadmin -safemode get
- 机架感知(RACK Aware)
使用机架对存储节点进行物理编排,用于优化存储和计算
-
PC Server (CPU架构组成Intel X86)种类
- 塔式服务器(台式机)__目前用的比较少了
- 机架式服务器
- 刀片机
-
DataNode在机架中的存储方式
当副本因子为3时,第一个副本存在本地机架上,第二个副本本地机架上另外一个节点上,第三个存储在处本地机架以外的节点上。
七、HDFS 热扩容和热删除
在不影响hdfs正常运行的情况下,进行扩容和删除
- 热扩容
-
环境准备
- 创建新的DataNode服务器 - 网络环境准备,防火墙,主机名,主机映射,ssh免密登录 - 完成hadoop的相关配置,与现有集群保持一致
-
在新节点启动
datanode
进程sbin/hadoop-daemon.sh start datanode
-
进行负载均衡处理
# 新加入的节点中没有文件,会出现散步不均匀,所以要进行负载均衡 # 在namenode节点中执行 sbin/start-balancer.sh
-
后续维护
集群中的每一个节点slaves、hosts文件内容都需要同步
-
备注:datanodes显示不全,解决办法
<!-- hdfs-site.xml 添加以下配置 --> <property> <name>dfs.namenode.datanode.registration.ip-hostname-check</name> <value>false</value> </property>
- 热删除
-
创建文件,标识要删除的主机名,文件名字和文件位置自定义
- 文件名 host.exclusion - 内容:要删除的节点的主机名
-
hdfs-site.xml
配置文件,添加下列配置<property> <name>dfs.hosts.exclude</name> <value>/root/host.exclusion</value> </property>
-
在NameNode节点进行集群节点的刷新以及节点块数据的重新分配
bin/hdfs dfsadmin -refreshNodes
-
关闭已经下线的dataNode进程
-
hdfs-site.xml配置文件删除以下配置
<property> <name>dfs.hosts.exclude</name> <value>/root/host.exclusion</value> </property>