Hbase只适合查结果和存结果,不适合做数据分析。hive数仓适合数据分析
--单个启动
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start master
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start regionserver
HregionServer
HMaster
[atguigu@hadoop103 hbase]$ bin/hbase-daemon.sh stop master
--群起
[atguigu@hadoop102 hbase]$ bin/start-hbase.sh
[atguigu@hadoop102 hbase]$ bin/stop-hbase.sh
--进入hbase
[atguigu@hadoop102 hbase]$ bin/hbase shell(工作中很少用shell,一般用api)
如果启动报错,要修改配置文件。要先把hadoop和zookeeper上面的已经生成的hbase目录删除,再重新启动。
Hbase的数据模型
Namespace: 命名空间,相当于mysql的database
Region: 表的分段
Store: 列簇的存储单位[有几个列簇就有几个store]
列簇: 相当于mysql的列名,是hbase的table的表结构的一部分
rowkey: 相当于mysql的主键。按照字典序排序
Column: 列簇:列限定符
Cell: rowkey+列簇:列限定符+时间戳
hbase物理存储结构:
rowkey,列簇,列限定符,时间戳,type,value
完整架构
ZOOKEEPER:
1、Hmaster通过zookeeper监听regionserver状态
2、保存元数据meta表的位置
HMaster:
1、监听HRegionServer状态
2、负责region的分配以及故障转移还有负载均衡
3、负责表的创建、修改、删除
HRegionServer:
1、负责数据的增删改查
2、保管region,负责region的split,storeFile的compact
HRegionServer中保管Region[多个]。
Region中包含一个或者多个Store[有几个列簇就有几个store]
Store中包含memstore以及storeFile
memstore是一块内存区域,当达到一定的条件之后会进行flush,每次flush都会生成一个storeFile文件
StoreFile是以HFile[文件信息、文件元数据信息、文件索引信息、文件的元数据的索引信息]这种文件格式保存在HDFS
数据是写入memstore,但是如果直接写入memstore可能会丢失数据[当regionserver宕机],所以为了memstore的数据安全,会先将数据写入HLOG,HLOG的数据是保存在HDFS
常用shell命令
[atguigu@hadoop102 hbase]$ bin/hbase shell(工作中很少用shell,一般用api)
1、创建namespace: create_namespace ‘命名空间’
2、创建表: create ‘命名空间:表名’,‘列簇名1’,‘列簇名2’
3、查看所有的表: list
4、查看所有命令空间: list_namespace
5、查看表结构: describe ‘命名空间:表名’
6、插入数据: put ‘命名空间:表名’,‘rowkey’,‘列簇名:列限定符’,value
7、查询数据:
1、根据rowkey查询数据
1、查询正行数据: get ‘命名空间:表名’,‘rowkey’
2、查询单个列簇的数据: get ‘命名空间:表名’,‘rowkey’,‘列簇名’
3、查询单个Column的数据:get ‘命名空间:表名’,‘rowkey’,‘列簇名:列限定符’
2、扫描
1、查询整表数据; scan ‘命名空间:表名’
2、查询单个列簇:scan ‘命名空间:表名’,‘列簇名’
2、查询单个Column的数据:scan ‘命名空间:表名’,‘列簇名:列限定符’
8、删除数据
1、删除cell数据: delete ‘命名空间:表名’,rowkey,‘列簇名:列限定符’
2、删除正行数据: deleteall ‘命名空间:表名’,rowkey
9、更新数据
与插入一样
10、删除表
1、禁用表: disable ‘命名空间:表名’
2、删除表: drop ‘命名空间:表名’
11、删除命名空间
1、先删除命名空间下所有表
2、删命名空间: drop_namespace ‘命名空间’
12、清空表数据: truncate ‘命名空间:表名’
13、统计表数据条数: count ‘命名空间:表名’
14、修改表结构
1、新增列簇:
alter ‘命名空间:表名’,{NAME=>列簇名,VERSIONS=>版本}
2、修改列簇的版本号
alter ‘命名空间:表名’,NAME=>列簇名,VERSIONS=>版本
2.2.1 基础操作
1)进入HBase客户端命令行
[atguigu@hadoop102 hbase]$ bin/hbase shell
2)查看帮助命令
hbase(main):001:0> help
2.2.2 DDL
对表操作
Namespace,相当于mysql的库
Group name: namespace
Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables
help “create_namespace”
Group name: ddl
Commands: alter, alter_async, alter_status, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, list_regions, locate_region, show_filters
1)创建所有的命名空间
hbase(main):002:0> create_namespace ‘bigdata’
2)查看所有的命名空间
hbase(main):003:0> list_namespace
3)删除命名空间
hbase(main):004:0> drop_namespace ‘bigdata’
注意:命名空间下没有表才可以删除
4)创建表
help “create”
hbase(main):005:0> create ‘student’,‘info’ //在默认’default’命名空间下创建表
hbase(main):007:0> create ‘bigdata:student’,‘info’, ‘info2’ //在指定命名空间下创建表
库:表名,列名1,列名2
命名空间:表名,列簇1,列簇2
5)查看所有的表
hbase(main):009:0> list
6)查看表的详情
hbase(main):012:0> describe ‘bigdata:student’
7)修改表
(1)删除列族信息
hbase(main):011:0> alter ‘bigdata:student’,‘delete’=>‘info2’
(2)修改版本信息
hbase(main):022:0> alter ‘bigdata:student’,{NAME=>‘info’,VERSIONS=>3}
8)删除表
hbase(main):019:0> disable ‘student’
hbase(main):020:0> drop ‘student’
提示:如果直接drop表,会报错:ERROR: Table student is enabled. Disable it first.
2.2.3 DML
对数据操作
Group name: dml
Commands: append, count, delete, deleteall, get, get_counter, get_splits, incr, put, scan, truncate, truncate_preserve
1)插入数据到表
hbase(main):003:0> put ‘bigdata:student’,‘1001’,‘info:sex’,‘male’
hbase(main):004:0> put ‘student’,‘1001’,‘info:age’,‘18’
hbase(main):005:0> put ‘student’,‘1002’,‘info:name’,‘Janna’
hbase(main):006:0> put ‘student’,‘1002’,‘info:sex’,‘female’
hbase(main):007:0> put ‘student’,‘1002’,‘info:age’,‘20’
命名空间:表名,rowkey,列名(列簇+列限定符),值
2)Scan方式查看数据
(1)扫描全表
hbase(main):008:0> scan ‘bigdata:student’
(2)限定开始位置扫描全表
hbase(main):010:0> scan ‘student’,{STARTROW => ‘1001’}
(3)限定开始和结束位置扫描全表
hbase(main):009:0> scan ‘student’,{STARTROW => ‘1001’, STOPROW => ‘1001’}
(4)扫描全表数据(包含被标记删除或者应该被覆盖的数据)
hbase(main):037:0> scan ‘bigdata:student’, {RAW => true, VERSIONS => 10}
3)Get方式查看数据
默认只查最新的数据
(1)指定RowKey查询
hbase(main):014:0> get ‘student’,‘1001’
(2)指定RowKey+列族查询
hbase(main):015:0> get ‘student’,‘1001’,‘info’
(3)指定RowKey+列族+列名查询
hbase(main):015:0> get ‘student’,‘1001’,‘info:name’
(4)指定获取数据版本查询
hbase(main):022:0> get ‘student’,‘1001’,{COLUMN=>‘info:name’,VERSIONS=>3}
查询到name字段保存的三份数据
4)统计表数据行数
hbase(main):021:0> count ‘student’
统计rowkey行数
5)更新数据(实际上还是Put)
hbase(main):012:0> put ‘student’,‘1001’,‘info:name’,‘Nick’
hbase(main):013:0> put ‘student’,‘1001’,‘info:age’,‘100’
6)删除数据
(1)指定RowKey+列族+列名删除
hbase(main):025:0> delete ‘student’,‘1001’,‘info:name’
(2)指定RowKey+列族删除(上课试了不行)
hbase(main):027:0> delete ‘student’,‘1001’,‘info’
(3)指定RowKey删除
hbase(main):031:0> deleteall ‘student’,‘1001’
注意:使用的是deleteall命令而不是delete命令
7)清空表数据
hbase(main):018:0> truncate ‘student’
HBase代码
public class HbaseDemo {
Connection connection;
Admin admin;
Table table;
@Before
public void init() throws IOException {
//1.创建配置信息并配置
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum","hadoop102,hadoop103,hadoop104");
//2.获取与HBase的连接
connection = ConnectionFactory.createConnection(conf);
//3.获取DDL操作对象
admin = connection.getAdmin();
table = connection.getTable(TableName.valueOf("test:user"));
}
/**
* 创建命名空间
* admin.createNamespace(namespaceDescriptor)
*/
@Test
public void createNamespace() throws IOException {
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create("test").build();
admin.createNamespace(namespaceDescriptor);
}
/**
* 创建表
* admin.createTable(tableDescriptor)
* @throws IOException
*/
@Test
public void creatTable() throws IOException {
TableName tableName = TableName.valueOf("test:user");
ColumnFamilyDescriptor family1 = ColumnFamilyDescriptorBuilder.newBuilder("base_info".getBytes()).build();
ColumnFamilyDescriptor family2 = ColumnFamilyDescriptorBuilder.newBuilder("extra_info".getBytes()).build();
TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
//设置列簇
.setColumnFamily(family1).setColumnFamily(family2)
.build();
admin.createTable(tableDescriptor);
}
/**
* 插入数据
* connection.getTable(tableName)
* @throws IOException
*/
@Test
public void put() throws IOException{
//3、数据插入
//put '表','rowkey','列簇;列限定符','值'
Put put = new Put("1001".getBytes())