最后一个Reducer在过去24小时内运行200 gb的数据集

时间:2016-11-26 17:26:53

标签: hadoop mapreduce hbase bulk-load

您好我有一个mapreduce apllication,可以将数据批量加载到HBase中。 我总共有142个文本文件,总大小为200gb。 我的映射器在5分钟内完成,所有减速器也完成,但最后一个停留在100%。 它需要很长时间并且从过去24小时开始运行。 我有一个专栏系列。 我的行键如下所示。

48433197315 | 1972-03-31T00:00:00Z | 4 48433197315 | 1972-03-31T00:00:00Z | 38 48433197315 | 1972-03-31T00:00:00Z | 41 48433197315 | 1972-03-31T00: 00:00Z | 23 48433197315 | 1972-03-31T00:00:00Z | 7 48433336118 | 1972-03-31T00:00:00Z | 17 48433197319 | 1972-03-31T00:00:00Z | 64 48433197319 | 1972-03- 31T00:00:00Z | 58 48433197319 | 1972-03-31T00:00:00Z | 61 48433197319 | 1972-03-31T00:00:00Z | 73 48433197319 | 1972-03-31T00:00:00Z | 97 48433336119 | 1972- 03-31T00:00:00Z | 7

我已经创建了这样的表格。

  private static Configuration getHbaseConfiguration() {
    try {
        if (hbaseConf == null) {
        System.out.println(
            "UserId= " + USERID + " \t keytab file =" + KEYTAB_FILE + " \t conf =" + KRB5_CONF_FILE);
        HBaseConfiguration.create();
        hbaseConf = HBaseConfiguration.create();
        hbaseConf.set("mapreduce.job.queuename", "root.fricadev");
        hbaseConf.set("mapreduce.child.java.opts", "-Xmx6553m");
        hbaseConf.set("mapreduce.map.memory.mb", "8192");
        hbaseConf.setInt(MAX_FILES_PER_REGION_PER_FAMILY, 1024);
        System.setProperty("java.security.krb5.conf", KRB5_CONF_FILE);
        UserGroupInformation.loginUserFromKeytab(USERID, KEYTAB_FILE);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return hbaseConf;
    }

    /**
     * HBase bulk import example Data preparation MapReduce job driver
     * 
     * args[0]: HDFS input path args[1]: HDFS output path
     * 
     * @throws Exception
     * 
     */
    public static void main(String[] args) throws Exception {

    if (hbaseConf == null)
        hbaseConf = getHbaseConfiguration();
    String outputPath = args[2];
    hbaseConf.set("data.seperator", DATA_SEPERATOR);
    hbaseConf.set("hbase.table.name", args[0]);
    hbaseConf.setInt(MAX_FILES_PER_REGION_PER_FAMILY, 1024);

    Job job = new Job(hbaseConf);
    job.setJarByClass(HBaseBulkLoadDriver.class);
    job.setJobName("Bulk Loading HBase Table::" + args[0]);
    job.setInputFormatClass(TextInputFormat.class);
    job.setMapOutputKeyClass(ImmutableBytesWritable.class);
    job.setMapperClass(HBaseBulkLoadMapperUnzipped.class);

    // job.getConfiguration().set("mapreduce.job.acl-view-job",
    // "bigdata-app-fricadev-sdw-u6034690");
    if (HbaseBulkLoadMapperConstants.FUNDAMENTAL_ANALYTIC.equals(args[0])) {
        HTableDescriptor descriptor = new HTableDescriptor(Bytes.toBytes(args[0]));
        descriptor.addFamily(new HColumnDescriptor(COLUMN_FAMILY));
        HBaseAdmin admin = new HBaseAdmin(hbaseConf);
        byte[] startKey = new byte[16];
        Arrays.fill(startKey, (byte) 0);
        byte[] endKey = new byte[16];
        Arrays.fill(endKey, (byte) 255);
        admin.createTable(descriptor, startKey, endKey, REGIONS_COUNT);
        admin.close();
        // HColumnDescriptor hcd = new
        // HColumnDescriptor(COLUMN_FAMILY).setMaxVersions(1);
        // createPreSplitLoadTestTable(hbaseConf, descriptor, hcd);
    }

    job.getConfiguration().setBoolean("mapreduce.compress.map.output", true);
    job.getConfiguration().setBoolean("mapreduce.map.output.compress", true);
    job.getConfiguration().setBoolean("mapreduce.output.fileoutputformat.compress", true);

    job.getConfiguration().setClass("mapreduce.map.output.compression.codec",
        org.apache.hadoop.io.compress.GzipCodec.class, org.apache.hadoop.io.compress.CompressionCodec.class);
    job.getConfiguration().set("hfile.compression", Compression.Algorithm.LZO.getName());

    // Connection connection =
    // ConnectionFactory.createConnection(hbaseConf);
    // Table table = connection.getTable(TableName.valueOf(args[0]));
    FileInputFormat.setInputPaths(job, args[1]);
    FileOutputFormat.setOutputPath(job, new Path(outputPath));

    job.setMapOutputValueClass(Put.class);
    HFileOutputFormat.configureIncrementalLoad(job, new HTable(hbaseConf, args[0]));

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

    System.out.println("job is successfull..........");

    // LoadIncrementalHFiles loader = new LoadIncrementalHFiles(hbaseConf);

    // loader.doBulkLoad(new Path(outputPath), (HTable) table);

    HBaseBulkLoad.doBulkLoad(outputPath, args[0]);

    }

    /**
     * Enum of counters.
     * It used for collect statistics
     */
    public static enum Counters {
        /**
         * Counts data format errors.
         */
        WRONG_DATA_FORMAT_COUNTER
}
}

我的代码中只有mapper中没有reducer。 我的映射器代码是这样的。

public class FundamentalAnalyticLoader implements TableLoader {

    private ImmutableBytesWritable hbaseTableName;
    private Text value;
    private Mapper<LongWritable, Text, ImmutableBytesWritable, Put>.Context context;
    private String strFileLocationAndDate;

    @SuppressWarnings("unchecked")
    public FundamentalAnalyticLoader(ImmutableBytesWritable hbaseTableName, Text value, Context context,
        String strFileLocationAndDate) {

    //System.out.println("Constructing Fundalmental Analytic Load");

    this.hbaseTableName = hbaseTableName;
    this.value = value;
    this.context = context;
    this.strFileLocationAndDate = strFileLocationAndDate;
    }

    @SuppressWarnings("deprecation")
    public void load() {
    if (!HbaseBulkLoadMapperConstants.FF_ACTION.contains(value.toString())) {

        String[] values = value.toString().split(HbaseBulkLoadMapperConstants.DATA_SEPERATOR);
        String[] strArrFileLocationAndDate = strFileLocationAndDate
            .split(HbaseBulkLoadMapperConstants.FIELD_SEPERATOR);

        if (17 == values.length) {
        String strKey = values[5].trim() + "|" + values[0].trim() + "|" + values[3].trim() + "|"
            + values[4].trim() + "|" + values[14].trim() + "|" + strArrFileLocationAndDate[0].trim() + "|"
            + strArrFileLocationAndDate[2].trim();

        //String strRowKey=StringUtils.leftPad(Integer.toString(Math.abs(strKey.hashCode() % 470)), 3, "0") + "|" + strKey;
        byte[] hashedRowKey = HbaseBulkImportUtil.getHash(strKey);
        Put put = new Put((hashedRowKey));


        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FUNDAMENTAL_SERIES_ID),
            Bytes.toBytes(values[0].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FUNDAMENTAL_SERIES_ID_OBJECT_TYPE_ID),
            Bytes.toBytes(values[1].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FUNDAMENTAL_SERIES_ID_OBJECT_TYPE),
            Bytes.toBytes(values[2]));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FINANCIAL_PERIOD_END_DATE),
            Bytes.toBytes(values[3].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FINANCIAL_PERIOD_TYPE),
            Bytes.toBytes(values[4].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.LINE_ITEM_ID), Bytes.toBytes(values[5].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_ITEM_INSTANCE_KEY),
            Bytes.toBytes(values[6].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_VALUE), Bytes.toBytes(values[7].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_CONCEPT_CODE),
            Bytes.toBytes(values[8].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_VALUE_CURRENCY_ID),
            Bytes.toBytes(values[9].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_IS_ESTIMATED),
            Bytes.toBytes(values[10].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_AUDITABILITY_EQUATION),
            Bytes.toBytes(values[11].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FINANCIAL_PERIOD_TYPE_ID),
            Bytes.toBytes(values[12].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_CONCEPT_ID),
            Bytes.toBytes(values[13].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.ANALYTIC_LINE_ITEM_IS_YEAR_TO_DATE),
            Bytes.toBytes(values[14].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.IS_ANNUAL), Bytes.toBytes(values[15].trim()));

        // put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
        // Bytes.toBytes(HbaseBulkLoadMapperConstants.TAXONOMY_ID),
        // Bytes.toBytes(values[16].trim()));
        //
        // put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
        // Bytes.toBytes(HbaseBulkLoadMapperConstants.INSTRUMENT_ID),
        // Bytes.toBytes(values[17].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FF_ACTION),
            Bytes.toBytes(values[16].substring(0, values[16].length() - 3)));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FILE_PARTITION),
            Bytes.toBytes(strArrFileLocationAndDate[0].trim()));

        put.add(Bytes.toBytes(HbaseBulkLoadMapperConstants.COLUMN_FAMILY),
            Bytes.toBytes(HbaseBulkLoadMapperConstants.FILE_PARTITION_DATE),
            Bytes.toBytes(strArrFileLocationAndDate[2].trim()));

        try {
            context.write(hbaseTableName, put);
        } catch (IOException e) {
            context.getCounter(Counters.WRONG_DATA_FORMAT_COUNTER).increment(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        } else {

        System.out.println("Values length is less 15 and value is " + value.toString());
        }

    }
    }

