HBase DDL操作
DDL操作主要是关于命名空间和表格的内容增删改查。
注:如果出现无法连接到zookeeper等的相关错误,可以将以下代码打jar包,在HMaster节点上执行
错误提示:
Exception in thread "main" java.net.SocketTimeoutException: callTimeout=1200000, callDuration=1200615: java.io.IOException: org.apache.zookeeper.KeeperException C o n n e c t i o n L o s s E x c e p t i o n : K e e p e r E r r o r C o d e = C o n n e c t i o n L o s s f o r / h b a s e / m a s t e r a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . R p c R e t r y i n g C a l l e r I m p l . c a l l W i t h R e t r i e s ( R p c R e t r y i n g C a l l e r I m p l . j a v a : 156 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . H B a s e A d m i n . e x e c u t e C a l l a b l e ( H B a s e A d m i n . j a v a : 2954 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . H B a s e A d m i n . e x e c u t e C a l l a b l e ( H B a s e A d m i n . j a v a : 2946 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . H B a s e A d m i n . c r e a t e N a m e s p a c e A s y n c ( H B a s e A d m i n . j a v a : 2111 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . A d m i n . c r e a t e N a m e s p a c e ( A d m i n . j a v a : 1657 ) a t o r g . h b a s e . H b a s e D D L . c r e a t e N a m e s p a c e ( H b a s e D D L . j a v a : 17 ) a t o r g . h b a s e . H b a s e D D L . m a i n ( H b a s e D D L . j a v a : 24 ) C a u s e d b y : o r g . a p a c h e . h a d o o p . h b a s e . M a s t e r N o t R u n n i n g E x c e p t i o n : j a v a . i o . I O E x c e p t i o n : o r g . a p a c h e . z o o k e e p e r . K e e p e r E x c e p t i o n ConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/master at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:156) at org.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:2954) at org.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:2946) at org.apache.hadoop.hbase.client.HBaseAdmin.createNamespaceAsync(HBaseAdmin.java:2111) at org.apache.hadoop.hbase.client.Admin.createNamespace(Admin.java:1657) at org.hbase.HbaseDDL.createNamespace(HbaseDDL.java:17) at org.hbase.HbaseDDL.main(HbaseDDL.java:24) Caused by: org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException ConnectionLossException:KeeperErrorCode=ConnectionLossfor/hbase/masteratorg.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:156)atorg.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:2954)atorg.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:2946)atorg.apache.hadoop.hbase.client.HBaseAdmin.createNamespaceAsync(HBaseAdmin.java:2111)atorg.apache.hadoop.hbase.client.Admin.createNamespace(Admin.java:1657)atorg.hbase.HbaseDDL.createNamespace(HbaseDDL.java:17)atorg.hbase.HbaseDDL.main(HbaseDDL.java:24)Causedby:org.apache.hadoop.hbase.MasterNotRunningException:java.io.IOException:org.apache.zookeeper.KeeperExceptionConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/master
at org.apache.hadoop.hbase.client.ConnectionImplementation M a s t e r S e r v i c e S t u b M a k e r . m a k e S t u b ( C o n n e c t i o n I m p l e m e n t a t i o n . j a v a : 1333 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . C o n n e c t i o n I m p l e m e n t a t i o n . g e t K e e p A l i v e M a s t e r S e r v i c e ( C o n n e c t i o n I m p l e m e n t a t i o n . j a v a : 1400 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . C o n n e c t i o n I m p l e m e n t a t i o n . g e t M a s t e r ( C o n n e c t i o n I m p l e m e n t a t i o n . j a v a : 1388 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . M a s t e r C a l l a b l e . p r e p a r e ( M a s t e r C a l l a b l e . j a v a : 57 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . R p c R e t r y i n g C a l l e r I m p l . c a l l W i t h R e t r i e s ( R p c R e t r y i n g C a l l e r I m p l . j a v a : 102 ) . . . 6 m o r e C a u s e d b y : j a v a . i o . I O E x c e p t i o n : o r g . a p a c h e . z o o k e e p e r . K e e p e r E x c e p t i o n MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1333) at org.apache.hadoop.hbase.client.ConnectionImplementation.getKeepAliveMasterService(ConnectionImplementation.java:1400) at org.apache.hadoop.hbase.client.ConnectionImplementation.getMaster(ConnectionImplementation.java:1388) at org.apache.hadoop.hbase.client.MasterCallable.prepare(MasterCallable.java:57) at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:102) ... 6 more Caused by: java.io.IOException: org.apache.zookeeper.KeeperException MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1333)atorg.apache.hadoop.hbase.client.ConnectionImplementation.getKeepAliveMasterService(ConnectionImplementation.java:1400)atorg.apache.hadoop.hbase.client.ConnectionImplementation.getMaster(ConnectionImplementation.java:1388)atorg.apache.hadoop.hbase.client.MasterCallable.prepare(MasterCallable.java:57)atorg.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:102)...6moreCausedby:java.io.IOException:org.apache.zookeeper.KeeperExceptionConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/master
at org.apache.hadoop.hbase.client.ConnectionImplementation.get(ConnectionImplementation.java:2208)
at org.apache.hadoop.hbase.client.ConnectionImplementation.access 500 ( C o n n e c t i o n I m p l e m e n t a t i o n . j a v a : 161 ) a t o r g . a p a c h e . h a d o o p . h b a s e . c l i e n t . C o n n e c t i o n I m p l e m e n t a t i o n 500(ConnectionImplementation.java:161) at org.apache.hadoop.hbase.client.ConnectionImplementation 500(ConnectionImplementation.java:161)atorg.apache.hadoop.hbase.client.ConnectionImplementationMasterServiceStubMaker.makeStubNoRetries(ConnectionImplementation.java:1294)
at org.apache.hadoop.hbase.client.ConnectionImplementation M a s t e r S e r v i c e S t u b M a k e r . m a k e S t u b ( C o n n e c t i o n I m p l e m e n t a t i o n . j a v a : 1327 ) . . . 10 m o r e C a u s e d b y : o r g . a p a c h e . z o o k e e p e r . K e e p e r E x c e p t i o n MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1327) ... 10 more Caused by: org.apache.zookeeper.KeeperException MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1327)...10moreCausedby:org.apache.zookeeper.KeeperExceptionConnectionLossException: KeeperErrorCode = ConnectionLoss for /hbase/master
at org.apache.zookeeper.KeeperException.create(KeeperException.java:102)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:54)
at org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient$ZKTask$1.exec(ReadOnlyZKClient.java:195)
at org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient.run(ReadOnlyZKClient.java:340)
at java.lang.Thread.run(Thread.java:748)
1.HBaseConnection
bash
package org.hbase;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import java.io.IOException;
public class HBaseConnection {
public static Connection connection =null;
//public static CompletableFuture<AsyncConnection> asyncConnectionCompletableFuture=null;
static {
//创建连接
//默认使用同步连接
try {
//读取本地文件
connection = ConnectionFactory.createConnection();
} catch (IOException e) {
e.printStackTrace();
}
//异步连接创建
//asyncConnectionCompletableFuture= ConnectionFactory.createAsyncConnection();
}
public static void closeConnection() throws IOException {
if(connection!=null){
connection.close();
}
}
public static void main(String[] args) throws IOException {
//使用连接
System.out.println(HBaseConnection.connection);
//关闭连接
HBaseConnection.closeConnection();
}
}
2.hbase-site.xml(请参考自己的配置文件)
bash
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://ns1/hbase</value>
</property>
<property>
<name>hbase.master.info.port</name>
<value>60010</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>bigdata111:2181,bigdata112:2181,bigdata113:2181</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/root/training/apache-zookeeper-3.7.1-bin/zkdata</value>
</property>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2181</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/root/training/hbase-2.4.17/tmp</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>
3.pom.xml
bash
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://ns1/hbase</value>
</property>
<property>
<name>hbase.master.info.port</name>
<value>60010</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>bigdata111:2181,bigdata112:2181,bigdata113:2181</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/root/training/apache-zookeeper-3.7.1-bin/zkdata</value>
</property>
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2181</value>
</property>
<property>
<name>hbase.tmp.dir</name>
<value>/root/training/hbase-2.4.17/tmp</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
<property>
<name>hbase.wal.provider</name>
<value>filesystem</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>
4.HbaseDDL
bash
package org.hbase;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class HbaseDDL {
public static Connection connection = HBaseConnection.connection;
/**
* @param namespace 输入的命名空间名称
**/
public static void createNamespace(String namespace) throws IOException {
// 获取admin
Admin admin = connection.getAdmin();
//指定buillder用于创建命名空间
NamespaceDescriptor.Builder builder = NamespaceDescriptor.create(namespace);
//对builder写入相关参数配置
builder.addConfiguration("user", "wunaiieq");
//admin使用builder完成创建
try {
admin.createNamespace(builder.build());
} catch (IOException e) {
System.out.println("此空间以存在");
e.printStackTrace();
}
// 关闭admin
admin.close();
}
/**
* 判断表格是否存在
*
* @param namespace 命名空间
* @param tableName 表名
* @return true 存在 false 不存在
**/
public static boolean isTableExists(String namespace, String tableName) throws IOException {
//获取admin
Admin admin = connection.getAdmin();
//使用方法判断
boolean b = false;
try {
b = admin.tableExists(TableName.valueOf(namespace, tableName));
} catch (IOException e) {
e.printStackTrace();
}
//连接关闭
admin.close();
//返回
return b;
}
/**
* 在HBase中创建一个新的表,并包含至少一个列族。
*
* @param namespace 命名空间名称,不能为空。
* @param tableName 表名称,不能为空。
* @param columnFamilies 列族名称,可变参数,可以具有多个,但必须至少提供一个列族。
* @throws IOException 如果命名空间或表已存在,或者发生其他I/O错误。
*
* @方法描述:
* 1. 首先检查列族数量,如果为0,则打印错误消息并返回。
* 2. 检查表是否已经存在,如果存在,则打印错误消息并返回。
* 3. 获取HBase的Admin对象,用于管理表。
* 4. 创建TableDescriptorBuilder,用于构建表的描述。
* 5. 遍历列族名称数组,为每个列族创建ColumnFamilyDescriptorBuilder,并设置最大版本数等参数。
* 6. 将每个构建好的列族描述添加到TableDescriptorBuilder中。
* 7. 使用Admin对象的createTable方法创建表。
* 8. 如果创建过程中发生IOException,打印错误堆栈并抛出异常。
* 9. 最后,关闭Admin对象以释放资源。
*
* @注意:
* - 确保在调用此方法之前,HBase连接已经建立且有效。
* - 如果命名空间不存在,HBase将自动创建它。
* - 创建表是一个潜在的风险操作,应在执行前进行充分的测试和验证。
*/
public static void createTable(String namespace, String tableName, String... columnFamilies) throws IOException {
// 检查列族数量
if (columnFamilies.length == 0) {
System.err.println("At least one column family must be specified.");
return;
}
// 检查表是否已经存在
if (isTableExists(namespace, tableName)) {
System.err.println("Table " + tableName + " already exists in namespace " + namespace + ".");
return;
}
// 获取HBase的Admin对象
Admin admin = connection.getAdmin();
try {
// 创建TableDescriptorBuilder,用于构建表的描述
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(TableName.valueOf(namespace, tableName));
// 遍历列族名称数组,为每个列族创建ColumnFamilyDescriptorBuilder,并设置参数
for (String columnFamily : columnFamilies) {
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(columnFamily));
// 设置列族的最大版本数,这里假设默认设置为3
columnFamilyDescriptorBuilder.setMaxVersions(3);
// 将构建好的列族描述添加到TableDescriptorBuilder中
tableDescriptorBuilder.setColumnFamily(columnFamilyDescriptorBuilder.build());
}
// 使用Admin对象的createTable方法创建表
admin.createTable(tableDescriptorBuilder.build());
} catch (IOException e) {
// 打印错误堆栈
e.printStackTrace();
// 抛出异常,让调用者可以处理
throw new IOException("Failed to create table " + tableName + " in namespace " + namespace, e);
} finally {
// 无论是否发生异常,都确保关闭Admin对象
admin.close();
}
}
/**
* 修改指定HBase表中列族的版本数。
*
* @param namespace 命名空间名称,不能为空。
* @param tableName 表名称,不能为空。
* @param columnFamily 列族名称,不能为空。
* @param version 要设置的最大版本数。
* @throws IOException 如果表不存在、列族不存在、命名空间不存在或发生其他I/O错误。
*
* @方法描述:
* 1. 首先获取HBase的Admin对象,用于管理表。
* 2. 使用Admin对象的getDescriptor方法获取指定命名空间和表名称的TableDescriptor。
* 3. 创建TableDescriptorBuilder,并初始化为当前表的描述,以确保保留现有配置。
* 4. 从TableDescriptor中获取指定列族的ColumnFamilyDescriptor。
* 5. 创建ColumnFamilyDescriptorBuilder,并初始化为当前列族的描述,以确保保留列族的其他配置。
* 6. 使用ColumnFamilyDescriptorBuilder的setMaxVersions方法设置列族的最大版本数。
* 7. 使用TableDescriptorBuilder的modifyColumnFamily方法将修改后的列族描述添加到表描述中。
* 8. 使用Admin对象的modifyTable方法应用修改后的表描述。
* 9. 如果修改过程中发生IOException,将抛出RuntimeException。
* 10. 最后,关闭Admin对象以释放资源。
*
* @注意:
* - 确保在调用此方法之前,HBase连接已经建立且有效。
* - 如果表或列族不存在,将抛出相应的异常。
* - 修改表结构是一个潜在的风险操作,应在执行前进行充分的测试和验证。
*/
public static void modifyTable(String namespace, String tableName, String columnFamily, int version) throws IOException {
// 获取HBase的Admin对象
Admin admin = connection.getAdmin();
//判断表格是否存在
if(isTableExists(namespace,tableName)){
System.out.println("Table not exists");
return;
}
try {
// 获取指定命名空间和表名称的TableDescriptor
TableDescriptor descriptor = admin.getDescriptor(TableName.valueOf(namespace, tableName));
// 创建TableDescriptorBuilder,并初始化为当前表的描述
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(descriptor);
// 从TableDescriptor中获取指定列族的ColumnFamilyDescriptor
ColumnFamilyDescriptor columnFamilyDescriptor = descriptor.getColumnFamily(Bytes.toBytes(columnFamily));
// 确保列族存在
if (columnFamilyDescriptor == null) {
throw new IllegalArgumentException("列族 " + columnFamily + " 不存在");
}
// 创建ColumnFamilyDescriptorBuilder,并初始化为当前列族的描述
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(columnFamilyDescriptor);
// 设置列族的最大版本数
columnFamilyDescriptorBuilder.setMaxVersions(version);
// 将修改后的列族描述添加到表描述中
tableDescriptorBuilder.modifyColumnFamily(columnFamilyDescriptorBuilder.build());
// 应用修改后的表描述
admin.modifyTable(tableDescriptorBuilder.build());
} catch (IOException e) {
// 抛出RuntimeException,让调用者可以捕获并处理
throw new RuntimeException("修改表时发生错误", e);
} finally {
// 无论是否发生异常,都确保关闭Admin对象
admin.close();
}
}
/**
* 删除指定的HBase表。
*
* @param namespace 命名空间
* @param tableName 表名
* @return true 表示删除成功,false 表示删除失败
* @throws IOException 如果操作过程中发生IO异常
*/
public static boolean deleteTable(String namespace,String tableName) throws IOException {
//判断存在
if(!isTableExists(namespace,tableName)){
System.out.println("Table not exists");
return false;
}
Admin admin =connection.getAdmin();
try {
//删除表格之前必须标记其未不可用
TableName tableName1 = TableName.valueOf(namespace, tableName);
admin.disableTable(tableName1);
admin.deleteTable(tableName1);
} catch (IOException e) {
throw new RuntimeException(e);
}
admin.close();
return true;
}
/**
* 全部注释,按需使用
* **/
public static void main(String[] args) throws IOException {
//创建空间
//createNamespace("wunaiieq");
//判断表存在
//System.out.println(isTableExists("bigdata", "student"));
//创建表
//createTable("wunaiieq", "teachers", "id", "age");
//modifyTable("wunaiieq","users","age",10);
//删除表
System.out.println(deleteTable("wunaiieq", "teachers"));
HBaseConnection.closeConnection();
}
}
运行效果
将代码打包部署于HMaster的节点上,运行jar文件即可
具体效果可以通过web端进行查看,端口为60010,ip替换即可
bash
http://192.168.80.113:60010/
其他说明
- 关于修改
修改必须先获取对原有表的描述,才能进行,结构如下