我的故事你说,我的文字我落,我值几两你定,我去何方我挑。
HDFS:解决海量数据的分布式存储的问题
MapReduce:解决海量数据的分布式计算的问题
YARN:解决分布式计算程序的资源分配以及任务监控问题 Mesos: 分布式资源管理系统(YARN的替代品)
flume、sqoop、hive、spark。。。。
5.2~5.4:需要进行配置文件的修改九个配置文件
分布式文件存储系统,所谓的分布式采用一些架构和一些组件将多台节点的存储资源当作一个整体进行海量资源的存储
辅助namenode完成edits编辑日志和fsimage镜像文件的合并操作
负责和HDFS集群进行通信实现文件的增删改查
负责进行block块的分割
HDFS的命令行操作 hdfs dfs | hadoop fs
HDFS的Java API操作 Configuration FileSystem
hadoop-client hadoop-hdfs
数据上传的时候,会根据配置进行block块的备份,备份的时候,选择哪些节点进行数据备份? 机架感知原则进行备份
客户端在和DN建立连接的时候,是和距离它最近的某一个DN建立连接怎么判断DN距离客户端的距离:网络拓扑原则客户端和HDFS的节点在同一个集群上
NameNode的第二个工作机制原理:元数据管理的原理 (NN和SNN的联合工作机制)
元数据:指的是HDFS存储文件/文件夹的类似的目录结构,目录中记录着每一个文件的大小、时间、每一个文件的block块的份数,block块存储的节点列表信息… NameNode默认的元数据内存是1000M,可以存储管理百万个block块的元数据信息
edits编辑日志文件:记录客户端对HDFS集群的写入和修改操作
fsimage镜像文件:理解为HDFS元数据的持久点检查文件
2~3:再次启动HDFS之后恢复元数据的机制
HDFS的安全模式(safemode)
SNN的作用就是对NN进行checkpoint操作
dfs.namenode.checkpoint.period 3600s
dfs.namenode.checkpoint.txns 1000000
dfs.namenode.checkpoint.check.period 60s
NameNode的出现故障之后,元数据的恢复方式
因为元数据的核心是edits和fsimage文件,同时snn工作的时候会把nn的文件复制到snn当中,因此如果NN的元数据丢失,我们可以从SNN中把这些文件再复制到NN的目录下 进行元数据的恢复(恢复可能会导致一部分的元数据丢失)
SNN的目录:${hadoop.tmp.dir}/dfs/namesecondary/curren
nn的目录:${hadoop.tmp.dir}/dfs/name/current
元数据还有一种恢复方式:配置HDFS的namenode的多目录保存(HDFS的编辑日志和镜像文件在多个目录下保存相同的备份) 方式只能使用在同一个节点上 问题:如果整个节点宕机,无法恢复了 dfs.namenode.name.dir
多个路径 最好把HDFS重新格式化一下,或者手动把目录创建一份
HA高可用模式
NameNode的第二个工作机制原理:NameNode管理整个HDFS集群的原理 (NN和DN的联合工作机制)
DataNode上存储的block块除了数据本身以外,还包含数据的长度、数据校验和、时间戳…
数据校验和是为了保证block块的完整性和一致性的,校验和机制,创建block块的时候会根据数据本身计算一个校验和,以后每一次DN进行block汇总的时候会再进行一次校验和的计算,如果两次校验和不一致 认为block块损坏了。
DataNode和NameNode心跳,默认三秒心跳一次,默认值可以调整 dfs.heartbeat.interval 3s 关闭HDFS,但是不需要重新格式化 心跳的作用有两个:1、检测DN是否或者 2、把NN让DN做的事情告诉DN
NN如何知道DN掉线-死亡-宕机了(掉线的时限):NN如果在某一次心跳中没有收到DN的心跳,NN不会认为DN死亡了,而是会继续心跳,如果超过掉线的时限的时间还没有心跳成功,NN才会认为DN死亡了,然后启动备份恢复机制 掉线时限的时长是有一个计算公式: timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval
dfs.namenode.heartbeat.recheck-interval
心跳检测时间 5分钟 dfs.heartbeat.interval
心跳时间 3s
默认情况下,如果超过10分30S没有收到DN的心跳 认为DN死亡了
DataNode每隔一段时间(默认6小时)会向NameNode汇报一次节点上所有的block块的信息 dfs.blockreport.intervalMsec 21600000ms
每隔6小时向NN汇报一次DN的block块的信息 dfs.datanode.directoryscan.interval 21600s
每隔6小时DN自己扫描一下DN上的block块信息
概念:HDFS是一个分布式文件存储系统,HDFS身为一个大数据软件,基本上都是7*24小时不停机的,那如果HDFS集群的容量不够用了,那么我们需要增加一个新的数据节点,因为HDFS不能停止,因此我们需要在HDFS集群运行过程中动态的增加一个数据节点(新节点的服役操作);旧节点的退役。
服役新节点之前,需要创建一台新的虚拟节点,并且配置Java、Hadoop环境、SSH免密登录、ip、主机映射、主机名
dfs.hosts 值:文件的路径
hdfs dfsadmin -refreshNodes yarn rmadmin -refreshNodes
在Hadoop的配置目录创建一个文件dfs.hosts.exclude,文件中编写退役的主机名
在Hadoop的hdfs-site.xml配置文件中声明退役的节点文件 dfs.hosts.exclude 值 文件的路径
同时需要在服役节点文件中把退役节点删除了dfs.hosts
刷新节点信息状态 hdfs dfsadmin -refreshNodes yarn rmadmin -refreshNodes
**【注意】**退役的时候,会先把退役节点的block块复制到没有退役的节点上,然后才会下线,而且退役的时候,必须保证退役之后剩余集群的节点数大于等于副本数
6.5.1~6.5.2在namenode所在节点的hadoop中配置
现在有一个文件,文件很大,文件中存储的每一行数据都是由空格分割的多个单词组成的,现在需要通过大数据分布式计算技术去统计文件中每一个单词出现的总次数
hadoop-client
package com.sxuek.wc;
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;
import java.io.IOException;
/**
* Driver驱动程序说白了就是封装MR程序的
* Driver驱动程序其实就是一个main函数
*/
public class WCDriver {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
//1、准备一个配置文件对象Configuration
Configuration configuration = new Configuration();
//指定HDFS的地址
configuration.set("fs.defaultFS","hdfs://192.168.68.101:9000");
//2、创建封装MR程序使用一个Job对象
Job job = Job.getInstance(configuration);
//3、封装处理的文件路径hdfs://single:9000/wc.txt
FileInputFormat.setInputPaths(job,new Path("/wc.txt"));
//4、封装MR程序的Mapper阶段 还要封装Mapper阶段输出的key-value类型
job.setMapperClass(WCMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//5、封装MR程序的reduce阶段 还需要封装reduce的输出kv类型
job.setReducerClass(WCReducer.class);
job.setOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
job.setNumReduceTasks(1);//指定reduce阶段只有一个ReduceTask
//6、封装MR程序的输出路径---输出路径一定不能存在 如果存在会报错
FileOutputFormat.setOutputPath(job,new Path("/wcoutput"));
//7、提交运行MR程序
boolean flag = job.waitForCompletion(true);
System.exit(flag?0:1);
}
}
package com.sxuek.wc;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* 单词技术的MapTask的计算逻辑
* 1、继承Mapper类,同时需要指定四个泛型 两两一组 分别代表输入的key value 和输出的key value的数据类型
* 默认情况下,map阶段读取文件数据是以每一行的偏移量为key 整数类型 每一行的数据为value读取的 字符串类型
* LongWritable Text
* map阶段输出以单词为key 字符串 以1为value输出 整数
* 数据类型不能使用Java中数据类型,数据类型必须是Hadoop的一种序列化类型
* Int---hadoop.io.IntWritable
* Long-hadoop.io.LongWritable
* String--hadoop.io.Text
* 2、重写map方法
*
*
*/
public class WCMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
/**
* map方法是MapTask的核心计算逻辑方法
* map方法是切片中一行数据调用一次
* @param key 这一行数据的偏移量
* @param value 这一行数据
* @param context 上下文对象 用于输出map阶段处理完成的keyvalue数据
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context) throws IOException, InterruptedException {
//拿到一行数据 并且将一行数据转成字符串类型
String line = value.toString();
//字符串以空格切割得到一个数组,数组中存放的就是一行的多个单词
String[] words = line.split(" ");
//遍历数组 得到每一个单词 以单词为key 以1为value输出数据即可
for (String word : words) {
context.write(new Text(word),new LongWritable(1L));
}
}
}
package com.sxuek.wc;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* Reducer的编程逻辑:
* 1、继承Reducer类,指定输入和输出的kv类型
* 输入KV就是Map阶段的输出KV Text LongWritable
* 输出kv Text LongWritable
* 2、重写reduce方法
*/
public class WCReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
/**
* Reduce方法是Reduce阶段的核心计算逻辑
* reduce方法是一组相同的key执行一次
* @param key 一组相同的key 某一个单词
* @param values 是一个集合,集合存放的就是这一个单词的所有的value值
* @param context 上下文对象 用于reduce阶段输出数据
* @throws IOException
* @throws InterruptedException
*/
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException {
//只需要将某一个单词聚合起来的value数据累加起来 得到总次数
long sum = 0L;
for (LongWritable value : values) {
sum += value.get();
}
//只需要以单词为key 以sum为value输出即可
context.write(key,new LongWritable(sum));
}
}