在HBase中想要获取一张表的基本信息需要用到一个类:TableDescriptor,通过它可以获取表的名字、列族等信息。
List<TableDescriptor> tableDescriptors = admin.listTableDescriptors(); tableDescriptor.getTableName() //可以获取表名 tableDescriptor.getColumnFamilies()//获取所有的列族
通过 Admin
对象的 listTableDescriptors()
方法就可以获取到 HBase
中所有 TableDescriptor
对象的集合了。
最后可以通过 Admin
对象知道表是否存在,以及是否可用:
admin.tableExists(tableName) //存在返回true admin.isTableEnabled(tableName) //可用返回true
测试:
列出hbase中所有表的表明、表是否存在、表是否可用。
package step1; import java.util.ArrayList; import java.util.List; import org.apache.hadoop.conf.*; import org.apache.hadoop.hbase.*; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.util.*; public class Task { public void showTableList() throws Exception { Configuration conf = HBaseConfiguration. create(); Connection connection = ConnectionFactory.createConnection (conf); Admin admin = connection. getAdmin(); try{ List<TableDescriptor> tableDescriptors = admin.listTableDescriptors (); for (TableDescriptor tableDescriptor : tableDescriptors) { TableName tableName = tableDescriptor.getTableName (); System.out.println ("Table:"+ tableName); System.out.println("\texists:"+ admin.tableExists (tableName)); System.out.println ("\tenabled:"+ admin.isTableEnabled(tableName)); } } finally { admin.close(); } } }
块大小(blocksize)配置
HBase
在存储数据的时候,会将数据切割成块来存储在集群中不同的位置。
块大小是 HBase
的一个重要配置选项,默认块大小为 65536(64K)
,默认单位是字节,采用这种细粒度,目的是块操作时更加有效加载和缓存数据,对于不同的业务数据,块大小的合理设置对读写性能有很大的影响。而对块大小的调整,主要取决于两点:
- 用户平均读取数据的大小。理论上讲,如果用户平均读取数据的大小较小,建议将块大小设置较小,这样可以使得内存可以缓存更多
block
,读性能自然会更好。相反,建议将块大小设置较大。随着BlockSize
的增大,系统随机读的吞吐量不断降低,延迟不断增大。对于以随机读为主的业务,可以适当调低BlockSize
的大小,以获得更好的读性能。对于以scan
为主的业务,可以适当增大BlockSize
的大小,以获得更好的读性能。可见,如果业务请求以Get
请求为主,可以考虑将块大小设置较小;如果以Scan
请求为主,可以将块大小调大;默认的64K
块大小是在Scan
和Get
之间取得的一个平衡。 - 数据平均键值对规模。
设置缓存大小
ColumnFamilyDescriptorBuilder buildFamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data"));//创建builder对象 buildFamily.setBlocksize(100000);//设置缓存大小
设置块缓存
设置缓存应该是一个要谨慎考虑的工作。
把数据放进读缓存,但工作负载却经常不能从中获得性能提升——例如,如果一张表或表里的列族只被顺序化扫描访问或者很少被访问,你不会介意 Get
或 Scan
花费时间是否有点长。在这种情况下,你可以选择关闭那些列族的缓存。如果你只是执行很多顺序化扫描,你会多次倒腾缓存,并且可能会滥用缓存把应该放进缓存获得性能提升的数据给排挤出去。如果关闭缓存,你不仅可以避免上述情况发生,而且可以让出更多缓存给其他表和同一表的其他列族使用。
buildFamily.setBlockCacheEnabled(false);//设置关闭缓存,默认是true
激进缓存的配置
你可以选择一些列族,赋予它们在数据块缓存里有更高的优先级( LRU
缓存)。如果你预期一个列族比另一个列族随机读更多,这个特性肯定能派上用场。
设置是否开启激进缓存:
buildFamily.setInMemory(value); //默认是false
生存时间配置
TTL
生存时间,当一个数据超过一定时间想要删掉,这个是以秒( s
)为单位的,设置一个时间,超过后数据会被加上删除标记。
如何设置:
buildFamily.setTimeToLive(value); //以秒为单位,超过这个时间设置的就会在下一次大合并中被删除
压缩设置
压缩配置,可以提高 CPU
的使用率,充分压榨 CPU
的性能。
示例:
buildFamily.setCompressionType(Compression.Algorithm.NONE);//默认是NONE
单元时间版本
HBase
可以设置多个时间版本,也可以获取多个版本中的数据,我们在设置的时候要根据业务来划分,版本是历史记录,版本增多意味更大的空间消耗。
buildFamily.setMinVersions(0); buildFamily.setMaxVersions(5);
测试:将test数据表的data列族块大小设置为2M
TableName tableName = TableName.valueOf("test"); ColumnFamilyDescriptorBuilder buildFamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data"));//构建Builder对象 buildFamily.setBlocksize(1024*1024*2); ColumnFamilyDescriptor family = buildFamily.build();//构建Family对象 admin.modifyColumnFamily(tableName, family);//调用修改方法,方法接收两个参数:TableName,ColumnFamilyDescriptor
删除列族
表中不需要的列族可以删掉,使用 deleteColumnFamily(TableName tableName, byte[] columnFamily)
方法即可。
admin.deleteColumnFamily(tableName, Bytes.toBytes("data"));//删除表中名为data的列族
测试:
- 修改表
t_emp2
;- 修改列族
data
的bolckSize
为1M
; - 关闭列族
data
的块缓存; - 设置列族
data
的压缩格式为GZ
;
- 修改列族
- 修改表
t_dept2
;- 设置列族
data1
的最小单元时间版本为2
,最大时间版本为5
; - 开启列族
data1
的激进缓存策略; - 设置列族
data1
的生存时间为一天
;
- 设置列族
- 删除表
t_emp2
的列族data1
; - 删除表
t_dept2
的列族data
。
import java.io.IOException; import org.apache.hadoop.conf.*; import org.apache.hadoop.hbase.*; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.io.compress.Compression; import org.apache.hadoop.hbase.util.*; public class Task { public void updateTables()throws Exception{ Configuration config = new Configuration(); Connection conn = ConnectionFactory.createConnection(config); Admin admin = conn.getAdmin() ; String[] tableNames = { "t_emp2" , "t_dept2"}; for (int i = 0; i < tableNames.length; i++) { TableName tableName = TableName.valueOf(Bytes.toBytes(tableNames[i])); if(i == 0) { ColumnFamilyDescriptorBuilder buildFamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data")); buildFamily.setBlockCacheEnabled(false); buildFamily.setBlocksize(1024*1024*1); buildFamily.setCompressionType(Compression.Algorithm.GZ); ColumnFamilyDescriptor family = buildFamily.build() ; admin.modifyColumnFamily(tableName, family); admin.deleteColumnFamily(tableName, Bytes.toBytes("data1") ); }else{ ColumnFamilyDescriptorBuilder buildFamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes ("data1")); buildFamily.setMinVersions(2); buildFamily.setMaxVersions(5); buildFamily.setInMemory(true); buildFamily.setTimeToLive(60*60*24); ColumnFamilyDescriptor family = buildFamily.build(); admin.modifyColumnFamily (tableName, family); admin.deleteColumnFamily (tableName, Bytes.toBytes("data")); } } } }
禁用表、删除表、启用表
在获取了 Admin
对象之后,直接使用 disableTable(TableName tableName)、deleteTable(TableName tableName)、enableTable(TableName tableName)
即可实现表的禁用、删除与启用操作。
示例,删除名为 test
的表,启用名为 demo
的表:
Configuration config = new Configuration(); Connection conn = ConnectionFactory.createConnection(config); Admin admin = connection.getAdmin(); TableName testName = TableName.valueOf(Bytes.toBytes("test")); TableName demoName = TableName.valueOf(Bytes.toBytes("test")); admin.disableTable(testName); admin.deleteTable(testName); admin.enableTable(demoName);
验证数据表是否是禁用状态、存在、启用。
admin.isTableDisabled(tableName)//是否禁用 admin.tableExists(tableName)//是否存在 admin.isTableEnabled(tableName)//是否启用
我也是小白以后多多交流
我加你了哦