Cli操作

建表

  1. create 'foo','cf1',SPLITS => ['10','20','30']
  2. create 'bar', 'cf1', SPLITS_FILE =>'/home/hadoop/rs.txt'

插入数据

  1. put 'wuren_foo', '20201204','cf1:name','foo'

0x01:客户端API:基础知识

概述

Table

HTable在2.0里已经没了,Table类实例化代价很小。
过时类
HTable实例创建代价很大。最好每个线程只有一个实例。需要多个用HTablePool类代替。
HTablePool是HBase连接池的老用法,该类在0.94,0.95和0.96中已经不建议使用,在0.98.1版本以后已经移除。https://blog.csdn.net/u010967382/article/details/38046821

KeyValue

KeyValue是HBase存储架构最底层的类。

数据版本化

用户如果不指定时间戳,RegionServer会指定时间戳。所以集群时间要同步。

CRUD

Put

写缓冲区

isAutoFlush()
setAutoFlush(false)激活缓冲区
flushCommits()把缓冲区数据发送到服务端
调整缓冲区大小
setWriteBufferSize()
getWriteBufferSize()

隐士刷写

put()、setWriteBufferSize()会检查缓冲区大小是否超过限制,如果超过调用flushCommits()
HTable.close()无条件触发隐式刷写。
一个HTable对应一个缓冲区,所以HTable线程不安全。
getWriteBuffer()可以获取缓冲区中数据。程序挂了缓冲区中数据就没了。

客户端和服务端检查

htable.put()会进行客户端检查,如果检查失败,后面的put实例不会被提交。
put列表实例的时候不保序(因为没法控制服务端集群)。
如果是服务端检查报错,如列族不存在。则其他put也会插入,只有报错的无法插入。

compare-and-set(CAS)

原子操作checkAndPut()检查值是否符合预期,符合则插入。
一旦检查成功则会屏蔽其他客户端对该行的修改,如果检查失败则放弃修改。

Get

Get类只能获取一行数据。

Result

Result里的数据已经返回到本地了,所以怎么取都不会有网络开销。

批处理操作

Row类是Get、Put、Delete的父类。
所以可以把操作放到一个Row列表中一起提交

  1. List<Row> batch = new ArrayList<Row>();
  2. table.batch(batch, results);

行锁(rowlock)

如果不显示传入,服务器也会生成行锁。

扫描

Scanner不会返回批量数据,而是返回迭代器。每次next()就是一次RPC调用。也可以配置减少RPC数增大每次拉去的行数——setScannerCaching(int scannerCaching)
setBatch(int batch)可以设置返回列数。
ResultScanner一定要调用close(),而且要放到try finally中。

租约

hbase.regionserver.lease.period
设置超时毫秒。超时后会自动释放ResultScanner

最佳实践

预分区

HBase表在刚刚被创建时,只有1个分区(region),当一个region过大(达到hbase.hregion.max.filesize属性中定义的阈值,默认10GB)时,表将会进行split,分裂为2个分区。表在进行split的时候,会耗费大量的资源,频繁的分区对HBase的性能有巨大的影响。

人们刚开始使用HBase时,趋向于写如下的代码:
Get get = new Get(rowkey); Result r = htable.get(get); byte[] b = r.getValue(Bytes.toBytes(“cf”), Bytes.toBytes(“attr”)); // returns current version of value
然而,特别是在循环内(和 MapReduce 工作内), 将列族和列名转为字节数组代价昂贵。最好使用字节数组常量,如下:
public static final byte[] CF = “cf”.getBytes(); public static final byte[] ATTR = “attr”.getBytes(); … Get get = new Get(rowkey); Result r = htable.get(get); byte[] b = r.getValue(CF, ATTR); // returns current version of value

Hive读写HBase

https://help.aliyun.com/document_detail/108545.html?spm=a2c4g.11186623.6.689.4f8f3db7qvmg0w

HFile

http://www.nosqlnotes.com/technotes/hbase/hfile/

CDH HBase 设置hfile.format.version

https://stackoverflow.com/questions/44958309/cloudera-cdh-5-7-2-hbase-how-to-set-hfile-format-version