欢迎光临
我们一直在努力

HBase过滤器与MapReduce数据输出量深度解析

HBase过滤器与MapReduce数据输出量深度解析

    • 引言
    • 一、HBase过滤器详解
      • 1.1 过滤器的作用
      • 1.2 过滤器的主要用途
      • 1.3 过滤器代码示例
      • 1.4 过滤器性能对比
    • 二、MapReduce输出量分析
      • 2.1 输出量影响因素
      • 2.2 过滤型MR程序
        • 场景1:错误日志提取
        • 场景2:订单状态过滤
      • 2.3 解析型MR程序
        • 场景:共同好友分析
      • 2.4 聚合型MR程序
        • 场景:Pi值计算
    • 三、不同类型MR程序的输出量对比
    • 四、优化策略
      • 4.1 过滤型作业优化
      • 4.2 解析型作业优化
      • 4.3 聚合型作业优化
    • 五、实际应用案例分析
      • 5.1 场景:Sca阶段增强日志处理
      • 5.2 场景:共同好友分析
    • 六、总结

🌺The Begin🌺点点关注,收藏不迷路🌺

引言

在大数据生态系统中,过滤器是优化数据查询的关键技术,而MapReduce作业的输出量则直接影响集群的I/O负载和作业效率。本文将深入探讨HBase过滤器的用途,并结合具体场景分析MapReduce作业的输出量变化规律。

一、HBase过滤器详解

1.1 过滤器的作用

HBase过滤器主要用于增强查询功能和减少网络传输:

#mermaid-svg-chuMOrOWj5OKHhjq{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-chuMOrOWj5OKHhjq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-chuMOrOWj5OKHhjq .error-icon{fill:#552222;}#mermaid-svg-chuMOrOWj5OKHhjq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-chuMOrOWj5OKHhjq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-chuMOrOWj5OKHhjq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-chuMOrOWj5OKHhjq .marker.cross{stroke:#333333;}#mermaid-svg-chuMOrOWj5OKHhjq svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-chuMOrOWj5OKHhjq p{margin:0;}#mermaid-svg-chuMOrOWj5OKHhjq .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-chuMOrOWj5OKHhjq .cluster-label text{fill:#333;}#mermaid-svg-chuMOrOWj5OKHhjq .cluster-label span{color:#333;}#mermaid-svg-chuMOrOWj5OKHhjq .cluster-label span p{background-color:transparent;}#mermaid-svg-chuMOrOWj5OKHhjq .label text,#mermaid-svg-chuMOrOWj5OKHhjq span{fill:#333;color:#333;}#mermaid-svg-chuMOrOWj5OKHhjq .node rect,#mermaid-svg-chuMOrOWj5OKHhjq .node circle,#mermaid-svg-chuMOrOWj5OKHhjq .node ellipse,#mermaid-svg-chuMOrOWj5OKHhjq .node polygon,#mermaid-svg-chuMOrOWj5OKHhjq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-chuMOrOWj5OKHhjq .rough-node .label text,#mermaid-svg-chuMOrOWj5OKHhjq .node .label text,#mermaid-svg-chuMOrOWj5OKHhjq .image-shape .label,#mermaid-svg-chuMOrOWj5OKHhjq .icon-shape .label{text-anchor:middle;}#mermaid-svg-chuMOrOWj5OKHhjq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-chuMOrOWj5OKHhjq .rough-node .label,#mermaid-svg-chuMOrOWj5OKHhjq .node .label,#mermaid-svg-chuMOrOWj5OKHhjq .image-shape .label,#mermaid-svg-chuMOrOWj5OKHhjq .icon-shape .label{text-align:center;}#mermaid-svg-chuMOrOWj5OKHhjq .node.clickable{cursor:pointer;}#mermaid-svg-chuMOrOWj5OKHhjq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-chuMOrOWj5OKHhjq .arrowheadPath{fill:#333333;}#mermaid-svg-chuMOrOWj5OKHhjq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-chuMOrOWj5OKHhjq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-chuMOrOWj5OKHhjq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-chuMOrOWj5OKHhjq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-chuMOrOWj5OKHhjq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-chuMOrOWj5OKHhjq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-chuMOrOWj5OKHhjq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-chuMOrOWj5OKHhjq .cluster text{fill:#333;}#mermaid-svg-chuMOrOWj5OKHhjq .cluster span{color:#333;}#mermaid-svg-chuMOrOWj5OKHhjq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-chuMOrOWj5OKHhjq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-chuMOrOWj5OKHhjq rect.text{fill:none;stroke-width:0;}#mermaid-svg-chuMOrOWj5OKHhjq .icon-shape,#mermaid-svg-chuMOrOWj5OKHhjq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-chuMOrOWj5OKHhjq .icon-shape p,#mermaid-svg-chuMOrOWj5OKHhjq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-chuMOrOWj5OKHhjq .icon-shape rect,#mermaid-svg-chuMOrOWj5OKHhjq .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-chuMOrOWj5OKHhjq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-chuMOrOWj5OKHhjq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-chuMOrOWj5OKHhjq :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

