分布式结构:
由于分布在不同主机上的进程,协同工作,一起才能构成整个应用。
4V特征
Volumn:体量大,单个数据体量大,数据条数也是海量。
Velocity:数据快,数据时效性高,由于产生的数据基数大的原因,数据的截获,存储,操作必须要高速。
Variaty:样式多,可以存储多种类型的数据,包括结构化数据,例如表格,半结构化数据,例如日志、网址,和非结构化数据,例如图片、视频等。
Value:价值密度低,即单个数据并无意义,但是大量数据后才有一定价值。
固有特性:时效性、不可变性
Hadoop(相当于一个存数据的大硬盘)
可靠的、可伸缩的、分布式计算的开源软件。
是一个框架、允许跨越计算机集群的大数据集处理,使用简单的编程模型(MapReduce)。
可从单个服务器扩展到几千台主机,每个节点提供了计算和存储的功能。而不是依赖高可用性的机器
而是依赖于应用层面上的实现。
Hadoop 三核心模块
1.HDFS :分布式文件系统,解决大数据的存储。(包含:NameNode、DataNode、SecondNameNode)
2.Yarn :作业调度和资源管理框架,一种资源协调者。
3.MapReduce :基于yarn系统的大数据集并行处理技术,解决大数据的计算。(包括:ResourceManager、NodeManager)
4.Hadoop common: 工具支撑所有其他模块的工作。
1.HDFS特点:
优点:
支持处理超大文件
高容错性
文件流写入
缺点:
不适合低延时数据访问场景,不能立刻对新数据做出反应。
不适合小文件频繁存储场景,因为每次读取文件,都要判断其属性(例如容量)。
不适合并发写入,文件随机修改场景
2.HDFS角色
一个HDFS集群可包括多个Client,一个Active NameNode(默认有两个备用的Standby NameNode,当Active故障时,Standby切换为Active,旧Active自动转为Standby【本设置,2.0版本以后才出现,解决单点问题】),以及多个DataNode,和一个Secondary NameNode。
Client:客户端,将数据切分成数据块,向NameNode发送读写请求。
NameNode(NN):元数据节点,管理文件系统,主要功能是将数据交由DataNode存储,之后将数据的存储地址记录下来。
DataNode(DN):数据节点,数据存储节点,保存和检索Block。(物理节点,相当于就是一台计算机)
Secondary NameNode(SNN):辅助NameNode工作,间断性启动,主要功能是(由于数据量很大)将NameNode中的edits(多条数据)压缩到fsimage镜像文件中;SSN每次启动都会将NameNode中的edits(如果有fsimage,也一同复制过来)进行整理压缩,再传给NameNode以便NameNode对数据进行管理和操作。
3.HDFS的副本机制(其安全性高的原因)
存储在DataNode中的Block(数据块):
HDFS最基本的存储单元,(2.0以后,2.0之前为64M)默认大小为128M(可以更改);
***尽量不要产生大量的小文件,否则会撑坏NameNode;
解决方法:①将多个小文件组合成一个大文件(依赖一些软件)
②将小文件存在nosql数据库Hbase中
副本机制:
作用:避免数据丢失。
副本数默认为3,一个主副本,另个备用副本。
原理:DN每次存储,都会随机在同机架的不同节点选择一个备份点,该备份点又会随机在不同机架的某个节点进行备份,最后一个节点备份完以后,将地址传给上一个节点,上个节点备份完后,将地址(本节点和下一个节点)再次回传,直至将所有地址传给第一个节点,第一个节点备份完后,将所有地址传给NN进行目录记录。(默认备份点:本机架节点一个,同机架不同节点一个,不同机架一个)
4.HDFS读文件
1.Client打开DistributedFileSystem程序,新建对象;
2.DistributedFileSystem从NameNode中获取获取数据块的地址(根据数据的大小,对应会有多个节点地址);
3.Client新建并读取FSDataInputStream文件流对象;(一般应用字节流,一次一个字节,字符流一次读两个字节,会产生多读的问题)
4.FSDataInputStream通过地址读取对应地址DataNode中的数据;
5.读取多个地址对应的数据块,并汇总,反馈给Client;
6.读取完成,关闭读取文件流接口
5.HDFS写文件
1.Client 创建并启动DistributedFileSystem;
2.DistributedFileSystem 从 NameNode中获取可以执行写操作的DataNode地址,NameNode创建日志;
3.Client将数据写入FSDataOutputStream中,进行数据分割;
4.FSDataOutputStream将数据块写入DataNode中;多快并行写入;
5.DataNode将数据存储的地址(总共三个备份地址)返回给Client;多个备份并行执行,某一个不成功则该块备份全部重写;
6.Client关闭FSDataOutputStream,写入结束;
7.Client将各数据块的相应的地址集返回给NameNode,NameNode完成写入日志,并存入目录;
分布式计算框架
功能:将大型数据操作作业分解为可以跨服务器集群并行执行的单个任务。(分而治之)
Map(映射)和Reduce(归约)
1.MapReduce的特点
优点:
易于编程
可扩展性
高容错性
高吞吐量
不适合领域:
难以实时计算
不适合流式计算
2.MapReduce实现WordCount
1.基础原理:
Splitting:将一个完整的大容量Documents切分成一小段一小段(每段容量都为128MB),分配给各数据节点处理。
Map:各节点在内存中将一段数据分割成单词集生成键值对(单词为键,数量1为值),先不考虑重复,每个单词的数量都为1,最后将数据落盘。
Combine:各节点将单词的键值对汇总,凡是单词相同的(键相同),键值对的值就+1;从而将各单词的数量初步汇总。
Shuffle/Sort:各节点计算单词哈希值,将哈希值%节点数=>应存入的节点,(这里会出现重复单词的键值对)不考虑重复,节点容量超出,则将单词存入另外的新节点。
Reduce:将所有单词汇总,单词重复的键值对将值相加;最终得出各单词的键与值,从而实现单词的计数;
2.代码实现思想:
MapReduce拥有两个接口:Mapper 和 Reduce
=>实现两个接口的实际函数方法即可完成任务
mapreduce的执行过程:(MR框架软件流程)
Mapper => Combiner => Partitioner => Shuffle and Sort => Reducer
程序执行过程中数据格式的定义:(我简化了中间的部分)
map: (K1,V1) → list (K2,V2)
map函数接受的是一个键值对,键(K1)是文件名,值(V1)是文件的内容,map逐个遍历单词,每遇到一个单词(K2),就产生一个中间键值对
reduce: (K2,list(V2)) → list (K3,V3)
reduce函数接收的多个键值对(map的结果的聚合),键(K2)为单词,值是一串"1"(最基本的实现是这样,但可以优化),然后将这些“1”累加就得到单词K2的出现次数。最终将所有单词的键值对汇总成List。
代码实现:
(该环境必须有 hadoop 环境,如果未安装,可参考 windows下安装 hadoop 环境 )
每个过程都有自己对应的默认类;根据自己的需求重写相应的类方法即可;
重写Mapper=>
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* Created by HX on 2020/6/3
*
* @Description:数据分割
*/
public class MyMapper extends Mapper {
private LongWritable one = new LongWritable(1);
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String [] words = value.toString().split(" "); //按空格分割出单词
for (String word : words) {
Text wd = new Text(word);
context.write(wd,one); //写入键值对
}
}
}
重写Reducer=>
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* Created by HX on 2020/6/3
*
* @Description:数据键值对汇总
*/
public class MyReduce extends Reducer {
private LongWritable res = new LongWritable();
@Override
protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {
long ressume = 0;
for (LongWritable one : values) {
ressume += one.get();
}
res.set(ressume);
context.write(key,res);
}
}
Driver(必写,主驱动类)=>
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* Created by HX on 2020/6/4
*
* @Description:配置各类的数据类型
*/
public class MyDriver {
public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration();
//准备一个空任务
Job job = Job.getInstance(cfg, "wc");
//设置job任务的主启动类
job.setJarByClass(MyDriver.class);
//指定该任务的输入数据源
FileInputFormat.addInputPath(job,new Path("e://abc.txt"));
//设置你的Mapper任务类
job.setMapperClass(MyMapper.class);
//设置Mapper任务类的输出数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//设置reduce任务类
job.setReducerClass(MyReduce.class);
//设置reducer任务类的输出数据类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//设置任务的输出数据目录路径
FileOutputFormat.setOutputPath(job,new Path("e://eee"));
job.waitForCompletion(true);
}
}
功能:控制集群的资源管理及调度。
主要工作机制:
客户机Client提交启动信息任务(Job)给yarn的RM(ResourceManager),RM通过启动信息和Job查找出合适的DN(DateNode),该DN启动特殊的Container为AM(ApplicationMaster);AM拿到启动信息后,通过RPC协议向RM申请调度工作资源的信息及权限,AM获得所有信息后,将Job分割成各个的task并分配给相应的DN中的NM(NodeManager),NM启动其Container,Container启动其中的MapReduce程序执行相应的task,其中Reduce任务会向各节点拉取其task所需的资源;期间NM会监控Container的工作状态,并将心跳提供给AM和RM,一旦Container故障,NM会将其杀死并上传信息,以保证其他Container的正常工作;当task完成后,Container会将结果反馈给AM进行汇总,AM汇总完所有信息,会将最终结果提交给RM,并申请注销该Job,RM最后通知AM,AM则通知各NM杀死相应的Container,完成该Job。
ResourceManager(RM)
ResourceManager负责整个系统的资源分配和管理,是一个全局的资源管理器。主要由两个组件构成:调度器和应用管理器。它的功能较多,包括ApplicationMaster管理,NodeManager管理,Application管理,状态机管理等
调度器(Scheduler):调度器根据队列、容器等限制条件(每个队列配给 一定的资源,最多执行一定数量的作业等),将系统中的资源分配给各自正在运行的程序。调度器仅根据各个应用程序的资源需求进行资源分配,而资源分配单位用一个抽象的概念”资源容器“(Container)从而限定每个使用的资源量,容器用于执行的特定应用的进程每个容器都有所有资源限制(CPU 内存 等)一个容器可以是一个Unix进程也可以是一个Linux cgroup(Linux内核提升的一种限值,记录隔离进程并且使用的物理资源 CPU 内存 IO 等 谷歌提出)调度器相应应用程序的资源请求,是可插拔的,如Capcity Scheduler、Fair Scheduler。
应用程序管理器(Applications Manager):应用程序管理器负责管理整个系统的所有应用程序,包括应用程序提交,与调度器协商资源以启动ApplicationMaster、监控ApplicationMaster运行状态并在失败时重新启动等,追踪分给的Container的情况。
ApplicationMaster(AM)
ApplicationMaster是一个详细的框架库,它结合了ResourceManager获取资源和NodeManager协同工作来运行和监控任务,用户提交的每一个应用程序军包含一个AM,主要的功能是:
与ResourceManager调度器协商以获取抽象资源(Container);
负责应用的监控,追踪应用执行状态重启任务失败等。
与NodeManager协同工作完成Task的执行和监控。
MRappMaster是Mapreduce的ApplicationMaster实现,它是的Mapreduce应用程序可以直接在YARN平台之上,MRApplication负责Mappreduce应用的生命周期、作业管理资源申请再分配、container启动与释放、作业恢复等。其他的如计算框架如 Spark on YARN ,Storm on Yarn。如果需要可以自己写一个符合规范的YARN的应用模型。
NodeManager(NM)
NM是每个节点上的资源和任务管理器,他会定时地向RM汇报 本节点上地资源使用情况和各个Container地运行状态;同时会接受AM的Container启动/停止等请求。
Container
YARN 资源抽象 ,封存了某个节点是的多维度资源,如内存、CPU、磁盘、网络等。当AM向RM申请资源时,RM为AM返回资源是用Container表示的 。YARN为每一个任务分配给一个Container且该任务只能读取该Container中描述的资源。Container不同于MRv1的slot,他是一个动态划分单位,根据应用程序的需求动态生成的。