HBASE中最基本的操作是CRUD(Creat,Read,Update,Delete)操作,HBase提供了两种方式实现相关操作,即JAVA API和HBASE shell。
Put 类
Put类是Hbase存储数据的基本类,通过api可知,put的构造方法有多种,但无论哪种构造方法,都需要传入行键row,如:
Put(byte[] row)
Put(byte[] row,RowLock rowlock)
Put(byte[] row,long ts)
Put(byte[] row,long ts,RowLock rowlock)
Put类的add方法可以添加columnfamily,qulifier,value信息其方法为:
add(byte[] family,byte[] qualifier,longtimestamp,byte[] value)
add(byte[] family,byte[] qualifier,longtimestamp,byte[] value)
每调用一次add()方法,将增加一列数据。如果用户在增加数据时没有指定时间戳,将使用region服务器的系统时间作为时间戳。
我们注意到在put类中的属性,大量使用byte数组,hbase提供了各种类来将java数据类型转为byte[]数组;Bytes.toBytes(int a); Bytes.toBytes(String str) ; Bytes.toBytes(ButyBuffer bb);
此外,put类还提供了一系列其他方法,来检查或获取相应的单元格信息,如:
getRow() 返回put实例的行键
getTimeStampu() |
返回put实例的时间戳 |
heapSize() |
获取put实例占用的堆内存 |
isEmpty() |
检查familyMap中是否包含keyValue实例 |
…… |
|
向hbase插入数据的代码实例:
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
public class hbaseCRUD {
public staticvoid main(String[]args) throws IOException {
Configuration conf = HBaseConfiguration.create();
Connection conn = ConnectionFactory.createConnection(conf);
Admin admin =conn.getAdmin();
if (admin ==null) {
System.out.println("admin is null,please check it");
System.exit(0);
}
String tablestr ="data1_2018_01_01";
TableName tableName = TableName.valueOf(tablestr.getBytes());
Table table=conn.getTable(tableName);
Put put =new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("colfm1"), Bytes.toBytes("qualifier1"), 123456789, Bytes.toBytes("val1"));
put.addColumn(Bytes.toBytes("colfm2"), Bytes.toBytes("qualifier2"), 123456789, Bytes.toBytes("val2"));
table.put(put);
table.close();
}
}
HTableDescriptor
HBase中表结构由HTableDescriptor描述(包括HColumnDescriptor),对表的新增\修改\删除操作在接口HMasterInterface中定义,而该接口由HMaster实现
(1)HTableDescriptor包含:
表名,byte[]和String格式;
表的元信息,以key-value形式存储,包括文件较大的大小(默认256M)、是否只读、flush时内存占用大小(默认64M)、是否root或meta region、DEFERRED_LOG_FLUSH;
表的各Family描述HColumnDescriptor;
(2)HColumnDescriptor:描述column family的信息,包括:
压缩格式(不压缩,仅压缩value,压缩block中的一系列记录);
数据的版本数量;
block的大小(???);
是否在内存中;
是否cache block;
是否使用bloomfilter;
cell内容的存活时间(ttl);
是否复制。
当一个columnfamily创建后,其参数不能修改,除非删除掉该column family后新建一个,但删除column family也会删除掉该column family下的数据
另外,HTableDescriptor中包含ROOT_TABLEDESC和META_TABLEDESC两个实例以描述root和meta表:
ROOT_TABLEDESC包含一个info的column family,META_TABLEDESC包含一个info和historian两个column family
(3)建表过程(HMaster的createTable方法):若指定了splitKeys则为该table按指定键初始创建多个region,否则仅创建一个region
a.为table创建HRegionInfo
b.判断是不是所有的meta region都online(由RegionManager的MetaScanner扫描线程分配meta region)
c.判断serverManager是否有足够regionserver来创建table(????)
d.根据步骤a中新建的HRegionInfo创建table:
从RegionManager的onlineMetaRegion查找该HRegionInfo应放入哪一个meta region中:
在onlineMetaRegion中查找仅比regionName小的meta region,而regionName由tableName,起始Key,和regionId(root为0,meta为1,user当前时间)组成
同过master的ServerConnection获取HRegionInterface代理连接到该meta region,并查找对应该table为Key的记录是否存在,若存在则报错该表已存在
由RegionManager根据HRegionInfo创建新的user region:
在rootDir目录下新建以tableName为名的目录,在tableName目录下新建一个region的目录(经编码后的regionName),并新建一个HRegion对象
将region对应记录放入对应meta region中;
设置该region状态为未分配,等待分配给regionserver.
(4)对表的其它操作:disable,enable,delete,这些操作封装在继承自TableOperation的类中,该类先获得要操作表的所有meta region,扫描这些meta region中所有该表的user region信息并做相应处理,最后处理meta region