有过滤器

带过滤条件的查询

服务器端过滤只返回1GB

客户端

RegionServer

无过滤器

查询所有数据

返回10GB数据

客户端

RegionServer

客户端过滤只取1GB

1.2 过滤器的主要用途

用途说明示例
数据过滤 在服务端过滤数据,减少传输 SingleColumnValueFilter
行键过滤 根据行键模式匹配 RowFilter
列过滤 只返回指定列族/列 FamilyFilter, QualifierFilter
分页查询 实现数据分页 PageFilter
前缀过滤 匹配行键前缀 PrefixFilter

1.3 过滤器代码示例

// 创建HBase过滤器:只返回age大于30且城市为北京的数据
Scan scan = new Scan();

// 过滤器1:age > 30
SingleColumnValueFilter ageFilter = new SingleColumnValueFilter(
Bytes.toBytes("info"),
Bytes.toBytes("age"),
CompareOperator.GREATER,
Bytes.toBytes(30)
);

// 过滤器2:city = "北京"
SingleColumnValueFilter cityFilter = new SingleColumnValueFilter(
Bytes.toBytes("info"),
Bytes.toBytes("city"),
CompareOperator.EQUAL,
Bytes.toBytes("北京")
);

// 组合过滤器:AND条件
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filterList.addFilter(ageFilter);
filterList.addFilter(cityFilter);

scan.setFilter(filterList);

// 执行查询
ResultScanner scanner = table.getScanner(scan);

1.4 过滤器性能对比

场景无过滤器有过滤器提升
数据扫描量 100GB 100GB
网络传输量 100GB 1GB 99%
客户端内存 显著
响应时间 10-100倍

二、MapReduce输出量分析

2.1 输出量影响因素

MapReduce作业的输出量主要取决于作业类型和业务逻辑:

#mermaid-svg-VC5mvaHdsBCA2PpJ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VC5mvaHdsBCA2PpJ .error-icon{fill:#552222;}#mermaid-svg-VC5mvaHdsBCA2PpJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VC5mvaHdsBCA2PpJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .marker.cross{stroke:#333333;}#mermaid-svg-VC5mvaHdsBCA2PpJ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VC5mvaHdsBCA2PpJ p{margin:0;}#mermaid-svg-VC5mvaHdsBCA2PpJ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster-label text{fill:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster-label span{color:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster-label span p{background-color:transparent;}#mermaid-svg-VC5mvaHdsBCA2PpJ .label text,#mermaid-svg-VC5mvaHdsBCA2PpJ span{fill:#333;color:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .node rect,#mermaid-svg-VC5mvaHdsBCA2PpJ .node circle,#mermaid-svg-VC5mvaHdsBCA2PpJ .node ellipse,#mermaid-svg-VC5mvaHdsBCA2PpJ .node polygon,#mermaid-svg-VC5mvaHdsBCA2PpJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .rough-node .label text,#mermaid-svg-VC5mvaHdsBCA2PpJ .node .label text,#mermaid-svg-VC5mvaHdsBCA2PpJ .image-shape .label,#mermaid-svg-VC5mvaHdsBCA2PpJ .icon-shape .label{text-anchor:middle;}#mermaid-svg-VC5mvaHdsBCA2PpJ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .rough-node .label,#mermaid-svg-VC5mvaHdsBCA2PpJ .node .label,#mermaid-svg-VC5mvaHdsBCA2PpJ .image-shape .label,#mermaid-svg-VC5mvaHdsBCA2PpJ .icon-shape .label{text-align:center;}#mermaid-svg-VC5mvaHdsBCA2PpJ .node.clickable{cursor:pointer;}#mermaid-svg-VC5mvaHdsBCA2PpJ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .arrowheadPath{fill:#333333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VC5mvaHdsBCA2PpJ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VC5mvaHdsBCA2PpJ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VC5mvaHdsBCA2PpJ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster text{fill:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ .cluster span{color:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VC5mvaHdsBCA2PpJ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VC5mvaHdsBCA2PpJ rect.text{fill:none;stroke-width:0;}#mermaid-svg-VC5mvaHdsBCA2PpJ .icon-shape,#mermaid-svg-VC5mvaHdsBCA2PpJ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VC5mvaHdsBCA2PpJ .icon-shape p,#mermaid-svg-VC5mvaHdsBCA2PpJ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VC5mvaHdsBCA2PpJ .icon-shape rect,#mermaid-svg-VC5mvaHdsBCA2PpJ .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VC5mvaHdsBCA2PpJ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VC5mvaHdsBCA2PpJ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VC5mvaHdsBCA2PpJ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

