Hadoop基本原理及Map-Reduce体系

1. 分布式文件系统HDFS

1.1 测试安装好的hadoop集群

  • 1.在hadoop的同级目录input中创建两个文件
  • 2.将两个文件拷贝到hadoop目录下的in目录(注意这个in目录不是linux实际目录)
bin/hadoop dfs -put ../input in
  • 3.查看这两个文件
bin/hadoop dfs -ls ./in/*  
  • 4.提交运行作业
bin/hadoop jar hadoop-0.x.x-examples.jar wordcount in out

其中hadoop-0.x.x-examples.jar为源码中的样例,wordcount表示该jar包中的某一项功能,in输入目录,out输出目录

  • 列出相应的目录
    in和out
bin/hadoop dfs -ls
  • 查看out中的计算结果
bin/hadoop dfs -cat ./out/*

1.2 通过web了解Hadoop的活动

  • 通过浏览器和http访问jobtracker所在节点xxxxx端口监控jobtracker
    可以查看作业运行日志,使用的节点等
  • 通过浏览器和http访问namenode所在节点的xxxx端口监控集群

1.3 数据写在哪(从os角度看)

  • 配置文件中定义了文件的存放位置
  • 数据+元数据(xx.meta)

1.4 HDFS设计的基础和目标

  • 硬件错误是常态。因此需要冗余。
  • 流式数据访问。即数据批量读取而非随机读取,Hadoop擅长做数据分析而不是事务处理
  • 大规模数据集
  • 简单一致模型。为了降低系统复杂度,对文件采用一次性写多次读的逻辑设计,即文件一经写入,关闭,就再也不能修改
  • 程序采用“数据就近”原则分配节点执行

1.5 HDFS体系结构

  • NameNode
  • DataNode
  • 事务日志
  • 映像文件
  • SecondaryNameNode

1.5.1 NameNode

  • 管理文件系统的命名空间
  • 记录每个文件数据块在各个Datanode上的位置和副本信息
  • 协调客户端对文件的访问
  • 记录命名空间内的改动或空间本身属性的改动
  • Namenode使用事务日志记录HDFS元数据的变化。使用映像文件存储文件系统的命名空间,包括文件映射,文件属性等。
    找到元数据保存的地方(注意:同级目录下有一些其他目录)
    current目录下fsimage即映象文件

1.5.2 Datanode

  • 负责所在物理节点的存储管理
  • 一次写入,多次读取(不修改)
  • 文件由数据块组成,典型的块大小是64MB
  • 数据块尽量散步到各个节点

1.5.3 读取数据的流程

  • 客户端要访问HDFS中的一个文件
  • 首先从namenode获得组成这个文件的数据块位置列表
  • 根据列表知道存储数据块的datanode
  • 访问datanode获取数据
  • Namenode并不参与数据实际传输

1.6 HDFS的可靠性

  • 1.冗余副本策略
    • 可以在hdfs-site.xml中设置复制因子指定副本数量
    • 所有数据块都有副本
    • Datanode启动时,遍历本地文件系统,产生一份hdfs数据块和本地文件的对应关系列表(blockreport)汇报给namenode
  • 2.机架策略
    • 集群一般是放在不同的机架上,机架间的带宽要比机架内带宽要小
    • HDFS的“机架感知”
    • 一般在本机架存放一个副本,在其他机架再存放别的副本,这样可以防止机架失效时丢失数据,可以提高带宽利用率
  • 3.心跳机制
    • Namenode周期性从datanode接收心跳信号和块报告
    • Namenode根据块报告验证元数据
    • 没有按时发送心跳的datanode会被标记为宕机,不会再给它任何I/O请求
    • 如果datanode失效造成副本数量下降,并且低于预先设置的阈值,namenode会检测出这些数据块,并在合适的时机进行重新复制
    • 引发重新复制的原因还包括数据副本本身损坏,磁盘错误,复制因子被增大等。
  • 4.安全模式
    • Namenode启动时会先经过一个“安全模式”阶段
    • 安全模式阶段不会产生数据写
    • 在此阶段Namenode收集各个datanode的报告,当数据块达到最小副本数以上时,会被认为是“安全”的
    • 在一定比例(可设置)的数据块被确定为“安全”后,再过若干时间,安全模式结束
    • 当检测到副本数不足的数据块时,该块会被复制到达最小副本数。
  • 5.校验和
    • 在文件创立时,每个数据块都产生校验和
    • 校验和会作为单独一个隐藏文件保存在命名空间下
    • 客户端获取数据时可以检查校验和是否相同,从而发现数据块是否损坏
    • 如果正在读取的数据块损坏,则可以继续读取其它副本。
  • 6.回收站
    • 删除文件时,其实是放入回收站/trash
    • 回收站里的文件可以快速恢复
    • 可以设置一个时间阈值,当回收站里文件的存放时间超过这个阈值,就被彻底删除,并且释放占用的数据块。
  • 7.元数据保护
    • 映像文件刚和事务日志是Namenode的核心数据。可以配置为拥有多个副本
    • 副本会降低Namenode的处理速度,但增加安全性
    • Namenode依然是单点,如果发生故障要手工切换
  • 8.快照机制
    • 支持存储某个时间点的映像,需要时可以使数据重返这个时间点的状态

1.7 HDFS文件操作

  • 命令行方式
  • API方式

1.7.1 列出HDFS下的文件

  • 注意,hadoop没有当前目录的概念,也没有cd命令
bin/hadoop dfs -ls

假设列出的目录有in目录,再去查看in目录
bin/hadoop dfs -ls ./in

1.7.2 上传文件到HDFS

bin/hadoop dfs -put ../abc abc
前面一个文件在本地的位置(采用linux风格的目录),后一个表示hadoop中的文件

上传文件后,使用bin/hadoop dfs -ls 查看,可以看到hadoop中的abc文件夹

1.7.3 将HDFS的文件复制到本地

bin/hadoop dfs -get abc ./xyz
将abc文件拷贝到当前目录下的xyz文件中

1.7.4 删除HDFS下的文档

bin/hadoop dfs -rmr abc

1.7.5 查看HDFS基本统计信息

bin/hadoop dfsadmin -report

1.7.6 查看hdfs文件夹大小

hadoop fs -du -s -h /user/hive/warehouse/ods.db

1.7.7 进入和退出安全模式

  • 进入安全模式
bin/hadoop dfsadmin -safemode enter
  • 退出安全模式
bin/hadoop dfsadmin -safemode leave 

1.8 其他一些操作

1.8.1 怎样添加节点?

  • 在新节点安装好hadoop
  • 把namenode的有关配置文件复制到该节点
  • 修改masters和slaves文件,增加该节点
  • 设置ssh免密码进出该节点
  • 单独启动该节点上的datanode和tasktracker(hadoop-daemoon.sh start datanode/tasktracker)
  • 运行start-balancer.sh进行数据负载均衡

1.8.2 启动某些特定后台进程而非所有后台进程

  • 观察Start-all.sh脚本的内容,其实就是分别启动各个脚本-对应特定的后台进程

1.8.3 负载均衡

  • 作用:当节点出现故障,或新增节点时,数据块分布可能不均匀,负载均衡可以重新平衡各个datanode上数据块的分布

1.9 Hadoop API

  • 上传本地文件到HDFS
import org.apache.hadoop.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import  org.apache.hadoop.fs.Path;

public class CopyFile{
    
    public static void main(String[] args) throws Exception{
        Configuration conf=new Configuration();
        //conf.addResources(new Path("conf/hadoop-default.xml"));
        //conf.addResources(new Path("conf/hadoop-site.xml"));
        FileSystem hdfs=FileSystem.get(conf);
        Path src=new Path("xxx.txt");
        Path dst=new Path("/");
        hdfs.copFormLocalFile(src,dst);
        for(FileStatus file:files){
            System.out.println(file.getPath());
        }
    }
}
  • 创建HDFS文件
import org.apache.hadoop.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import  org.apache.hadoop.fs.Path;

public class CreateFile{
    public static void main(String[] args)throws Exception{
        Configuration conf=new Configuration();
        bte[] buff="hello word!".getBytes();
        FileSystem hdfs=FileSystem.get(conf);
        Path dfs=new Path("/test");
        FSDataOutputStream outputstream=hdfs.create(dfs);
        outputStream.write(buff,0,buff.length);
    }
}
  • 重命名HDFS文件
import org.apache.hadoop.Configuration;
import org.apache.hadoop.fs.FileSystem;
import  org.apache.hadoop.fs.Path;

public class Rename{
    public static void main(String[] args)throws Exception{
        Configuration conf=new Configuration();
        FileSystem hdfs=FileSystem.get(conf);
        Path frpath=new Path("/test");
        Path topath=new Path("/test1");
        boolean isRename=hdfs.rename(frpath,topath); 
    }
}
  • 查看HDFS文件的最后修改时间
import org.apache.hadoop.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import  org.apache.hadoop.fs.Path;

public class GetLTime{
    public void main(String[] args) throws Exception{
        Configuration conf=new Configuration();
        FileSystem hdfs=FileSystem.get(conf);
        Path fpath=new Path("/test1");
        FileStatus fileStatus=hdfs.getFileStatus(fpath);
        long modificationTime=fileStatus.getModificationTime();
        System.out.println("Modification times:"+modificationTime);
    }
}

2. Map-Reduce体系架构与实战

2.1 Map-Reduce编程模型

input->map->shuffle->reduce->output

2.2 Map-Reduce原理

2.2.1 Mapper

  • Map-reduce的思想就是“分而治之”
  • Mapper负责“分”,即把复杂的任务分解为若干个“简单的任务”执行
  • “简单任务”有几个含义:1.数据或计算规模相对于原任务要大大缩小;2.就近计算,即会被分配到存放了所需数据的节点进行计算;3.这些小任务可以并行计算,彼此间几乎没有依赖关系。

2.2.2 Reducer

  • 对map阶段的结果进行汇总
  • Reducer的数目由mapred-site.xml配置文件里的项目mapred.reduce.tasks决定。缺省值为1,用户可以覆盖之。

2.2.3 Shuffler

  • 在mapper和reducer中间的一个步骤(可以没有)
  • 可以把mapper的输出按照某种key值重新切分和组合成n份,把key值符合某种范围的输出到特定的reducer那里去处理
  • 可以简化reducer过程

2.2.4 例子

  • Mapper
public static class TokenizerMapper extends Mapper<Object,Text,Text,IntWritable>{
    private final static IntWritable one=new IntWritable(1);
    private Text word=new Text();
    
    public void map(Object key,Text value,Context context) throws IOException,InterruptedException{
        System.out.println("key="+key.toString());//添加查看key值
        System.out.println("value="=value.toString());//添加查看value值
        
        StringTokenizer itr=new StringTokenizer(value.toString());
        while(itr.hasMoreTokens()){
          word.set(itr.nextToken());
         context.write(word,one);
        }
    }
}
  • Reducer
public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable>{
    private IntWritable result=new IntWritable();
    
    public void reduce(Text key,Iterable<IntWritable> values,Context context)throws IOException,InterruptedException{
        int sum=0;
        for(IntWritable val:values){
            sum+=val.get();
        }
        result.set(sum);
        context.write(key,result);
    }
}
  • 运行mapper和reducer
public static void main(String[] args) throws Exception{
    Configuration conf=new Configuration();
    String[] otherArgs=new GenericOptionsParser(conf,args).getRemainingArgs();
    if(otherArgs.length!=2){
        System.err.println("Usage:wordcount<in><out>");
        System.exit(2);
    }
    Job job=new Job(conf,"word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    FileInputFormat.addInputPath(job,new Path(otherArgs[1]));
    System.exit(job.waitForCompletion(true)? 0:1);
}

2.3 性能调优

  • 究竟需要多少个reducer?
  • 输入:大文件优于小文件
  • 减少网络传输:压缩map的输出
  • 优化每个节点能运行的任务数:mapred.tasktracker.map.tasks.maximum和mapred.tasktracker.reduce.tasks.maximum(缺省值均为2)

2.4 调度机制

  • 缺省为先入先出作业队列调度
  • 支持公平调度器
  • 支持容量调度器

2.5 任务执行优化

  • 推测式优化:即如果jobtracker发现有拖后腿的任务,会再启动一个相同的备份任务,然后哪个先执行完就会kill去另一个。因此在监控网页上经常能看到正常执行完的作业有被kill掉的任务
  • 推测式执行缺省打开,但如果是代码问题,并不能解决问题,而且会使集群更慢,通过在mapred-site.xml配置文件中设置mapred.map.tasks.speculative.excution和mapred.reduce.tasks.speculative.execution可以为map任务或reduce任务开启或关闭推测式执行
  • 重用JVM,可以省去启动新的JVM消耗时间,在mapred-site.xml配置文件中设置mapred.job.reuse.jvm.num.tasks设置单个JVM上运行的最大任务数(1,>1或-1表示没有限制)
  • 忽略模式,任务在读取数据失败2次后,会把数据位置告诉jobtracker,后者重新启动该任务并且在遇到所记录的坏数据时直接跳过(缺省关闭,用SkipBadRecord方法打开)

2.6 错误处理机制:硬件故障

  • 硬件故障是指jobtracker故障或tasktracker故障
  • jobtracker是单点,若发生故障目前hadoop还无法处理,唯有选择最牢靠的硬件作为jobtracker
  • Jobtracker通过心跳(周期1分钟)信号了解tasktracker是否发生故障或负载过于严重
  • Jobtracker将从任务节点列表中移除发生故障的tasktracker
  • 如果故障节点在执行map任务并且尚未完成,jobtracker会要求其他节点继续执行尚未完成的reduce任务。

2.7 错误处理机制:任务失败

  • 由于代码缺陷或进程崩溃引起任务失败
  • JVM自动退出,向tasktracker父进程发送方错误信息,错误信息也会写入到日志
  • Tasktracker监听程序会发现进程退出,或进程很久没有更新信息送回,将任务标记为失败
  • 标记失败任务后,任务计数器减去1以便接收新任务,并通过心跳信号告诉jobtracker任务失败的信息
  • Jobtrack获悉任务失败后,将把该任务重新放入调度队列,重新分配出去再执行
  • 如果一个任务失败超过4次(可以设置),将不会再被执行,同时作业也宣布失败。

2.8 审计日志

  • 把log4j.logger.org.apache.hadoop.fs.FSNamesystem.audit=WARN改为“INFO”可以打开审计日志。每个HDFS事件都会在namenode的log中写入一行记录。

2.9 第三方工具

  • Ganglia
  • Chukwa
  • Openstack

3. Hadoop中重要的进程

3.1 Namenode

  • HDFS的守护进程
  • 每个进程都有一个
  • 记录文件如何分割成数据块的,以及这些数据存放的节点位置
  • 对内存和I/O进行集中管理
  • 是单点,发生故障将使集群奔溃

3.2 Secondar NameNode(辅助名称节点)

  • 监控HDFS状态的辅助后台程序
  • 每个集群都有一个
  • 与NameNode进行通讯,定期保存HDFS元数据快照
  • 当NameNode故障可以作为备用NameNode使用
  • 需要手动开启

3.3 DataNode

  • 每台从服务器都运行一个
  • 负责HDFS数据块读写到本地文件系统

3.4 JobTracker

  • 用于处理作业(用户提交代码)后台程序
  • 决定有哪些文件参与处理,然后切割task并分配节点
  • 监控task,重启失败的task(于不同的节点)
  • 每个集群只有唯一一个JobTracker,位于Master节点。

3.5 TaskTracker

  • 位于slave节点上,与datanode结合(代码与数据一起的原则)
  • 管理各自节点上的task(由jobtracker分配)
  • 每个节点只有一个tasktracker,但一个tasktracker可以启动多个JVM,用于并行执行map或reduce任务
  • 与jobtracker交互

3.6 Master和Slave

  • Master:Namenode,Secondary Namenode,Jobtracker.浏览器(用于观看管理页面),其他Hadoop工具。
  • Slave:Tasktracker、Datanode
  • Master不是唯一的

3.7 三种运行模式

  • 单机模式:安装简单,几乎不用做任何配置,仅限于调试用途
  • 伪分布模式:在单节点上同时启动namenode、datanode、jobtracker、tasktracker、secondary namenode等5个进程,模拟分布式运行的各个节点
  • 完全分布模式:正常的Hadoop集群,由多个各司其职的节点构成

扫码关注公众号

  • 后台回复“Hadoop”、“Hbase”等免费获取更多Hadoop、Hbase学习教材及实战资料在这里插入图片描述
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值