java管理hbase

2020-05-04 331次浏览 已收录 2个评论

在HBase中想要获取一张表的基本信息需要用到一个类:TableDescriptor,通过它可以获取表的名字、列族等信息。

List<TableDescriptor> tableDescriptors = admin.listTableDescriptors();
tableDescriptor.getTableName() //可以获取表名
tableDescriptor.getColumnFamilies()//获取所有的列族

通过 <span class="typ">Admin</span></code>对象的 <code class="prettyprint prettyprinted"><span class="pln">listTableDescriptors</span><span class="pun">()</span></code>方法就可以获取到 <code class="prettyprint prettyprinted"><span class="typ">HBase</span></code>中所有 <code class="prettyprint prettyprinted"><span class="typ">TableDescriptor</span></code>对象的集合了。

最后可以通过 <code class="prettyprint prettyprinted"><span class="typ">Admin</span></code>对象知道表是否存在,以及是否可用:
<pre class="EnlighterJSRAW" data-enlighter-language="java">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)配置

<span class="typ">HBase</span></code>在存储数据的时候,会将数据切割成块来存储在集群中不同的位置。

块大小是 <code class="prettyprint prettyprinted"><span class="typ">HBase</span></code>的一个重要配置选项,默认块大小为 <code class="prettyprint prettyprinted"><span class="lit">65536</span><span class="pun">(</span><span class="lit">64K</span><span class="pun">)</span></code>,默认单位是字节,采用这种细粒度,目的是块操作时更加有效加载和缓存数据,对于不同的业务数据,块大小的合理设置对读写性能有很大的影响。而对块大小的调整,主要取决于两点:
<ol>
<li>用户平均读取数据的大小。理论上讲,如果用户平均读取数据的大小较小,建议将块大小设置较小,这样可以使得内存可以缓存更多 <code class="prettyprint prettyprinted"><span class="pln">block</span></code>,读性能自然会更好。相反,建议将块大小设置较大。随着 <code class="prettyprint prettyprinted"><span class="typ">BlockSize</span></code>的增大,系统随机读的吞吐量不断降低,延迟不断增大。对于以随机读为主的业务,可以适当调低 <code class="prettyprint prettyprinted"><span class="typ">BlockSize</span></code>的大小,以获得更好的读性能。对于以 <code class="prettyprint prettyprinted"><span class="pln">scan</span></code>为主的业务,可以适当增大 <code class="prettyprint prettyprinted"><span class="typ">BlockSize</span></code>的大小,以获得更好的读性能。可见,如果业务请求以 <code class="prettyprint prettyprinted"><span class="typ">Get</span></code>请求为主,可以考虑将块大小设置较小;如果以 <code class="prettyprint prettyprinted"><span class="typ">Scan</span></code>请求为主,可以将块大小调大;默认的 <code class="prettyprint prettyprinted"><span class="lit">64K</span></code>块大小是在 <code class="prettyprint prettyprinted"><span class="typ">Scan</span></code>和 <code class="prettyprint prettyprinted"><span class="typ">Get</span></code>之间取得的一个平衡。</li>
<li>数据平均键值对规模。</li>
</ol>
<span style="color: #800000;">设置缓存大小</span>
<pre class="EnlighterJSRAW" data-enlighter-language="java">ColumnFamilyDescriptorBuilder buildFamily = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("data"));//创建builder对象
buildFamily.setBlocksize(100000);//设置缓存大小

设置块缓存

设置缓存应该是一个要谨慎考虑的工作。

把数据放进读缓存,但工作负载却经常不能从中获得性能提升——例如,如果一张表或表里的列族只被顺序化扫描访问或者很少被访问,你不会介意 GetScan花费时间是否有点长。在这种情况下,你可以选择关闭那些列族的缓存。如果你只是执行很多顺序化扫描,你会多次倒腾缓存,并且可能会滥用缓存把应该放进缓存获得性能提升的数据给排挤出去。如果关闭缓存,你不仅可以避免上述情况发生,而且可以让出更多缓存给其他表和同一表的其他列族使用。

buildFamily.setBlockCacheEnabled(false);//设置关闭缓存,默认是true
激进缓存的配置

你可以选择一些列族,赋予它们在数据块缓存里有更高的优先级( <span class="pln">LRU</span></code>缓存)。如果你预期一个列族比另一个列族随机读更多,这个特性肯定能派上用场。

设置是否开启激进缓存:
<pre class="EnlighterJSRAW" data-enlighter-language="java">buildFamily.setInMemory(value); //默认是false

生存时间配置

TTL生存时间,当一个数据超过一定时间想要删掉,这个是以秒( s)为单位的,设置一个时间,超过后数据会被加上删除标记。

如何设置:

buildFamily.setTimeToLive(value); //以秒为单位,超过这个时间设置的就会在下一次大合并中被删除
压缩设置

压缩配置,可以提高 <span class="pln">CPU</span></code>的使用率,充分压榨 <code class="prettyprint prettyprinted"><span class="pln">CPU</span></code>的性能。

示例:
<pre class="EnlighterJSRAW" data-enlighter-language="java">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

删除列族

表中不需要的列族可以删掉,使用 <span class="pln">deleteColumnFamily</span><span class="pun">(</span><span class="typ">TableName</span><span class="pln"> tableName</span><span class="pun">,</span> <span class="kwd">byte</span><span class="pun">[]</span><span class="pln"> columnFamily</span><span class="pun">)</span></code>方法即可。
<pre class="EnlighterJSRAW" data-enlighter-language="java">admin.deleteColumnFamily(tableName, Bytes.toBytes("data"));//删除表中名为data的列族


测试:

  • 修改表 t_emp2
    • 修改列族 databolckSize1M
    • 关闭列族 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"));
 }
}
 }
}

禁用表、删除表、启用表

在获取了 <span class="typ">Admin</span></code>对象之后,直接使用 <code class="prettyprint prettyprinted"><span class="pln">disableTable</span><span class="pun">(</span><span class="typ">TableName</span><span class="pln"> tableName</span><span class="pun">)、</span><span class="pln">deleteTable</span><span class="pun">(</span><span class="typ">TableName</span><span class="pln"> tableName</span><span class="pun">)、</span><span class="pln">enableTable</span><span class="pun">(</span><span class="typ">TableName</span><span class="pln"> tableName</span><span class="pun">)</span></code>即可实现表的禁用、删除与启用操作。

示例,删除名为 <code class="prettyprint prettyprinted"><span class="pln">test</span></code>的表,启用名为 <code class="prettyprint prettyprinted"><span class="pln">demo</span></code>的表:
<pre class="EnlighterJSRAW" data-enlighter-language="java">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)//是否启用

渣渣龙, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java管理hbase
喜欢 (0)

您必须 登录 才能发表评论!

(2)个小伙伴在吐槽
  1. 我也是小白以后多多交流
    你哥2020-05-26 09:35
  2. 我加你了哦
    努力2020-05-26 10:01