作业类型

过滤型Filter

输出 < 输入

解析型Parse

输出 > 输入

聚合型Aggregate

输出 << 输入

2.2 过滤型MR程序

特点:输出量远小于输入量,只保留满足条件的数据。

场景1:错误日志提取

// 场景:从1.5T-2T的日志中提取ERROR级别日志
public class ErrorLogFilter extends Mapper<LongWritable, Text, Text, Text> {

public void map(LongWritable key, Text value, Context context) {
String line = value.toString();
if (line.contains("ERROR") || line.contains("Exception")) {
context.write(new Text(line), new Text(""));
}
}
}

// 输入:1.5T – 2T 全量日志
// 输出:假设错误日志占1%,约15GB – 20GB
// 输出/输入 ≈ 1%

场景2:订单状态过滤

// 过滤出已完成订单
public class CompletedOrderFilter extends Mapper<LongWritable, Text, Text, Text> {

public void map(LongWritable key, Text value, Context context) {
String[] fields = value.toString().split(",");
String status = fields[3]; // 订单状态字段

if ("COMPLETED".equals(status)) {
context.write(new Text(fields[0]), value);
}
}
}

// 输入:1亿条订单记录
// 输出:已完成订单约占30%,3000万条
// 输出/输入 ≈ 30%

2.3 解析型MR程序

特点:输出量大于输入量,一条输入产生多条输出。

场景:共同好友分析

// 场景:输入是用户好友列表,输出是用户对的共同好友
// 输入格式:用户A\\t好友1,好友2,好友3
public class CommonFriendsMapper extends Mapper<LongWritable, Text, Text, Text> {

public void map(LongWritable key, Text value, Context context) {
String[] parts = value.toString().split("\\t");
String user = parts[0];
String[] friends = parts[1].split(",");

// 为每个好友对生成一条记录
for (int i = 0; i < friends.length; i++) {
for (int j = i + 1; j < friends.length; j++) {
// 输出:好友对 -> 共同拥有者
String friendPair = friends[i] + "-" + friends[j];
context.write(new Text(friendPair), new Text(user));
}
}
}
}

// 输入:100万用户,平均每人100个好友
// 输入记录数:100万条
// 输出记录数:100万 * C(100,2) ≈ 100万 * 4950 ≈ 49.5亿条
// 输出/输入 ≈ 4950倍!

2.4 聚合型MR程序

特点:输出量远小于输入量,进行汇总计算。

场景:Pi值计算

// 场景:通过蒙特卡洛方法计算圆周率
// 输入:大量随机点
public class PiEstimator {

public static class PiMapper extends Mapper<Object, Text, Text, IntWritable> {
public void map(Object key, Text value, Context context) {
// 每个map任务处理一批随机点
int inside = 0;
int total = Integer.parseInt(value.toString());

for (int i = 0; i < total; i++) {
double x = Math.random();
double y = Math.random();
if (x*x + y*y <= 1) inside++;
}

// 只输出两个数字:圆内点数和总点数
context.write(new Text("inside"), new IntWritable(inside));
context.write(new Text("total"), new IntWritable(total));
}
}

public static class PiReducer extends Reducer<Text, IntWritable, Text, DoubleWritable> {
public void reduce(Text key, Iterable<IntWritable> values, Context context) {
// 聚合所有map的结果
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
if (key.toString().equals("inside")) {
insideSum = sum;
} else {
totalSum = sum;
}
}

public void cleanup(Context context) {
// 计算Pi值
double pi = 4.0 * insideSum / totalSum;
context.write(new Text("Estimated Pi"), new DoubleWritable(pi));
}
}
}

// 输入:10亿个随机点(10GB数据)
// 输出:只有1个数值(Pi的估计值)≈ 8字节
// 输出/输入 ≈ 1 : 1,250,000,000

