计划每周写一篇博客,督促自己快点学习,懒惰会让人上瘾,努力奋斗,不忘初心。
某天,忽然来任务,要做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;