hadoop学习笔记

14 篇文章 0 订阅
6 篇文章 0 订阅

hadoop文件

 

 

namenode: 存储元数据, 被分块保存的数据的信息,如大小,位置
datanode: 存储被分块的数据, path->hadoop/data/dfs/data(本地的实际地址)
​
hadoop会建立一个虚拟的文件目录工客户端访问(hdfs://ip:9000/)

HDFS实现思想

1. hdfs是通过分布式集群来存储文件, 为客户端提供了一个便捷的访问方式,就是一个虚拟的目录结构
2. 文件存储到hdfs集群中去的时候是被切分成block的
3. 文件的block存放在若干台datanode节点上
4. hdfs文件系统中的文件与真实的block之间有映射关系, 由namenode管理
5. 每一个block在集群中会存储多个副本,以提高数据的可靠性与访问的吞吐量

 

hadoop的namenode

1. 客户端上传文件时, NN首先往edits.log文件记录元数据操作日志
2. 客户端开始上传文件,完成后返回成功的信息给NN, NN就在内存中写入上传的元数据
3. 再往fsimage(元数据的持久化地方)里写入, 当edits.log写满时/到达一定时间(默认3600s). SecondaryNameNode负责这部分操作.
​
元数据地址: /usr/hadoop/tmp/dfs/name/current

HadoopAPI

RPC远程通讯, 利用远程通讯调用hadoop原生的方法,拿到返回结果(通过fs)
hadoop里的通讯走RPC
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(conf);
​
Path src = new Path('hdfs"//master:9000/test.txt'); /*hadoop文件地址*/
FSDataInputStream io = fs.open(src);
FileOutputStream os = new FileOutputStream('/localpath');
IOUtils.copy(in, os);
FileSystem fs = null;
​
public void init() throws Exception{
    //读取classpath下的xxx.site.xml配置文件,并解析其内容,封装到conf对象中 
    Configuration conf = new Configuration();
    // 也可以在代码中对conf中的配置信息进行手动设置,会覆盖配置文件中读取的值
    conf.set("fs.defaultFS", 'hdfs://master:9000/');
    fs = FileSystem.get(new URi('hdfs://master:9000/'), conf, 'hadoop') /*指定登录user, 与集群进行通讯*/
}
fs.copyFromlocalFile(new Path(''), new Path('hdfs://master:9000/')) /*传入本地路径, 目标路径*/

 

MapReduce

mapper->对数据进行切片,计算,返回{k:v}({词: 1})格式
​
reduce->对map的结果, 统计key的数量
​
Mapper: 处理具体文本,发送结果
Reducer: 合并各个Mapper发送过来的结果
Job: 制定相关配置,框架,[将相同的mapper结果发送到同一个reduce上处理,或依照逻辑不同志发送到一个reduce处理]
​
​
mapreduce的程序可以在任何地方运行,它只是一种统计逻辑,文件的读写可以在任何地方

mapper实现

package cn.itcast.hadoop.mr.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.util.StringUtils;
// <LongWritable, Text, Text, LongWritable> 4个泛型中,前两个是指定mapper输入数据的类型,这是hadoop自定义的序列化数据类型,便于传输
// map和 reducer的输入和输出都是key-value对的形式
public class WCMapper extends Mapper <LongWritable, Text, Text, LongWritable> {
    // 每读一次数据,就调一次这个方法
    // 默认情况下。框架输入的我们mapper的输入数据中,key是要处理的文本中的一行的起始偏移量, 内容就是value
    @Override
    protected void map(LongWritable key, Text value,  Context context) throws IOException, InterruptedException{
        //具体业务逻辑就像和在这里, 传入数据就是  key, value
        //将这一行的内容转化成string类型
        String line = value.toString();
        // 对这一行的文本按特定分隔符切分
        String[] words = StringUtils.split(line, ' ');
        // 遍历这个单词数组, 输出为kv形式   k:单词  v:1
        for (String word : words) {
        //hadoop的输出类型
            context.write(new Text(word), new LongWritable(1));}}} 

reduce实现

package cn.itcast.hadoop.mr.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WCReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
    //框架在map处理后,将所有kv缓存起来,进行分组,然后传递一个组<key,vakue>,调用一次reduce方法
    //参数<word, {1,1,1,1,1,.....}> 经过shuffle后的键值
    @Override
    protected void reduce(Text Key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
        long count = 0;
        for (LongWritable value:values) {
            count += value.get(); //拿到LongWritable的值
        }
        context.write(Key, new LongWritable(count));}}

job实现

job用于描述一个特定的作业,比如作业使用哪一个map,reduce. 还可以指定该作业要处理的数据所在的路径, 作业的输出的结果放到哪个路径下.
package cn.itcast.hadoop.mr.wordcount;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.io.Text;
//import com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider.Text;
public class WCRunner {
    public static void main(String[] args) throws Exception{
        Configuration conf = new Configuration();
        Job wcJob = Job.getInstance(conf);//获取Job类
        //设置整个job所有的哪些类在哪个jar包
        wcJob.setJarByClass(WCRunner.class);
        //本job使用的mapper和reducer类
        wcJob.setMapperClass(WCMapper.class);
        wcJob.setReducerClass(WCReducer.class);
        // 指定reduce的输出数据kv类型
        wcJob.setOutputKeyClass(Text.class);
        wcJob.setOutputValueClass(LongWritable.class);
        // 指定mapper的输出数据kv类型
        wcJob.setMapOutputKeyClass(Text.class);
        wcJob.setMapOutputValueClass(LongWritable.class);
        //指定要处理的输入数据存放路径(文件所在文件夹)
        FileInputFormat.setInputPaths(wcJob, new Path("/wc/srcdata/"));
        //指定处理结果的输出数据存放路径
        FileOutputFormat.setOutputPath(wcJob, new Path("/wc/output"));
        //将job提交给集群运行, 并指定在控制台打印过程
        wcJob.waitForCompletion(true);}}

Yarn, 资源调度

 

​ Yarn工作流程

1. wcJob.waitforCompleition启动一个RunJar进程,这个进程向RM申请执行一个Job
2. RM 返回一个Job相关资源的路径staging-dir,和为Job产生的jobID
3. RunJar提交资源到 HDFS的 staging-dir 上
4. RunJar提交资源完毕之后,上报RM 提交资源完毕
5. RM下个Job加入RM中的任务队列中
6. 各个Node Manager通过通信,从RM的任务队列中领取任务
7. 各个Node Manager初始化运行资源的容器,从staging-dir上面拉取资源
8. RM选择一个Node Manager 启动MRAppMaster 来运行map reducer
9. MRAppMaster向RM注册
10. MRAppMaster启动Mapper任务
11. MRAppMaster启动Reducer任9务
12. 任务完成后,向RM注销自己

实现hadoop的序列化接口

在map的时候, 传递自定义数据类型, 需要实现hadoop相应的序列化接口

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值