티스토리 뷰

NoSQL 의 한종류인 HBASE 도입 관련하여 내부적으로 입력테스트를 진행해 보았습니다.


테스트 시나리오

1. 현재 운영중인 DB Schema와 동일한 필드 입력( 필드명, 사이즈 )

2. 1000만건의 데이터 입력

3. 데이터 입력시간 체크


 환경

ubuntu 12.04 ( giga bit network switch )

hadoop-1.0.1

hbase-0.92.1

java 1.6


Hbase 환경

총 세대의 서버 분산환경

nobody1 - RegionServer , HMaster, HQuorumPeer
nobody2 - RegionServer, HQuorumPeer
nobody3 - RegionServer



library required

hadoop-core-1.0.0.jar

hbase-0.92.1.jar

zookeeper-3.4.3.jar


insertHbase.java

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;


public class InsertHbase {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String table_name = "tb_insert";
        try {
            insertHBase(table_name);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static HTable createHBaseTable(String table_name, String[] cf) {
       
       
        // TODO Auto-generated method stub
        Configuration conf = HBaseConfiguration.create();
   
        //conf.set("hbase.zookeeper.quorum", "192.168.0.100:2181");
        HTable htable = null;
        try {
            HBaseAdmin admin = new HBaseAdmin(conf);

            if (admin.tableExists(table_name)) {
            }
            else {
                HTableDescriptor desc = new HTableDescriptor(table_name);
                for (String cf_name : cf) {
                    desc.addFamily(new HColumnDescriptor(cf_name));
                }
               
                admin.createTable(desc);
            }

            htable = new HTable(table_name);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
       
        return htable;
    }
   
    private static void insertHBase(String table_name) throws SQLException, IOException {
       
        String[] cf = { "a", "b" };
        HTable htable = createHBaseTable(table_name, cf);

       
        byte[] rowKey = null;
        int count = 0;
       
       
        long stime = System.currentTimeMillis ();
        SimpleDateFormat formatter = new SimpleDateFormat ( "yyyy.MM.dd HH:mm:ss", Locale.KOREA );
        String dTime = formatter.format(stime);
       
        BufferedWriter out = new BufferedWriter(new FileWriter("/home/rocksea/hbase_report.log"));
        out.write(dTime+"\t Start Time : "+dTime); out.newLine();
       
        System.out.println("Start Time:"+dTime);       
        for(int i=0; i < 10000000; i++){
            rowKey = Bytes.toBytes(Integer.toString(i+1));
            Put put = new Put(rowKey);
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("CTS"), Bytes.toBytes(InsertHbase.makeStar(10).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MSTR_NO"), Bytes.toBytes(InsertHbase.makeStar(8).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("SBJCT"), Bytes.toBytes(InsertHbase.makeStar(50).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("TXT"), Bytes.toBytes(InsertHbase.makeStar(200).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("WRTR"), Bytes.toBytes(InsertHbase.makeStar(50).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("PBLC_CNFG"), Bytes.toBytes(InsertHbase.makeStar(2).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("ALW_CNFG"), Bytes.toBytes(InsertHbase.makeStar(12).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("SRCH_CNFG"), Bytes.toBytes(InsertHbase.makeStar(12).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("RGSTR_CNFG"), Bytes.toBytes(InsertHbase.makeStar(12).toString()));

            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("FILE1"), Bytes.toBytes(InsertHbase.makeStar(601).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("FILE2"), Bytes.toBytes(InsertHbase.makeStar(601).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("FILE3"), Bytes.toBytes(InsertHbase.makeStar(601).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("FILE4"), Bytes.toBytes(InsertHbase.makeStar(601).toString()));

            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MC1"), Bytes.toBytes(InsertHbase.makeStar(5).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MC2"), Bytes.toBytes(InsertHbase.makeStar(5).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MC3"), Bytes.toBytes(InsertHbase.makeStar(5).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MC4"), Bytes.toBytes(InsertHbase.makeStar(5).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("MC5"), Bytes.toBytes(InsertHbase.makeStar(5).toString()));

            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S1"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S2"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S3"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S4"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S5"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S6"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S7"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S8"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S9"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));
            put.add(Bytes.toBytes(cf[0]), Bytes.toBytes("S10"), Bytes.toBytes(InsertHbase.makeStar(32).toString()));

            try {
                htable.put(put);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        long dtime = System.currentTimeMillis ();
        dTime = formatter.format(dtime);
       
        out.write(dTime+"\t End Time : "+dTime); out.newLine();
        out.write(dTime+"\t Total Second : "+((dtime-stime)/1000)); out.newLine();
        System.out.println("End Time:"+dTime);
        System.out.println("Total Second :"+ (dtime-stime)/1000);
        out.close();
    }
    public static StringBuffer makeStar(int cnt){
        StringBuffer sValue = new StringBuffer();
        for(int i=0; i <= cnt; i++)
            sValue.append("*");
        return sValue;
    }
}


Commands

hbase(main):001:0> help
HBASE SHELL COMMANDS:
 alter     Alter column family schema;  pass table name and a dictionary
           specifying new column family schema. Dictionaries are described
           below in the GENERAL NOTES section.  Dictionary must include name
           of column family to alter.  For example,

           To change or add the 'f1' column family in table 't1' from defaults
           to instead keep a maximum of 5 cell VERSIONS, do:
           hbase> alter 't1', {NAME => 'f1', VERSIONS => 5}

           To delete the 'f1' column family in table 't1', do:
           hbase> alter 't1', {NAME => 'f1', METHOD => 'delete'}

           You can also change table-scope attributes like MAX_FILESIZE
           MEMSTORE_FLUSHSIZE and READONLY.

           For example, to change the max size of a family to 128MB, do:
           hbase> alter 't1', {METHOD => 'table_att', MAX_FILESIZE => '134217728'}

 count     Count the number of rows in a table. This operation may take a LONG
           time (Run '$HADOOP_HOME/bin/hadoop jar hbase.jar rowcount' to run a
           counting mapreduce job). Current count is shown every 1000 rows by
           default. Count interval may be optionally specified. Examples:

           hbase> count 't1'
           hbase> count 't1', 100000

 create    Create table; pass table name, a dictionary of specifications per
           column family, and optionally a dictionary of table configuration.
           Dictionaries are described below in the GENERAL NOTES section.
           Examples:

           hbase> create 't1', {NAME => 'f1', VERSIONS => 5}
           hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}
           hbase> # The above in shorthand would be the following:
           hbase> create 't1', 'f1', 'f2', 'f3'
           hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, \
             BLOCKCACHE => true}

 describe  Describe the named table: e.g. "hbase> describe 't1'"

 delete    Put a delete cell value at specified table/row/column and optionally
           timestamp coordinates.  Deletes must match the deleted cell's
           coordinates exactly.  When scanning, a delete cell suppresses older
           versions. Takes arguments like the 'put' command described below

 deleteall Delete all cells in a given row; pass a table name, row, and optionally
           a column and timestamp

 disable   Disable the named table: e.g. "hbase> disable 't1'"

 drop      Drop the named table. Table must first be disabled. If table has
           more than one region, run a major compaction on .META.:

           hbase> major_compact ".META."

 enable    Enable the named table

 exists    Does the named table exist? e.g. "hbase> exists 't1'"

 exit      Type "hbase> exit" to leave the HBase Shell

 get       Get row or cell contents; pass table name, row, and optionally
           a dictionary of column(s), timestamp and versions.  Examples:

           hbase> get 't1', 'r1'
           hbase> get 't1', 'r1', {COLUMN => 'c1'}
           hbase> get 't1', 'r1', {COLUMN => ['c1', 'c2', 'c3']}
           hbase> get 't1', 'r1', {COLUMN => 'c1', TIMESTAMP => ts1}
           hbase> get 't1', 'r1', {COLUMN => 'c1', TIMESTAMP => ts1, \
             VERSIONS => 4}

 list      List all tables in hbase

 put       Put a cell 'value' at specified table/row/column and optionally
           timestamp coordinates.  To put a cell value into table 't1' at
           row 'r1' under column 'c1' marked with the time 'ts1', do:

           hbase> put 't1', 'r1', 'c1', 'value', ts1

 tools     Listing of hbase surgery tools

 scan      Scan a table; pass table name and optionally a dictionary of scanner
           specifications.  Scanner specifications may include one or more of
           the following: LIMIT, STARTROW, STOPROW, TIMESTAMP, or COLUMNS.  If
           no columns are specified, all columns will be scanned.  To scan all
           members of a column family, leave the qualifier empty as in
           'col_family:'.  Examples:

           hbase> scan '.META.'
           hbase> scan '.META.', {COLUMNS => 'info:regioninfo'}
           hbase> scan 't1', {COLUMNS => ['c1', 'c2'], LIMIT => 10, \
             STARTROW => 'xyz'}

           For experts, there is an additional option -- CACHE_BLOCKS -- which
           switches block caching for the scanner on (true) or off (false).  By
           default it is enabled.  Examples:

           hbase> scan 't1', {COLUMNS => ['c1', 'c2'], CACHE_BLOCKS => false}

 status    Show cluster status. Can be 'summary', 'simple', or 'detailed'. The
           default is 'summary'. Examples:

           hbase> status
           hbase> status 'simple'
           hbase> status 'summary'
           hbase> status 'detailed'

 shutdown  Shut down the cluster.

 truncate  Disables, drops and recreates the specified table.

 version   Output this HBase version

GENERAL NOTES:
Quote all names in the hbase shell such as table and column names.  Don't
forget commas delimit command parameters.  Type <RETURN> after entering a
command to run it.  Dictionaries of configuration used in the creation and
alteration of tables are ruby Hashes. They look like this:

  {'key1' => 'value1', 'key2' => 'value2', ...}

They are opened and closed with curley-braces.  Key/values are delimited by
the '=>' character combination.  Usually keys are predefined constants such as
NAME, VERSIONS, COMPRESSION, etc.  Constants do not need to be quoted.  Type
'Object.constants' to see a (messy) list of all constants in the environment.

In case you are using binary keys or values and need to enter them into the
shell then use double-quotes to make use of hexadecimal or octal notations,
for example:

  hbase> get 't1', "key\x03\x3f\xcd"
  hbase> get 't1', "key\003\023\011"
  hbase> put 't1', "test\xef\xff", 'f1:', "\x01\x33\x40"

Using the double-quote notation you can directly use the values output by the
shell for example during a "scan" call.

This HBase shell is the JRuby IRB with the above HBase-specific commands added.
For more on the HBase Shell, see http://wiki.apache.org/hadoop/Hbase/Shell

결과

2012.06.26 13:50:30     Start Time : 2012.06.26 13:50:30
2012.06.26 19:48:29     End Time : 2012.06.26 19:48:29
2012.06.26 19:48:29     Total Second : 21478


이상으로 hbase insert test 에 대한 포스팅을 마치도록 하겠습니다.


by rocksea.

댓글