Hbase入库基于java

本文分享了一次HBase性能优化的经历,包括rowkey设计的重要性、表分片策略及其实现方式,并提供了完整的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计划每周写一篇博客,督促自己快点学习,懒惰会让人上瘾,努力奋斗,不忘初心。

某天,忽然来任务,要做hbse入库,之前自学过hbase,感觉挺简单的,网上搜了些model直接撸码,一天完成核心功能,测试了下跑通了,更加需求建了两个表,每张表日录入数据量接近两千万,感觉挺简单的。大概过了快一个月,这个很简单的东西,罢工了提示查询失败。

因业务需要,设计时keyvalue定义很长,40多个字节,包含业务和时间,每天接近两千万的数据录入,只能坚持20多天,后来,多方求证,换了一种替代办法,每半个月建立一张新表,根据查询时间,判断要查询的表,从而获取数据。

总结:

    1、rowkey设计很重要,最好不大于8字节。如果超过了,考虑分表

    2、列族和列限定符尽量小,有利于加快查询速度。

啰嗦这么多,上代码。

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.MasterNotRunningException;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
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;

import com.hbase.insert.model.InsertModel;

@SuppressWarnings("all")
public class HbaseUtil {
    
    private static final Log log = LogFactory.getLog(HbaseUtil.class);
    
    private Configuration conf;
    private InsertModel insertModel;
    
    public HbaseUtil(InsertModel insertModel){
        this.conf=HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", insertModel.getIp());
        this.insertModel=insertModel;
    }
    
    
    /**
     * 创建表
     * @param tableName
     */
    public void createTable(String tableName){
        try {
            HBaseAdmin admin=new HBaseAdmin(conf);
            NamespaceDescriptor[] namespace=admin.listNamespaceDescriptors();
            int state=0;
            
            /*获取命名空间*/
            for(NamespaceDescriptor name:namespace){
                if(name.getName().equals(insertModel.getDataName())){
                    state=1;
                }
            }
            /*创建命名空间*/
            if(state==0){
                admin.createNamespace(NamespaceDescriptor.create(insertModel.getDataName()).build());
            }
            
            
            if(admin.tableExists(insertModel.getDataName()+":"+tableName)){
                log.info("tables Exists!");
            }else{
                
                /*创建表*/
                HTableDescriptor desc=new HTableDescriptor(TableName.valueOf(insertModel.getDataName()+":"+tableName));
                
                desc.addFamily(new HColumnDescriptor(insertModel.getFamilName()).setTimeToLive(insertModel.getTime()));
                admin.createTable(desc);
                log.info("create table Success!");
            }
            admin.close();
        } catch (MasterNotRunningException e) {
            log.error(e,e);
        } catch (ZooKeeperConnectionException e) {
            log.error(e,e);
        } catch (IOException e) {
            log.error("IOException ",e);
        }
    }
    
    public boolean getTableStatus(String tableName){
        try {
            HBaseAdmin admin=new HBaseAdmin(conf);
            return admin.tableExists(insertModel.getDataName()+":"+tableName);
            
        } catch (MasterNotRunningException e) {
            log.error(e,e);
        } catch (ZooKeeperConnectionException e) {
            log.error(e,e);
        } catch (IOException e) {
            log.error(e,e);
        }
        return false;
    }
    
    /**
     * 删除表
     */
    public void delTable(String tableName){
        try {
            HBaseAdmin admin=new HBaseAdmin(conf);
            if(admin.tableExists(insertModel.getDataName()+":"+tableName)){
                admin.disableTable(insertModel.getDataName()+":"+tableName);
                admin.deleteTable(insertModel.getDataName()+":"+tableName);
                log.info("Delete "+tableName+" Success!");
            }else{
                log.info("No Found This Table:"+tableName);
            }
            
        } catch (MasterNotRunningException e) {
            log.error(e,e);
        } catch (ZooKeeperConnectionException e) {
            log.error(e,e);
        } catch (IOException e) {
            log.error(e,e);
        }
    }
    /**
     * 添加数据
     */
    public void addData(List<String> lineContext,String Yesterday,String dataTime){
        HTable table = null;
        try {
            String[] text;
            Put put;
            String rowkey;
            
            List<Put> imsi=new ArrayList<Put>();
            
            for(String context:lineContext){  //imsi,phone
                text=context.split("\\,");
                if(text[1].startsWith("1")&&text[1].length()==11){
                    rowkey=text[0]+Yesterday;
                    put =new Put(Bytes.toBytes(rowkey)); //设置rowkey
                    put.add(Bytes.toBytes(insertModel.getFamilName()),Bytes.toBytes(insertModel.getCloumnName()),Bytes.toBytes(text[1]));
                    imsi.add(put);
                    
                }
                
            }
            table=new HTable(conf,Bytes.toBytes(insertModel.getDataName()+":"+insertModel.getImsiTable()+dataTime));
            table.put(imsi);

        } catch (IOException e) {
            log.error(e,e);
        }
        
    } 
    

}

其中InsertModel主要有一下字段。

    //数据库名
    private String dataName;
    //imsi表名
    private String imsiTable;
    //手机号表名
    private String msisdnTable;
    //源文件路径
    private String url;
    //Hbase Ip
    private String ip;
    //列族
    private String familyName;
    //列名
    private String cloumnName;
    //表值存储时间
    private Integer time;
    //多少行提交一次
    private Integer rowsize;
    /*表时间*/
    private String tableTime;
    /*参数日期前一天*/
    private String paramTime;

转载于:https://my.oschina.net/wangzonghui/blog/1607279

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值