一、简述 截至到目前(2019.04),HBase 有两个主要的版本,分别是1.x 和 2.x ,两个版本的Java API有所不同,1.x 中某些方法在2.x中被标识为@deprecated
过时。所以下面关于API的样例,我会分别给出1.x和2.x两个版本。完整的代码见本仓库:
同时你使用的客户端的版本必须与服务端版本保持一致,如果用2.x版本的客户端代码去连接1.x版本的服务端,会抛出NoSuchColumnFamilyException
等异常。
二、Java API 1.x 基本使用 2.1 新建Maven工程,导入项目依赖 要使用Java API 操作HBase,需要引入hbase-client
。这里选取的HBase Client
的版本为1.2.0
。
1 2 3 4 5 <dependency > <groupId > org.apache.hbase</groupId > <artifactId > hbase-client</artifactId > <version > 1.2.0</version > </dependency >
2.2 API 基本使用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 public class HBaseUtils { private static Connection connection; static { Configuration configuration = HBaseConfiguration.create(); configuration.set("hbase.zookeeper.property.clientPort" , "2181" ); configuration.set("hbase.zookeeper.quorum" , "hadoop001" ); try { connection = ConnectionFactory.createConnection(configuration); } catch (IOException e) { e.printStackTrace(); } } public static boolean createTable (String tableName, List<String> columnFamilies) { try { HBaseAdmin admin = (HBaseAdmin) connection.getAdmin(); if (admin.tableExists(tableName)) { return false ; } HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf(tableName)); columnFamilies.forEach(columnFamily -> { HColumnDescriptor columnDescriptor = new HColumnDescriptor(columnFamily); columnDescriptor.setMaxVersions(1 ); tableDescriptor.addFamily(columnDescriptor); }); admin.createTable(tableDescriptor); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean deleteTable (String tableName) { try { HBaseAdmin admin = (HBaseAdmin) connection.getAdmin(); admin.disableTable(tableName); admin.deleteTable(tableName); } catch (Exception e) { e.printStackTrace(); } return true ; } public static boolean putRow (String tableName, String rowKey, String columnFamilyName, String qualifier, String value) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(Bytes.toBytes(rowKey)); put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(qualifier), Bytes.toBytes(value)); table.put(put); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean putRow (String tableName, String rowKey, String columnFamilyName, List<Pair<String, String>> pairList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(Bytes.toBytes(rowKey)); pairList.forEach(pair -> put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(pair.getKey()), Bytes.toBytes(pair.getValue()))); table.put(put); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } public static Result getRow (String tableName, String rowKey) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Get get = new Get(Bytes.toBytes(rowKey)); return table.get(get); } catch (IOException e) { e.printStackTrace(); } return null ; } public static String getCell (String tableName, String rowKey, String columnFamily, String qualifier) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Get get = new Get(Bytes.toBytes(rowKey)); if (!get.isCheckExistenceOnly()) { get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier)); Result result = table.get(get); byte [] resultValue = result.getValue(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier)); return Bytes.toString(resultValue); } else { return null ; } } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName, FilterList filterList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); scan.setFilter(filterList); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName, String startRowKey, String endRowKey, FilterList filterList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); scan.setStartRow(Bytes.toBytes(startRowKey)); scan.setStopRow(Bytes.toBytes(endRowKey)); scan.setFilter(filterList); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static boolean deleteRow (String tableName, String rowKey) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Delete delete = new Delete(Bytes.toBytes(rowKey)); table.delete(delete); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean deleteColumn (String tableName, String rowKey, String familyName, String qualifier) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Delete delete = new Delete(Bytes.toBytes(rowKey)); delete.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(qualifier)); table.delete(delete); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } }
2.3 单元测试 以单元测试的方式对上面封装的API进行测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 public class HBaseUtilsTest { private static final String TABLE_NAME = "class" ; private static final String TEACHER = "teacher" ; private static final String STUDENT = "student" ; @Test public void createTable () { List<String> columnFamilies = Arrays.asList(TEACHER, STUDENT); boolean table = HBaseUtils.createTable(TABLE_NAME, columnFamilies); System.out.println("表创建结果:" + table); } @Test public void insertData () { List<Pair<String, String>> pairs1 = Arrays.asList(new Pair<>("name" , "Tom" ), new Pair<>("age" , "22" ), new Pair<>("gender" , "1" )); HBaseUtils.putRow(TABLE_NAME, "rowKey1" , STUDENT, pairs1); List<Pair<String, String>> pairs2 = Arrays.asList(new Pair<>("name" , "Jack" ), new Pair<>("age" , "33" ), new Pair<>("gender" , "2" )); HBaseUtils.putRow(TABLE_NAME, "rowKey2" , STUDENT, pairs2); List<Pair<String, String>> pairs3 = Arrays.asList(new Pair<>("name" , "Mike" ), new Pair<>("age" , "44" ), new Pair<>("gender" , "1" )); HBaseUtils.putRow(TABLE_NAME, "rowKey3" , STUDENT, pairs3); } @Test public void getRow () { Result result = HBaseUtils.getRow(TABLE_NAME, "rowKey1" ); if (result != null ) { System.out.println(Bytes .toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name" )))); } } @Test public void getCell () { String cell = HBaseUtils.getCell(TABLE_NAME, "rowKey2" , STUDENT, "age" ); System.out.println("cell age :" + cell); } @Test public void getScanner () { ResultScanner scanner = HBaseUtils.getScanner(TABLE_NAME); if (scanner != null ) { scanner.forEach(result -> System.out.println(Bytes.toString(result.getRow()) + "->" + Bytes .toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name" ))))); scanner.close(); } } @Test public void getScannerWithFilter () { FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL); SingleColumnValueFilter nameFilter = new SingleColumnValueFilter(Bytes.toBytes(STUDENT), Bytes.toBytes("name" ), CompareOperator.EQUAL, Bytes.toBytes("Jack" )); filterList.addFilter(nameFilter); ResultScanner scanner = HBaseUtils.getScanner(TABLE_NAME, filterList); if (scanner != null ) { scanner.forEach(result -> System.out.println(Bytes.toString(result.getRow()) + "->" + Bytes .toString(result.getValue(Bytes.toBytes(STUDENT), Bytes.toBytes("name" ))))); scanner.close(); } } @Test public void deleteColumn () { boolean b = HBaseUtils.deleteColumn(TABLE_NAME, "rowKey2" , STUDENT, "age" ); System.out.println("删除结果: " + b); } @Test public void deleteRow () { boolean b = HBaseUtils.deleteRow(TABLE_NAME, "rowKey2" ); System.out.println("删除结果: " + b); } @Test public void deleteTable () { boolean b = HBaseUtils.deleteTable(TABLE_NAME); System.out.println("删除结果: " + b); } }
三、Java API 2.x 基本使用 3.1 新建Maven工程,导入项目依赖 这里选取的HBase Client
的版本为最新的2.1.4
。
1 2 3 4 5 <dependency > <groupId > org.apache.hbase</groupId > <artifactId > hbase-client</artifactId > <version > 2.1.4</version > </dependency >
3.2 API 的基本使用 2.x 版本相比于1.x 废弃了一部分方法,关于废弃的方法在源码中都会指明新的替代方法,比如,在2.x中创建表时:HTableDescriptor
和HColumnDescriptor
等类都标识为废弃,取而代之的是使用TableDescriptorBuilder
和ColumnFamilyDescriptorBuilder
来定义表和列族。
以下为HBase 2.x 版本Java API的使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 public class HBaseUtils { private static Connection connection; static { Configuration configuration = HBaseConfiguration.create(); configuration.set("hbase.zookeeper.property.clientPort" , "2181" ); configuration.set("hbase.zookeeper.quorum" , "hadoop001" ); try { connection = ConnectionFactory.createConnection(configuration); } catch (IOException e) { e.printStackTrace(); } } public static boolean createTable (String tableName, List<String> columnFamilies) { try { HBaseAdmin admin = (HBaseAdmin) connection.getAdmin(); if (admin.tableExists(TableName.valueOf(tableName))) { return false ; } TableDescriptorBuilder tableDescriptor = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName)); columnFamilies.forEach(columnFamily -> { ColumnFamilyDescriptorBuilder cfDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(columnFamily)); cfDescriptorBuilder.setMaxVersions(1 ); ColumnFamilyDescriptor familyDescriptor = cfDescriptorBuilder.build(); tableDescriptor.setColumnFamily(familyDescriptor); }); admin.createTable(tableDescriptor.build()); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean deleteTable (String tableName) { try { HBaseAdmin admin = (HBaseAdmin) connection.getAdmin(); admin.disableTable(TableName.valueOf(tableName)); admin.deleteTable(TableName.valueOf(tableName)); } catch (Exception e) { e.printStackTrace(); } return true ; } public static boolean putRow (String tableName, String rowKey, String columnFamilyName, String qualifier, String value) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(Bytes.toBytes(rowKey)); put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(qualifier), Bytes.toBytes(value)); table.put(put); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean putRow (String tableName, String rowKey, String columnFamilyName, List<Pair<String, String>> pairList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(Bytes.toBytes(rowKey)); pairList.forEach(pair -> put.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(pair.getKey()), Bytes.toBytes(pair.getValue()))); table.put(put); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } public static Result getRow (String tableName, String rowKey) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Get get = new Get(Bytes.toBytes(rowKey)); return table.get(get); } catch (IOException e) { e.printStackTrace(); } return null ; } public static String getCell (String tableName, String rowKey, String columnFamily, String qualifier) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Get get = new Get(Bytes.toBytes(rowKey)); if (!get.isCheckExistenceOnly()) { get.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier)); Result result = table.get(get); byte [] resultValue = result.getValue(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier)); return Bytes.toString(resultValue); } else { return null ; } } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName, FilterList filterList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); scan.setFilter(filterList); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static ResultScanner getScanner (String tableName, String startRowKey, String endRowKey, FilterList filterList) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Scan scan = new Scan(); scan.withStartRow(Bytes.toBytes(startRowKey)); scan.withStopRow(Bytes.toBytes(endRowKey)); scan.setFilter(filterList); return table.getScanner(scan); } catch (IOException e) { e.printStackTrace(); } return null ; } public static boolean deleteRow (String tableName, String rowKey) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Delete delete = new Delete(Bytes.toBytes(rowKey)); table.delete(delete); } catch (IOException e) { e.printStackTrace(); } return true ; } public static boolean deleteColumn (String tableName, String rowKey, String familyName, String qualifier) { try { Table table = connection.getTable(TableName.valueOf(tableName)); Delete delete = new Delete(Bytes.toBytes(rowKey)); delete.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(qualifier)); table.delete(delete); table.close(); } catch (IOException e) { e.printStackTrace(); } return true ; } }
四、正确连接Hbase 在上面的代码中,在类加载时就初始化了Connection连接,并且之后的方法都是复用这个Connection,这时我们可能会考虑是否可以使用自定义连接池来获取更好的性能表现?实际上这是没有必要的。
首先官方对于Connection
的使用说明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Connection Pooling For applications which require high-end multithreaded access (e.g., web-servers or application servers that may serve many application threads in a single JVM), you can pre-create a Connection, as shown in the following example: 对于高并发多线程访问的应用程序(例如,在单个JVM中存在的为多个线程服务的Web服务器或应用程序服务器), 您只需要预先创建一个Connection。例子如下: // Create a connection to the cluster. Configuration conf = HBaseConfiguration.create(); try (Connection connection = ConnectionFactory.createConnection(conf); Table table = connection.getTable(TableName.valueOf(tablename))) { // use table as needed, the table returned is lightweight }
之所以能这样使用,这是因为Connection并不是一个简单的socket连接,接口文档 中对Connection的表述是:
1 2 3 4 5 6 7 A cluster connection encapsulating lower level individual connections to actual servers and a connection to zookeeper. Connections are instantiated through the ConnectionFactory class. The lifecycle of the connection is managed by the caller, who has to close() the connection to release the resources. Connection是一个集群连接,封装了与多台服务器(Matser/Region Server)的底层连接以及与zookeeper的连接。 连接通过ConnectionFactory 类实例化。连接的生命周期由调用者管理,调用者必须使用close()关闭连接以释放资源。
之所以封装这些连接,是因为HBase客户端需要连接三个不同的服务角色:
Zookeeper :主要用于获取meta
表的位置信息,Master的信息;
HBase Master :主要用于执行HBaseAdmin接口的一些操作,例如建表等;
HBase RegionServer :用于读、写数据。
Connection对象和实际的Socket连接之间的对应关系如下图:
上面两张图片引用自博客:连接HBase的正确姿势
在HBase客户端代码中,真正对应Socket连接的是RpcConnection
对象。HBase使用PoolMap
这种数据结构来存储客户端到HBase服务器之间的连接。PoolMap
的内部有一个ConcurrentHashMap
实例,其key是ConnectionId
(封装了服务器地址和用户ticket),value是一个RpcConnection
对象的资源池。当HBase需要连接一个服务器时,首先会根据ConnectionId
找到对应的连接池,然后从连接池中取出一个连接对象。
1 2 3 4 5 6 7 8 9 10 11 12 @InterfaceAudience .Privatepublic class PoolMap <K , V > implements Map <K , V > { private PoolType poolType; private int poolMaxSize; private Map<K, Pool<V>> pools = new ConcurrentHashMap<>(); public PoolMap (PoolType poolType) { this .poolType = poolType; } .....
HBase中提供了三种资源池的实现,分别是Reusable
,RoundRobin
和ThreadLocal
。具体实现可以通hbase.client.ipc.pool.type
配置项指定,默认为Reusable
。连接池的大小也可以通过hbase.client.ipc.pool.size
配置项指定,默认为1,即每个Server 1个连接。也可以通过修改配置实现:
1 2 3 config.set("hbase.client.ipc.pool.type" ,...); config.set("hbase.client.ipc.pool.size" ,...); connection = ConnectionFactory.createConnection(config);
由此可以看出HBase中Connection类已经实现了对连接的管理功能,所以我们不必在Connection上在做额外的管理。
另外,Connection是线程安全的,但Table和Admin却不是线程安全的,因此正确的做法是一个进程共用一个Connection对象,而在不同的线程中使用单独的Table和Admin对象。Table和Admin的获取操作getTable()
和getAdmin()
都是轻量级,所以不必担心性能的消耗,同时建议在使用完成后显示的调用close()
方法来关闭它们。
五、总结 一起总结怎样通过Java来操作HBase数据吧!
先说说具体的API先,如下
HBaseConfiguration是每一个hbase client都会使用到的对象,它代表的是HBase配置信息。它有两种构造方式:
public HBaseConfiguration()
public HBaseConfiguration(final Configuration c)
默认的构造方式会尝试从hbase-default.xml和hbase-site.xml中读取配置。如果classpath没有这两个文件,就需要你自己设置配置。
Configuration HBASE_CONFIG = new Configuration();
HBASE_CONFIG.set(“hbase.zookeeper.quorum”, “zkServer”);
HBASE_CONFIG.set(“hbase.zookeeper.property.clientPort”, “2181″);
HBaseConfiguration cfg = new HBaseConfiguration(HBASE_CONFIG);
1. 创建表 创建表是通过HBaseAdmin对象来操作的。HBaseAdmin负责表的META信息处理。HBaseAdmin提供了createTable这个方法:
public void createTable(HTableDescriptor desc)
HTableDescriptor 代表的是表的schema, 提供的方法中比较有用的有
setMaxFileSize,指定最大的region size
setMemStoreFlushSize 指定memstore flush到HDFS上的文件大小
增加family通过 addFamily方法
public void addFamily(final HColumnDescriptor family)
HColumnDescriptor 代表的是column的schema,提供的方法比较常用的有
setTimeToLive:指定最大的TTL,单位是ms,过期数据会被自动删除。
setInMemory:指定是否放在内存中,对小表有用,可用于提高效率。默认关闭
setBloomFilter:指定是否使用BloomFilter,可提高随机查询效率。默认关闭
setCompressionType:设定数据压缩类型。默认无压缩。
setMaxVersions:指定数据最大保存的版本个数。默认为3。
2. 删除表 删除表也是通过HBaseAdmin来操作,删除表之前首先要disable表。这是一个非常耗时的操作,所以不建议频繁删除表。
disableTable和deleteTable分别用来disable和delete表。
3. 查询数据 查询分为单条随机查询和批量查询。
单条查询是通过rowkey在table中查询某一行的数据。HTable提供了get方法来完成单条查询。
批量查询是通过制定一段rowkey的范围来查询。HTable提供了个getScanner方法来完成批量查询。
public Result get(final Get get)
public ResultScanner getScanner(final Scan scan)
Get对象包含了一个Get查询需要的信息。它的构造方法有两种:
public Get(byte [] row)
public Get(byte [] row, RowLock rowLock)
Rowlock是为了保证读写的原子性,你可以传递一个已经存在Rowlock,否则HBase会自动生成一个新的rowlock。
Scan对象提供了默认构造函数,一般使用默认构造函数。
Get/Scan的常用方法有:
addFamily/addColumn:指定需要的family或者column,如果没有调用任何addFamily或者Column,会返回所有的columns.
setMaxVersions:指定最大的版本个数。如果不带任何参数调用setMaxVersions,表示取所有的版本。如果不掉用setMaxVersions,只会取到最新的版本。
setTimeRange:指定最大的时间戳和最小的时间戳,只有在此范围内的cell才能被获取。
setTimeStamp:指定时间戳。
setFilter:指定Filter来过滤掉不需要的信息
Scan特有的方法:
setStartRow:指定开始的行。如果不调用,则从表头开始。
setStopRow:指定结束的行(不含此行)。
setBatch:指定最多返回的Cell数目。用于防止一行中有过多的数据,导致OutofMemory错误。
ResultScanner是Result的一个容器,每次调用ResultScanner的next方法,会返回Result.
public Result next() throws IOException;
public Result [] next(int nbRows) throws IOException;
Result代表是一行的数据。常用方法有:
getRow:返回rowkey
raw:返回所有的key value数组。
getValue:按照column来获取cell的值
4. 插入数据 HTable通过put方法来插入数据。
public void put(final Put put) throws IOException
public void put(final List puts) throws IOException
可以传递单个批Put对象或者List put对象来分别实现单条插入和批量插入。
Put提供了3种构造方式:
public Put(byte [] row)
public Put(byte [] row, RowLock rowLock)
public Put(Put putToCopy)
Put常用的方法有:
add:增加一个Cell
setTimeStamp:指定所有cell默认的timestamp,如果一个Cell没有指定timestamp,就会用到这个值。如果没有调用,HBase会将当前时间作为未指定timestamp的cell的timestamp.
setWriteToWAL: WAL是Write Ahead Log的缩写,指的是HBase在插入操作前是否写Log。默认是打开,关掉会提高性能,但是如果系统出现故障(负责插入的Region Server挂掉),数据可能会丢失。
另外HTable也有两个方法也会影响插入的性能
setAutoFlash: AutoFlush指的是在每次调用HBase的Put操作,是否提交到HBase Server。默认是true,每次会提交。如果此时是单条插入,就会有更多的IO,从而降低性能.
setWriteBufferSize: Write Buffer Size在AutoFlush为false的时候起作用,默认是2MB,也就是当插入数据超过2MB,就会自动提交到Server
5. 删除数据 HTable 通过delete方法来删除数据。
public void delete(final Delete delete)
6. 切分表 HBaseAdmin提供split方法来将table 进行split.
public void split(final String tableNameOrRegionName)
如果提供的tableName,那么会将table所有region进行split ;如果提供的region Name,那么只会split这个region.
由于split是一个异步操作,我们并不能确切的控制region的个数。 Delete构造方法有:
public Delete(byte [] row)
public Delete(byte [] row, long timestamp, RowLock rowLock)
public Delete(final Delete d)
Delete常用方法有
deleteFamily/deleteColumns:指定要删除的family或者column的数据。如果不调用任何这样的方法,将会删除整行。
注意:如果某个Cell的timestamp高于当前时间,这个Cell将不会被删除,仍然可以查出来。
参考资料
连接HBase的正确姿势
Apache HBase ™ Reference Guide