三、不同类型MR程序的输出量对比

作业类型典型场景输入大小输出大小比例数据流向
过滤型 错误日志提取 2TB 20GB 1% 输入 > 输出
过滤型 订单状态过滤 1亿条 3000万条 30% 输入 > 输出
解析型 共同好友分析 100万条 49.5亿条 4950倍 输入 < 输出
解析型 日志解析成结构化 1GB 1.2GB 120% 输入 < 输出
聚合型 Pi值计算 10GB 8字节 极小 输入 >>> 输出
聚合型 单词计数 100GB 1MB 0.001% 输入 >>> 输出

四、优化策略

4.1 过滤型作业优化

// 使用Combiner提前过滤
public class OptimizedFilter extends Mapper<...> {

public void map(...) {
// 尽早过滤
if (!shouldKeep(line)) return;

// 使用压缩输出
context.getConfiguration().setBoolean("mapreduce.output.compress", true);
context.getConfiguration().set("mapreduce.output.compression.codec",
"org.apache.hadoop.io.compress.SnappyCodec");
}
}

4.2 解析型作业优化

// 控制爆炸式增长的输出
public class ControlledParseMapper extends Mapper<...> {

public void map(...) {
// 限制输出量
if (context.getCounter("Parse", "OutputCount").getValue() > MAX_OUTPUT) {
return; // 超过阈值,停止输出
}

// 批量输出
List<Text> batchOutput = new ArrayList<>();
// 填充batchOutput
for (Text output : batchOutput) {
context.write(output, ...);
}
}
}

4.3 聚合型作业优化

// 使用Combiner减少数据传输
public class PiCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {

public void reduce(Text key, Iterable<IntWritable> values, Context context) {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
context.write(key, new IntWritable(sum)); // 预聚合
}
}

五、实际应用案例分析

5.1 场景:Sca阶段增强日志处理

// 处理1.5T-2T的增强日志
public class ScaLogProcessor {

public static void main(String[] args) {
Configuration conf = new Configuration();

Job job = Job.getInstance(conf, "Sca Log Processor");
job.setJarByClass(ScaLogProcessor.class);

// Mapper配置
job.setMapperClass(LogFilterMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LogWritable.class);

// Reducer配置
job.setReducerClass(LogAggregatorReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);

// 输入:2TB
FileInputFormat.addInputPath(job, new Path("/data/sca/logs"));
// 输出:约20GB (1% 过滤率)
FileOutputFormat.setOutputPath(job, new Path("/output/sca/filtered"));

// 启用压缩
FileOutputFormat.setCompressOutput(job, true);
FileOutputFormat.setOutputCompressorClass(job, SnappyCodec.class);

System.exit(job.waitForCompletion(true) ? 0 : 1);
}

static class LogFilterMapper extends Mapper<...> {
public void map(...) {
String line = value.toString();
// 只保留ERROR级别日志
if (line.contains("ERROR") || line.contains("WARN")) {
context.write(...);
}
}
}
}

5.2 场景:共同好友分析

// 完整共同好友分析作业
public class CommonFriends {

public static void main(String[] args) throws Exception {
// 输入:用户好友列表
// 输出:共同好友统计

// 预期输出量估算:
// 100万用户,平均100好友
// 中间输出 ≈ 100万 * 4950 = 49.5亿条
// 最终输出 ≈ 1000万条好友对

// 需要大量资源
job.setNumReduceTasks(200); // 增加Reducer数量
}
}

六、总结

作业类型输入输出关系典型应用优化重点
过滤型 输入 > 输出 日志过滤、状态筛选 尽早过滤、压缩输出
解析型 输入 < 输出 共同好友、数据展开 控制爆炸增长、内存管理
聚合型 输入 >> 输出 统计计算、Pi值 Combiner使用、预聚合
HBase过滤器 减少网络传输 数据查询优化 服务端过滤、合理设计

核心要点:

  • HBase过滤器在服务端过滤数据,极大减少网络传输
  • 过滤型MR输出比输入少,适合数据清洗
  • 解析型MR输出可能爆炸式增长,需要特别注意
  • 聚合型MR输出极小,适合统计计算
  • Pi值计算是典型的聚合型作业,输出/输入比例极小
  • 理解不同作业类型的数据量特征,有助于合理规划资源、优化作业性能,避免出现OOM或数据倾斜问题。

    在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    赞(0)
    未经允许不得转载:171主机测评 » HBase过滤器与MapReduce数据输出量深度解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址