zoukankan      html  css  js  c++  java
  • HBase源码实战:CreateRandomStoreFile

    /*
     *
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package org.apache.hadoop.hbase.regionserver;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Random;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.FileSystem;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.HConstants;
    import org.apache.hadoop.hbase.KeyValue;
    import org.apache.hadoop.hbase.io.compress.Compression;
    import org.apache.hadoop.hbase.io.hfile.CacheConfig;
    import org.apache.hadoop.hbase.io.hfile.HFileBlockIndex;
    import org.apache.hadoop.hbase.io.hfile.HFileContext;
    import org.apache.hadoop.hbase.io.hfile.HFileContextBuilder;
    import org.apache.hadoop.hbase.util.BloomFilterFactory;
    import org.apache.hadoop.io.BytesWritable;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLineParser;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.HelpFormatter;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.Options;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.ParseException;
    import org.apache.hbase.thirdparty.org.apache.commons.cli.PosixParser;
    
    /**
     * Creates an HFile with random key/value pairs.
     */
    public class CreateRandomStoreFile {
    
      /**
       * As much as this number of bytes can be added or subtracted from key/value
       * lengths.
       */
      private static final int LEN_VARIATION = 5;
    
      private static final Logger LOG =
          LoggerFactory.getLogger(CreateRandomStoreFile.class);
      private static final String OUTPUT_DIR_OPTION = "o";
      private static final String NUM_KV_OPTION = "n";
      private static final String HFILE_VERSION_OPTION = "h";
      private static final String KEY_SIZE_OPTION = "k";
      private static final String VALUE_SIZE_OPTION = "v";
      private static final String COMPRESSION_OPTION = "c";
      private static final String BLOOM_FILTER_OPTION = "bf";
      private static final String BLOCK_SIZE_OPTION = "bs";
      private static final String BLOOM_BLOCK_SIZE_OPTION = "bfbs";
      private static final String INDEX_BLOCK_SIZE_OPTION = "ibs";
    
      /** The exit code this command-line tool returns on failure */
      private static final int EXIT_FAILURE = 1;
    
      /** The number of valid key types in a store file */
      private static final int NUM_VALID_KEY_TYPES =
          KeyValue.Type.values().length - 2;
    
      private Options options = new Options();
    
      private int keyPrefixLen, keyLen, rowLen, cfLen, valueLen;
      private Random rand;
    
      /**
       * Runs the tools.
       *
       * @param args command-line arguments
       * @return true in case of success
       * @throws IOException
       */
      public boolean run(String[] args) throws IOException {
        options.addOption(OUTPUT_DIR_OPTION, "output_dir", true,
            "Output directory");
        options.addOption(NUM_KV_OPTION, "num_kv", true,
            "Number of key/value pairs");
        options.addOption(KEY_SIZE_OPTION, "key_size", true, "Average key size");
        options.addOption(VALUE_SIZE_OPTION, "value_size", true,
            "Average value size");
        options.addOption(HFILE_VERSION_OPTION, "hfile_version", true,
            "HFile version to create");
        options.addOption(COMPRESSION_OPTION, "compression", true,
            " Compression type, one of "
                + Arrays.toString(Compression.Algorithm.values()));
        options.addOption(BLOOM_FILTER_OPTION, "bloom_filter", true,
            "Bloom filter type, one of "
                + Arrays.toString(BloomType.values()));
        options.addOption(BLOCK_SIZE_OPTION, "block_size", true,
            "HFile block size");
        options.addOption(BLOOM_BLOCK_SIZE_OPTION, "bloom_block_size", true,
            "Compound Bloom filters block size");
        options.addOption(INDEX_BLOCK_SIZE_OPTION, "index_block_size", true,
            "Index block size");
    
        if (args.length == 0) {
          HelpFormatter formatter = new HelpFormatter();
          formatter.printHelp(CreateRandomStoreFile.class.getSimpleName(), options,
              true);
          return false;
        }
    
        CommandLineParser parser = new PosixParser();
        CommandLine cmdLine;
        try {
          cmdLine = parser.parse(options, args);
        } catch (ParseException ex) {
          LOG.error(ex.toString(), ex);
          return false;
        }
    
        if (!cmdLine.hasOption(OUTPUT_DIR_OPTION)) {
          LOG.error("Output directory is not specified");
          return false;
        }
    
        if (!cmdLine.hasOption(NUM_KV_OPTION)) {
          LOG.error("The number of keys/values not specified");
          return false;
        }
    
        if (!cmdLine.hasOption(KEY_SIZE_OPTION)) {
          LOG.error("Key size is not specified");
          return false;
        }
    
        if (!cmdLine.hasOption(VALUE_SIZE_OPTION)) {
          LOG.error("Value size not specified");
          return false;
        }
    
        Configuration conf = HBaseConfiguration.create();
    
        Path outputDir = new Path(cmdLine.getOptionValue(OUTPUT_DIR_OPTION));
    
        long numKV = Long.parseLong(cmdLine.getOptionValue(NUM_KV_OPTION));
        configureKeyValue(numKV,
            Integer.parseInt(cmdLine.getOptionValue(KEY_SIZE_OPTION)),
            Integer.parseInt(cmdLine.getOptionValue(VALUE_SIZE_OPTION)));
    
        FileSystem fs = FileSystem.get(conf);
    
        Compression.Algorithm compr = Compression.Algorithm.NONE;
        if (cmdLine.hasOption(COMPRESSION_OPTION)) {
          compr = Compression.Algorithm.valueOf(
              cmdLine.getOptionValue(COMPRESSION_OPTION));
        }
    
        BloomType bloomType = BloomType.NONE;
        if (cmdLine.hasOption(BLOOM_FILTER_OPTION)) {
          bloomType = BloomType.valueOf(cmdLine.getOptionValue(
              BLOOM_FILTER_OPTION));
        }
    
        int blockSize = HConstants.DEFAULT_BLOCKSIZE;
        if (cmdLine.hasOption(BLOCK_SIZE_OPTION))
          blockSize = Integer.valueOf(cmdLine.getOptionValue(BLOCK_SIZE_OPTION));
    
        if (cmdLine.hasOption(BLOOM_BLOCK_SIZE_OPTION)) {
          conf.setInt(BloomFilterFactory.IO_STOREFILE_BLOOM_BLOCK_SIZE,
              Integer.valueOf(cmdLine.getOptionValue(BLOOM_BLOCK_SIZE_OPTION)));
        }
    
        if (cmdLine.hasOption(INDEX_BLOCK_SIZE_OPTION)) {
          conf.setInt(HFileBlockIndex.MAX_CHUNK_SIZE_KEY,
              Integer.valueOf(cmdLine.getOptionValue(INDEX_BLOCK_SIZE_OPTION)));
        }
    
        HFileContext meta = new HFileContextBuilder().withCompression(compr)
                            .withBlockSize(blockSize).build();
        StoreFileWriter sfw = new StoreFileWriter.Builder(conf,
            new CacheConfig(conf), fs)
                .withOutputDir(outputDir)
                .withBloomType(bloomType)
                .withMaxKeyCount(numKV)
                .withFileContext(meta)
                .build();
    
        rand = new Random();
        LOG.info("Writing " + numKV + " key/value pairs");
        for (long i = 0; i < numKV; ++i) {
          sfw.append(generateKeyValue(i));
        }
    
        int numMetaBlocks = rand.nextInt(10) + 1;
        LOG.info("Writing " + numMetaBlocks + " meta blocks");
        for (int metaI = 0; metaI < numMetaBlocks; ++metaI) {
          sfw.getHFileWriter().appendMetaBlock(generateString(),
              new BytesWritable(generateValue()));
        }
        sfw.close();
    
        Path storeFilePath = sfw.getPath();
        long fileSize = fs.getFileStatus(storeFilePath).getLen();
        LOG.info("Created {}, {} bytes, compression={}", storeFilePath, fileSize, compr.toString());
    
        return true;
      }
    
      private void configureKeyValue(long numKV, int keyLen, int valueLen) {
        numKV = Math.abs(numKV);
        keyLen = Math.abs(keyLen);
        keyPrefixLen = 0;
        while (numKV != 0) {
          numKV >>>= 8;
          ++keyPrefixLen;
        }
    
        this.keyLen = Math.max(keyPrefixLen, keyLen);
        this.valueLen = valueLen;
    
        // Arbitrarily split the key into row, column family, and qualifier.
        rowLen = keyPrefixLen / 3;
        cfLen = keyPrefixLen / 4;
      }
    
      private int nextInRange(int range) {
        return rand.nextInt(2 * range + 1) - range;
      }
    
      public KeyValue generateKeyValue(long i) {
        byte[] k = generateKey(i);
        byte[] v = generateValue();
    
        return new KeyValue(
            k, 0, rowLen,
            k, rowLen, cfLen,
            k, rowLen + cfLen, k.length - rowLen - cfLen,
            rand.nextLong(),
            generateKeyType(rand),
            v, 0, v.length);
      }
    
      public static KeyValue.Type generateKeyType(Random rand) {
        if (rand.nextBoolean()) {
          // Let's make half of KVs puts.
          return KeyValue.Type.Put;
        } else {
          KeyValue.Type keyType =
              KeyValue.Type.values()[1 + rand.nextInt(NUM_VALID_KEY_TYPES)];
          if (keyType == KeyValue.Type.Minimum || keyType == KeyValue.Type.Maximum)
          {
            throw new RuntimeException("Generated an invalid key type: " + keyType
                + ". " + "Probably the layout of KeyValue.Type has changed.");
          }
          return keyType;
        }
      }
    
      private String generateString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < rand.nextInt(10); ++i) {
          sb.append((char) ('A' + rand.nextInt(26)));
        }
        return sb.toString();
      }
    
      private byte[] generateKey(long i) {
        byte[] k = new byte[Math.max(keyPrefixLen, keyLen
            + nextInRange(LEN_VARIATION))];
        for (int pos = keyPrefixLen - 1; pos >= 0; --pos) {
          k[pos] = (byte) (i & 0xFF);
          i >>>= 8;
        }
        for (int pos = keyPrefixLen; pos < k.length; ++pos) {
          k[pos] = (byte) rand.nextInt(256);
        }
        return k;
      }
    
      private byte[] generateValue() {
        byte[] v = new byte[Math.max(1, valueLen + nextInRange(LEN_VARIATION))];
        for (int i = 0; i < v.length; ++i) {
          v[i] = (byte) rand.nextInt(256);
        }
        return v;
      }
    
      public static void main(String[] args) {
        CreateRandomStoreFile app = new CreateRandomStoreFile();
        try {
          if (!app.run(args))
            System.exit(EXIT_FAILURE);
        } catch (IOException ex) {
          LOG.error(ex.toString(), ex);
          System.exit(EXIT_FAILURE);
        }
    
      }
    
    }
  • 相关阅读:
    函数组件在react懒加载的方式
    axios 封装
    react高阶组件+ref转发的组合使用
    Iterator & Iterable 和 Comparable&Comparator
    java.lang.Collections
    虚拟机类加载学习和思考
    垃圾收集器与内存分配策略
    jvm内存区域与内存溢出
    spring装配Bean过程
    索引知识点补充
  • 原文地址:https://www.cnblogs.com/felixzh/p/10273822.html
Copyright © 2011-2022 走看看