高度赞赏任何提高速度的帮助。 enter image description here enter image description here enter image description here计数器图片 here`

2 个答案:

答案 0 :(得分:2)

我怀疑所有记录都进入单一区域。 创建空表时,HBase在偶数范围内分割键地址空间。但是因为所有实际的密钥共享相同的前缀,所以它们都进入单个区域。这意味着单个region / reduce任务完成所有工作,而所有其他region / reduce任务都没有做任何有用的事情。您可以通过查看Hadoop计数器来检查此假设:与其他reduce任务相比,减少任务读取/写入的字节数减少了多少。

如果这是问题,那么您需要使用createTable(HTableDescriptor desc, byte[][] splitKeys手动准备拆分键并创建表格。拆分键应均匀划分实际数据集以获得最佳性能。

示例#1。如果您的密钥是普通的英文单词,那么通过第一个字符将表格分成26个区域会很容易(分割键是'a','b',...,'z')。或者通过前两个字符将它分成26 * 26个区域:('aa','ab',...,'zz')。区域不一定是均匀的,但这无论如何都比只有单一区域更好。

示例#2。如果你的密钥是4字节哈希,那么很容易通过第一个字节(0x00,0x01,...,0xff)将表分成256个区域,或者通过前两个字节将表分成2 ^ 16个区域。

在您的特定情况下,我看到两个选项:

  1. 搜索数据集中的最小键(按排序顺序)和最大键。并将其用作startKeyendKeyAdmin.createTable()。仅当密钥在startKeyendKey之间均匀分布时,此方法才有效。

  2. 使用散列(键)和示例#2中的方法前缀键。这应该可以正常工作,但您无法进行语义查询,例如(KEY&gt; = $ {first}和KEY&lt; = $ {last})。

答案 1 :(得分:0)

大多数情况下,如果作业在最后一刻或几秒钟挂起,则问题可能是特定节点或具有并发性问题的资源等。

小清单可能是: 1.使用较小的数据集再试一次。这将排除代码的基本功能。 2.由于大部分工作已经完成,因此映射器和减速器可能都很好。您可以尝试几次运行相同卷的作业。日志可以帮助您识别同一节点是否存在重复运行问题。 3.验证输出是否按预期生成。 4.您还可以减少尝试添加到HBase的列数。这将减轻相同体积的负载。

工作被绞死可能是由于各种各样的问题造成的。但是故障排除主要包括上述步骤 - 如果数据相关,资源相关,特定节点相关,内存相关等,则验证原因。