目录
连接HBase
在HBase架构中的数据层面,HMaster负责管理类的操作(例如表、命令空间的创建删除),而HRegionServer负责表的读写(即CRUD)。对应地在客户端API中有两个类:Admin类与HTable(Table)类,Admin类对象职能类似于HMaster,而HTable的职能类似于HRegionServer。
通常这两个类的对象在一个应用程序中只创建一次,并且它们是由Connection对象获取的,Connection对象需要通过配置文件加载。所以以上对象一般为静态的,并且获取创建的过程在静态块中执行。
需要将core-site.xml、hdfs-site.xml、hbase-site.xml和log4j.properties放在src下
private static Configuration conf;
private static Connection conn;
private static Admin admin;
private static Table table
static{
//HBaseConfiguration是Configuration的子类,所以也可以获取到hdfs有关配置文件
conf = HBaseConfiguration.create();
try {
//通过ConnectionFactory建立与HBase的连接
conn = ConnectionFactory.createConnection(conf);
//从连接中获取Admin对象,而Table对象一般需要通过表名来获取
admin =conn.getAdmin();
} catch (IOException e) {
e.printStackTrace();
}
}
Table类:CRUD
以下是针对Table实例的操作
客户端对HBase的CRUD说到底就是针对单元格的操作,也就是发送不同类型的KeyValue(较新的api中使用的是Cell类,即单元格,不过内部构造是类似的),KeyValue的结构如下:
<row-key>/<family>:<qualifiter>/<version>/<type>/<value-length>
type字段指定了操作的类型,整体指定了具体的单元格和值
增对应Put类对象;查对应Get类对象;删对应Delete类对象;API中没有改操作,因为Put可以直接覆盖原值;这些对象内部不过是构造了不同的KeyValue
put
- Put类的构造函数
//需要指定行键,为特定行添加数据
Put(byte[] row)
Put(byte[], long ts)
- 向Put对象指定的那一行添加一列的数据
//每次add都会添加特定的列,若再添加时间戳即形成了一个单元格
Put addColumn(byte [] family, byte [] qualifier, byte [] value)
Put addColumn(byte [] family, byte [] qualifier, long ts, byte [] value)
Put add(Cell kv)
若在addColumn时不指定时间戳,则会使用来自构造函数的时间戳;若构造时也没有声明,则时间戳将由HRegionServer来设定
单行put
- 最后由Table类对象调用put()完成单行put
void put(Put put) throws IOException
示例:
/**写入一行数据*/
public static void put_single_row(String tName, String rk,String cf, String qua, String val){
Put put = new Put(Bytes.toBytes(rk));
put.addColumn(Bytes.toBytes(cf),Bytes.toBytes(qua),Bytes.toBytes(val));
try {
//通过连接获取Table类对象需要传入TableName对象,即表名
TableName tbn = TableName.valueOf(tName);
table = conn.getTable(tbn);
table.put(put);
} catch (IOException e) {
e.printStackTrace();
}
}
客户端的写缓冲区
每一次put操作实际上就是一次rpc操作,这样的工作原理只适合小数据量的操作。减少rpc调用的关键是限制往返时间(LAN中1次rpc大约花1ms)和控制消息大小。所以API配备了一个客户端的写缓冲区,缓冲区负责收集put操作,然后调用rpc操作一次性将put发送至服务器。
- 默认情况下客户端缓冲区是禁用的,可以通过将自动刷写设置为false来激活缓冲区
table.setAutoFlush(false)
- 当需要强制将数据刷写到服务器上时调用
void flushCommits() throws IOException
//table.flushCommits()
被缓冲的Put实例可能跨越多行,客户端内部会批量处理这些Put并把它们传送到对应的regionserver,这是客户端对于Regionserver的分拣,而在Regionserver上的分拣则是决定数据去往哪个region。
- 通常强制刷写是不必要的,一旦超出了缓冲区指定的大小限制,客户端会隐式地调用刷写方法,可以通过以下命令设置缓冲区大小
setWriteBufferSize(long writeBufferSize) throws IOEception
//table.setWriteBufferSize(2097152)
默认缓冲区大小为2MB(2097152字节),若需要存储较大的数据,可以考虑增大此值,还可以在hbase-site.xml中设置此值
<property>
<name>hbase.client.write.buffer</name>
<value>2097152</value>
</property>
- 估算服务端内存的占用
hbase.client.write.buffer * hbase.regionserver.handler.count * regionserver的数量
多行Put
- table同时还允许插入Put列表