Hbase是面向列的分布式数据库,在实际开发和运维中,增删改查是最核心的基础操作。不同场景下我们可以选择不同的操作方式,下面分别介绍Shell命令和Java API两种实现路径。

一、Hbase Shell常用增删改查操作
Hbase自带的交互式Shell工具可以快速完成基础数据操作,适合运维调试和简单数据操作场景。
1. 新增(插入)数据
使用put命令可以向指定表的指定行、列族、列限定符插入数据,语法为put '表名','行键','列族:列名','值'。
# 向user表插入一行数据,行键为1001,列族info的列name值为张三 put 'user','1001','info:name','张三' # 继续向同一行的info列族插入age值 put 'user','1001','info:age','20'
2. 查询数据
Shell中查询数据常用get和scan命令,get查询单行数据,scan扫描全表或范围数据。
# 查询user表行键为1001的所有数据
get 'user','1001'
# 查询user表info列族下name列的数据
get 'user','1001','info:name'
# 扫描user表所有数据
scan 'user'
# 扫描行键范围在1001到1003之间的数据
scan 'user',{STARTROW=>'1001',ENDROW=>'1003'}3. 修改数据
Hbase的修改本质是覆盖写入,同一行键同一列的新值会覆盖旧值,使用put命令即可完成修改。
# 将行键1001的info:age值修改为22,覆盖原有值 put 'user','1001','info:age','22'
4. 删除数据
删除数据使用delete删除指定列,deleteall删除整行数据。
# 删除user表行键1001的info:age列 delete 'user','1001','info:age' # 删除user表行键1001的所有数据 deleteall 'user','1001'
二、Java API常用增删改查操作
实际开发中更多通过Java程序调用Hbase API完成数据操作,需要先引入对应的依赖,这里以Hbase 2.x版本为例。
1. 环境准备
首先在项目中引入Hbase客户端依赖,Maven配置如下:
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.4.9</version>
</dependency>2. 初始化连接
操作前需要先创建Hbase连接,示例代码如下:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import java.io.IOException;
public class HbaseUtil {
private static Connection connection;
// 初始化Hbase连接
public static Connection getConnection() throws IOException {
if (connection == null || connection.isClosed()) {
Configuration config = HBaseConfiguration.create();
// 设置Hbase集群Zookeeper地址,如果是本地测试可以写127.0.0.1
config.set("hbase.zookeeper.quorum", "127.0.0.1");
config.set("hbase.zookeeper.property.clientPort", "2181");
connection = ConnectionFactory.createConnection(config);
}
return connection;
}
}3. 新增(插入)数据
通过Put对象封装插入数据,调用Table的put方法完成插入。
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class HbaseInsert {
public static void insertData() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
// 创建Put对象,指定行键
Put put = new Put(Bytes.toBytes("1002"));
// 添加列数据,参数分别为列族、列名、值
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("李四"));
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("25"));
// 执行插入
table.put(put);
table.close();
System.out.println("数据插入完成");
}
}4. 查询数据
查询单行使用Get对象,扫描全表或范围使用Scan对象。
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.List;
public class HbaseQuery {
// 查询单行数据
public static void querySingleRow() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
// 创建Get对象,指定行键
Get get = new Get(Bytes.toBytes("1002"));
Result result = table.get(get);
// 遍历结果中的列
List<Cell> cells = result.listCells();
if (cells != null) {
for (Cell cell : cells) {
String family = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
String qualifier = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
System.out.println("列族:" + family + ",列名:" + qualifier + ",值:" + value);
}
}
table.close();
}
// 扫描全表数据
public static void scanAll() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
Scan scan = new Scan();
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
// 处理每一行结果,逻辑和单行查询类似
List<Cell> cells = result.listCells();
if (cells != null) {
for (Cell cell : cells) {
String rowKey = Bytes.toString(result.getRow());
String family = Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
String qualifier = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
String value = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
System.out.println("行键:" + rowKey + ",列族:" + family + ",列名:" + qualifier + ",值:" + value);
}
}
}
scanner.close();
table.close();
}
}5. 修改数据
Java API中修改同样是通过Put对象覆盖写入,和插入逻辑一致,新值会覆盖旧值。
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class HbaseUpdate {
public static void updateData() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
Put put = new Put(Bytes.toBytes("1002"));
// 覆盖原有info:age的值
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("26"));
table.put(put);
table.close();
System.out.println("数据修改完成");
}
}6. 删除数据
删除数据使用Delete对象,可以指定删除列或者整行。
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class HbaseDelete {
// 删除指定列
public static void deleteColumn() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
Delete delete = new Delete(Bytes.toBytes("1002"));
// 删除info列族的age列
delete.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"));
table.delete(delete);
table.close();
System.out.println("列删除完成");
}
// 删除整行
public static void deleteRow() throws IOException {
Connection connection = HbaseUtil.getConnection();
Table table = connection.getTable(TableName.valueOf("user"));
Delete delete = new Delete(Bytes.toBytes("1002"));
table.delete(delete);
table.close();
System.out.println("整行删除完成");
}
}三、操作注意事项
- Hbase没有传统关系型数据库的update语句,修改本质是新版本数据覆盖旧版本,默认保留多个版本数据,可通过配置调整版本数量。
- 删除操作在Hbase中实际是插入一条删除标记,数据不会立即从磁盘清除,会在后续合并过程中清理。
- 使用Java API操作后要及时关闭Table和Connection资源,避免资源泄露。
- 行键设计对Hbase查询性能影响极大,建议根据查询场景合理设计行键,避免热点问题。
以上就是Hbase增删改查的常用操作方式,用户可以根据实际场景选择Shell命令或者Java API实现对应的数据操作需求。