1.HBase 架构
============================================
2. HBase Shell 操作
2.1. 基本操作
- 进入HBase客户端命令行:
bin/hbase shell
- 查看帮助命令:
help
- 查看当前数据库中有哪些表:
list
2.2. 表的操作
// 2.2.1. 创建表 create 'student','info'(列族) // 2.2.2. 插入数据到表 put 'student','1001','info:sex','male' put 'student','1001','info:age','18' put 'student','1002','info:name','Janna' put 'student','1002','info:sex','female' put 'student','1002','info:age','20' // 2.2.3. 扫描查看表数据 scan 'student' scan 'student',{STARTROW => '1001', STOPROW => '1004'} scan 'student',{STARTROW => '1001'} // 2.2.4. 查看表结构 describe 'student' // 2.2.5. 更新指定字段的数据 put 'student','1001','info:name','zhangsan' put 'student','1001','info:age','22' // 2.2.6. 查看“指定行”或“指定列族:列”的数据 get 'student','1001' get 'student','1001','info:name' // 2.2.7. 统计表数据行数 count 'student' // 2.2.8. 删除数据: // 删除某rowkey的全部数据 deleteall 'student','1001' // 删除某rowkey的某一列数据 delete 'student','1002','info:sex' // 2.2.9. 清空表数据 // 清空表的操作顺序为先disable, 然后再 truncate truncate 'student' // 2.2.10. 删除表 // 先让该表为 disable 状态 disable 'student' // 然后才能 drop 这个表 drop 'student' // 2.2.11 变更表信息 // 将info列族中的数据存放3个版本 alter 'student',{NAME=>'info',VERSIONS=>3} get 'student','1001',{COLUMN=>'info:name',VERSIONS=>3}
3. HBase 数据结构
3.1 RowKey
- RowKey 可以是任意字符串(最大长度是64KB,实际应用中长度一般为10-100bytes),在HBASE内部,RowKey 保存为字节数组。存储时,数据按照 RowKey 的字典序排序存储。设计 RowKey 时,要充分考虑排序存储这个特性,将经常一起读取的行存储在一起。(位置相关性)
- RowKey 是用来检索记录的主键。访问HBase table中的行,有三种方式:
- 通过单个 RowKey 访问;
- 通过 RowKey 的 range(正则)
- 全表扫描
3.2 Column Family
- 列族:HBASE 表中的每个列,都归属于某个列族。列族是表的 schema 的一部分(而列不是)。必须在使用表之前定义。列名都以列族作为前缀。例如:courses:history, courses:math 都属于 courses 这个列族。
3.3 Cell
- 由(rowkey, column Family:column, version)唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存储。
3.4 TimeStamp
- 版本通过时间戳来索引;
3.5 命名空间
- Table: 表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在 default 默认的命名空间中;
- RegionServer group:一个命名空间包含了默认的 RegionServer Group;
- Permission: 权限。命名空间能够让我们来定义访问控制列表ACL(Access Control List);
- Quota:限额,可以强制一个命名空间可包含的 region 数量;
- 常用命令:
- 查看命名空间:
list_namespace
; - 创建命名空间:
create_namespace 'bigdata'
; - 在指定命名空间下,创建表:
create 'bigdata:student','info'
; - 删除命名空间:
drop_namespace 'bigdata'
;
- 查看命名空间:
4. HBase 原理
4.1 读流程
=========================
4.2 写流程
- Client 向 HregionServer 发送写请求;
- HregionServer 将数据写到 HLog(write ahead log)。为了数据的持久化和恢复;
- HregionServer 将数据写到内存(MemStore);
- 反馈 Client 写成功;
=========================
4.3 数据flush过程
- 当 MemStore 数据达到阈值(默认是 128M,老版本是 64M),将数据刷到磁盘,将内存中的数据删除,同时删除HLog中的历史数据;
- 将数据存储到HDFS中;
- 在HLog中做标记点;
4.4 数据合并过程
- 当数据块达到4块,Hmaster 触发合并操作, Region 将数据块加载到本地,进行合并;
- 当合并的数据超过 256M, 进行拆分,将拆分后的 Region 分配给不同的 HregionServer 管理;
- 当 HregionServer 宕机后,将 HregionServer 上的 hlog拆分,然后分配给不同的 HregionServer 加载,修改 META;
- 注意:HLog 会同步到 HDFS;
5. HBase API 操作
5.1 环境准备
// pom.xml <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-server</artifactId> <version>1.3.4</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.3.4</version> </dependency> <dependencies>
5.2 程序编写
public class TestHbase { private static Admin admin = null; private static Connection connection = null; private static Configuration configuration = null; static { // HBase 配置文件 configuration = HBaseConfiguration.create(); // zookeeper 配置 configuration.set("hbase.zookeeper.quorum", "Zookeeper地址"); configuration.set("hbase.zookeeper.property.clientPort", "2181"); // 获取连接对象 try { connection = ConnectionFactory.createConnection(configuration); admin = connection.getAdmin(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void close(Connection conn, Admin admin) { if (conn != null) { try { conn.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (admin != null) { try { admin.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } // 判断表是否存在 @Test public void tableExist() throws IOException { // 执行操作 Boolean student = admin.tableExists(TableName.valueOf("student")); System.out.println("表Staff是否存在:"+student); Boolean staff = admin.tableExists(TableName.valueOf("staff")); System.out.println("表Staff是否存在:"+staff); this.close(connection, admin); } // 创建表 @Test public void createTable() throws IOException { // 创建表描述器 HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("country")); // 创建列描述器 HColumnDescriptor hColumnDescriptor = new HColumnDescriptor("name"); // 添加列族 hTableDescriptor.addFamily(hColumnDescriptor); // 创建表操作 admin.createTable(hTableDescriptor); System.out.println("表已经创建成功!"); this.close(connection, admin); } // 删除表 @Test public void deleteTable() throws IOException { // 使表不可用 admin.disableTable(TableName.valueOf("country")); // 删除表 admin.deleteTable(TableName.valueOf("country")); System.out.println("表已经删除成功!"); this.close(connection, admin); } // 操作表中数据: // 增/改数据 @Test public void putData() throws IOException { // 获取table对象 Table table = connection.getTable(TableName.valueOf("student")); // 创建put对象 Put put = new Put(Bytes.toBytes("1010")); // 添加数据 put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("貂蝉")); // 执行添加操作 table.put(put); System.out.println("数据添加成功!"); this.close(connection, admin); } // 删除数据 @Test public void deleteData() throws IOException { // 获取table对象 Table table = connection.getTable(TableName.valueOf("student")); // 创建delete对象 Delete delete = new Delete(Bytes.toBytes("1010")); // 第一种方式:不建议使用,只是删除最新版本 // delete.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name")); // 第二种方式:删除所有版本 delete.addColumns(Bytes.toBytes("info"), Bytes.toBytes("name")); // 删除数据 table.delete(delete); System.out.println("数据删除成功!"); table.close(); this.close(connection, admin); } // 查询数据 // 全表扫描 @Test public void scanTable() throws IOException { Table table = connection.getTable(TableName.valueOf("student")); // 构建扫描器 Scan scan = new Scan(); ResultScanner results = table.getScanner(scan); for(Result result : results) { Cell[] cells = result.rawCells(); for (Cell cell : cells) { System.out.println("RK:" + Bytes.toString(CellUtil.cloneRow(cell)) + ",CF:" + Bytes.toString(CellUtil.cloneFamily(cell)) + ",CN:" + Bytes.toString(CellUtil.cloneQualifier(cell)) + ",VALUE:" + Bytes.toString(CellUtil.cloneValue(cell))); } } table.close(); this.close(connection, admin); } // 获取指定列族:列的数据 @Test public void scanColumnFamily() throws IOException { Table table = connection.getTable(TableName.valueOf("student")); // 创建get对象 Get get = new Get(Bytes.toBytes("1001")); Result result = table.get(get); Cell[] cells = result.rawCells(); for (Cell cell : cells) { System.out.println("RK:" + Bytes.toString(CellUtil.cloneRow(cell)) + ",CF:" + Bytes.toString(CellUtil.cloneFamily(cell)) + ",CN:" + Bytes.toString(CellUtil.cloneQualifier(cell)) + ",VALUE:" + Bytes.toString(CellUtil.cloneValue(cell))); } } }
参考资料:
- ubuntu 16.04 开放指定端口
- HBase 单机启动问题
- hadoop +zookeeper + hbase 单节点安装
- Windows 环境下,出现“UnknownHostException”
来源:https://www.cnblogs.com/linkworld/p/10963910.html