【Hadoop】HDFS(四)

HDFS

扩展

数据平衡

  1. 当HDFS集群中,存储空间不足的时候,那么此时可能会选择新添磁盘或者新添节点,那么添加完之后,考虑做数据在磁盘或者节点之间的平衡

  2. 节点内(磁盘)的平衡

    1. 假设第一台服务器新添了一块磁盘,那么此时需要在第一台服务器上生成均衡计划

      hdfs diskbalancer -plan hadoop01
      # 执行完成之后,会在当前目录下生成一个均衡文件hadoop01.plan.json
      
    2. 执行均衡计划

      hdfs diskbalancer -execute hadoop01.plan.json
      
    3. 查看均衡任务的执行情况

      hdfs diskbalancer -query hadoop01
      
    4. 取消均衡计划

      hdfs diskbalancer -cancel hadoop01.plan.json
      
  3. 节点间的平衡

    1. 开启均衡任务

      # start-balancer.sh -threhold n
      # threhold-阈值,n表示节点之间的使用差
      # 10表示当各个节点之间,磁盘利用率相差如果超过10%,那么就需要进行均衡
      start-balancer.sh -threhold 10
      
    2. 关闭均衡

      stop-balancer.sh
      

集群间的数据拷贝

  1. 如果需要将数据从一个HDFS集群拷贝到另一个HDFS集群,那么可以执行

    hadoop distcp hdfs://hadoop01:9000/a.txt hdfs://hadoop101:9000/a.txt
    
  2. 实际过程中,较少发生。一般是在进行集群的合并的时候,才会考虑集群之间的数据拷贝

Federation HDFS(了解)

  1. 当前HDFS架构存在一个小小的问题
    1. 集群中只有一个NameNode,那么就意味着所有的请求都需要经过这唯一的NameNode进行处理,NameNode的处理效率一定程度决定了HDFS的效率
    2. 因为只有1个NameNode,所以导致所有的元数据都需要记录到NameNode上。实际开发中,一台服务器如果被设置为了NameNode,那么这台服务器需要大约腾出来50GB(大约是2亿~3亿条元数据)左右的内存给NameNode使用
  2. 考虑到上述问题,HDFS提供了一种缓解方案:Federation HDFS(联邦HDFS)。将路径拆分到不同的节点上,当客户端产生请求的时候,根据客户端的请求路径不同,那么将请求分发到不同的节点上处理,此时利用了多个NameNode来共同承担原来一个NameNode的责任,这种情况称之为联邦HDFS
  3. 联邦HDFS的特点
    1. 利用多台服务器来处理请求,那么可以一定程度上提高集群的并发量(能够接受的请求数量),也能够更充分的利用集群的磁盘的IO资源
    2. 这种方式的特点在于,HDFS上的虚拟路径相对固定,因此联邦HDFS更适合于业务相对稳定的场景
  4. 在联邦HDFS中,要求所有的NameNode的BlockPoolID相同

MapReduce

概述

  1. MapReduce是Doug根据的Google的<The Google MapReduce>来仿照实现的
  2. MapReduce将整个计算过程拆分为了两个大阶段:Map(映射)阶段和Reduce(规约)阶段

入门案例

  1. 案例:统计这个文件中每一个字符出现的次数

  2. MapReduce刚开始的时候,会先对要处理的文件进行切片(Split)。

    1. Split是逻辑切分,是在划分任务量
    2. Block是物理切分,是在确定存储单位
  3. 实际过程中,考虑到数据要跨节点传输,为了减少跨节点的数量,所以Split=Block/n。在MapReduce中,默认Split和Block等大

    在这里插入图片描述

  4. Mapper类

    package com.fesco.charcount;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    import java.io.IOException;
    
    // Mapper
    // 在MapReduce中,要求传输的数据能够被序列化
    // 而MapReduce使用的不是Java的原生序列化机制,而是采用了新的序列化机制
    // KEYIN - 输入的键的类型,是这一行的字节偏移量
    // VALUEIN - 输入的值的类型,是这一行数据
    // KEYOUT - 输出的键的类型。当前案例中,输出的键是字符
    // VALUEOUT - 输出的值的类型。当前案例中,输出的值是次数
    public class CharCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    
        private final IntWritable once =  new IntWritable(1);
    
        // MapTask的处理逻辑是放在map方法中
        // 切片中的每一行都会调用一次map方法进行处理
        // key:键。每一行的字节偏移量
        // value:值。这一行数据
        // context:环境参数
        @Override
        protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {
            // 将这一行中的字符拆分出来
            char[] cs = value.toString().toCharArray();
            //
            for (char c : cs) {
                context.write(new Text(String.valueOf(c)), once);
            }
        }
    }
    
  5. Reducer类

    package com.fesco.charcount;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    import java.io.IOException;
    
    // KEYIN,VALUEIN - 输入的键和值。Reducer的数据是Mapper产生的,那么就意味着Mapper的输出类型就是Reducer的输入类型
    // KEYOUT,VALUEOUT - 输出的键和值。当前案例中,最终输出的字符和对应的次数
    public class CharCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    
        // key:键。当前案例中,键是字符
        // values:值。Reduce开始的时候会将相同的键对应的值放到一起,这个过程称之为分组。分组结束之后,会将值放入迭代器中,每一个键调用一次reduce方法
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
            // key:h
            // values:1,1,1,1,1,1....
            // 定义变量记录和
            int sum = 0;
            // 遍历values
            for (IntWritable value : values) {
                sum += value.get();
            }
            context.write(key, new IntWritable(sum));
    
        }
    }
    
  6. Driver类(入口类)

    package com.fesco.charcount;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.io.IntWritable;
    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;
    
    public class CharCountDriver {
    
        public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
    
            // 环境参数
            Configuration conf = new Configuration();
            // 申请任务
            Job job = Job.getInstance(conf);
            // 指定入口类
            job.setJarByClass(CharCountDriver.class);
            // 指定Mapper类
            job.setMapperClass(CharCountMapper.class);
            // 指定Reducer类
            job.setReducerClass(CharCountReducer.class);
            // 指定Mapper的输出类型
            job.setMapOutputKeyClass(Text.class);
            job.setMapOutputValueClass(IntWritable.class);
            // 指定Reducer的输出类型
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(IntWritable.class);
            // 指定输入路径
            FileInputFormat.addInputPath(job, new Path("hdfs://10.16.3.181:9000/txt/characters.txt"));
            // 指定输出路径,要求输出路径必须不存在
            FileOutputFormat.setOutputPath(job, new Path("hdfs://10.16.3.181:9000/result/char_count"));
            // 提交任务
            job.waitForCompletion(true);
        }
    }
    

指定输出路径,要求输出路径必须不存在
FileOutputFormat.setOutputPath(job, new Path(“hdfs://10.16.3.181:9000/result/char_count”));
// 提交任务
job.waitForCompletion(true);
}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZikH~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值