一、回顾
-》应用场景
为了解决大数据实时存储而诞生的(hive/hdfs都是离线文件存储)
-》归档存储
-》搜索引擎
-》数据实时读写
公司大数据数据开发都会用HBase或者类似于NoSQL数据库,从整体的性能来说HBase
会更加优秀一点.
启动hadoop:
启动Zookeeper:
HBase存储路径:
Hbase特点
基于HDFS
HBase诞生的原因:
NOSQL读写速度很快但是只能用于小规模的数据量(传统数据库会将NoSQL作为缓存)
HDFS可以存储大数据,但是读写速度不能进行实时存储
将两者的优点合二为一就诞生了HBase
HDFS解决大数据存储(分布式)的唯一方案
-》快速读写:积极使用内存
这与NoSql相似
hdfs是文件存储系统,,存储hdfs说白了还是存储到磁盘中,所以如果
想读写速度快,必然要积极使用内存
读:读数据会到内存中读,如果数据不在的话,才会到文件中读
写:写的时候回先写到内存中去,然后由内存自动写入hdfs中去
NoSQL数据库
一般都有自己的语言,不支持SQL
例如:redis/mongodb
分布式
-》底层基于hdfs
-》主从架构
master:主节点,主要负责管理
regionserver:从节点,负责对于数据的读写存储
-》依赖于zookeeper
-》hbase元数据
类似于hive想对那张表进行分析,就得查找元数据,然后再进行处理
hbase的元数据存储在zookeeper中,客户端先连接zookeeper,
zookeeper告诉客户端要查找的数据在哪
-》通过zookeeper实现高可用HA
HBase也有单点问题,如果master宕机还需要有备份的master
列存储
-》如果该列没有值,则该行没有该列,hbase中的每行的列可以不一样
-》hbase基本结构
mysql hbase
database namespace
table table
主键 行健
列簇
列 列标签
timestamp timestamp
value value
-》列簇:将拥有相似读写属性的列进行分组,名称任意,一般不超过3个
-》hbase存储结构
-》key:rowkey+cf+column+timestamp
-》value:cell
二、Hbase的数据库操作
启动hbase
-》hadoop
-》zookeeper
-》hbase
bin/start-hbase.sh
配置过免秘钥登录,没有配置按照Day26中的启动方式
进入客户端
bin/hbase shell
DDL
namespace
注意:对于hbase的namespace,你可以直接理解为表名的一部分
只要访问非默认namespace下的表,都需要使用namespace:tablename的方式来操作
创建namespace
create_namespace 'ns_name';
create_namespace 'ns2';
列举所有namespace
list_namespace
删除namespace
drop_namespace 'ns_name'
查看namespace
describe_namespace
查看时候可以给出许多的属性值:
table
创建
--help create;
语法:create 'ns:tbname','cf1','cf2'
create 'ns:tbname', {NAME => 'cf'}
注意:
1-如果表名不加namespace,默认是默认的namespace:default
2-创建表时,至少要有一个列簇
3-创建表时,不需要给列,hbase按列存储,在存储时才给列
4-不同的namespace下,表名可以相同
如果表名不加namespace,默认是默认的namespace:default:
查看namespace:
列举
list:默认列举当前hbase中所有的用户表
删除
drop 'ns:tbname'
drop 'ts2'
注意:
1-在hbase中如果想要删除一张表
-》先禁用该表,将该表下线,不允许再进行读写
-》再将下线的表进行删除
2-在公司中如果需要变更或者删除表,都需要先禁用
-》如果是变更,记住,变更完成之后,要启用表
-》先停用表
disable 'ts2'
-》删除表
drop 'ts2'
-》变更后要启动表
enable 'tbname'
-》描述
describe 'tbname'
desc 'tbname'
-》修改
help alter
alter
DML
增
put :插入一条(列),如果一个rowkey中有多列,那需要插入多条
put 'ns:tbname','rowkey','cf:column','value'
put 'ns1:order','08530371_2015-04-21 00:00:25_314295453731663','info:date','2015-04-21 00:00:21'
删
help delete
delete:删除某一列
delete 'ns1:t1', 'r1', 'cf:c1', ts1
delete 'ns1:t1', 'r1'
deleteall 't1', 'r1':用于删除整行的内容
清空
truncate
修改
hbase中没有更新的命令
put : 使用插入命令进行更新操作
当前更新的值会覆盖原来的值
原先的值:
08530371_2015-04-21 00:00:25_314295453731663 column=info:date, timestamp=1528185357875, value=2015-04-21 00:00:21
put 'ns1:order','08530371_2015-04-21 00:00:25_314295453731663','info:date','2015-05-21 00:00:21'
修改后的值:
08530371_2015-04-21 00:00:25_314295453731663 column=info:date, timestamp=1528185750000, value=2015-05-21 00:00:21
注意:
-》多版本情况下执行了更新
-》老的版本的值依旧存在,在查询时,显示最新版本的值
-》默认情况下:版本只存1份
-》针对每个列簇中的列可以指定多个版本
查看多版本
创建表的时候针对不同的列簇设置版本个数:
create 'ns:tbname', {NAME => 'cf1',VERSIONS => 4},{NAME => 'cf2',VERSIONS => 1}
-》对于hbase中所有的删除或者更新操作,不是立刻执行的,只是打了标签立刻返回
相当于关系数据库中的逻辑删除,打了标签没有真正删除
查询
Hbase中的rowkey是唯一的查询索引(rowkey的设计)
rowkey设计的好坏会影响到查询的效率
-》get :获取一行的数据,一列是一条,一行有多条
-》最快的查询方式,但很少用,专门针对于某一个rowkey的查询
get 'ns1:t1', 'r1'
读某个rowkey
get 't1', 'r1', {COLUMN => 'c1'}
读某个rowkey的某一列
get 't1', 'r1', {COLUMN => ['c1', 'c2', 'c3']}
读某个rowkey的多列
查询
只查询某一列:
scan:全表扫描,一般来说不用
大数据数量太多,全表扫描性能太低
scan 'ns:tbname'
scan+filter:最常用的方式,性能仅次于get
STARTROW:起始位置 STOPROW:结束位置
scan 'ns1:order', {STARTROW => '40419271_2015-04-21 00:00:21_314295453511152'}
scan 'ns1:order', {STARTROW => '40419271',STOPROW => ''}
注意:
01-hbase中所有数据的读写都是依赖rowkey来进行数据读写
02-hbase所有的数据读写都是前缀匹配 相当于40419271%
count统计行数
整张表中有多少行(rowkey)
面试题:在hbase中如何最快的统计出一张表中有多少行
-》1、SQL语句(用Hive集成HBase)--慢
-》2、count 'ns:tbname'--快
-》3、协处理器--最快
三、Hbase的数据来源
3.1 将数据导入hbase表
put插入数据的速度很慢,一条语句只能插入一列
下面推荐了三种方法导入数据(工作中偏向于后两种,最常用的是第二种)
-》1、kettle:ETL工具
-》2、sqoop/flume:将结构化数据或者半结构化数据往HBase中存
-》3、Java application/MapReduce/spark
这里提供了HBASE API 接口写入HBASE
Put对象,写入HBASE
3.2 通过sqoop将Mysql中数据导入到HBase表中
修改sqoop_env.sh
Sqoop是将MySql与HBase、hive、hdfs三者的导入导出
实现:将订单表从mysql中导入到hbase
bin/sqoop import \
--connect jdbc:mysql://bigdata-training01.erongda.com:3306/dingdan \
--username root \
--password 123456 \
--table so \
--split-by rk \
--columns date,order_id,user_id,order_amt,order_id_new,rk \
--hbase-create-table \
--hbase-table ns1:order02 \
--hbase-row-key rk \
--column-family info \
-m 2
解析:
--hbase-create-table \ 如果表不存在,就会帮助创建表
--split-by rk \ 如果MySQL表中没有主键,可以通过这个参数来指定
--columns 指定导入的列
-m 2 使用两个MapReduce
报错原因:MySQL这张so表中没有主键
指定了两个mapReduce处理数据,必然一个MapReduce只能处理一部分数据。
数据是通过主键来切分,没有主键就无法切割数据。
解决方案:1、--split-by rk \
2、将-m2改为-m1
统计插入表的数据:
查看某一条rowKey的数据:
四、Hbase基本存储架构
这是主从节点,一般DataNode,NodeManager、RegionServer都是在同一台机器上
排列的顺序
-》hbase中所有的读写依赖于rowkey
-》在hbase中:rowkey和列标签写入后都按照字典顺序进行排序了
解析:1、排序并不是插入的先后顺序,而是rowkey的字典顺序(按照rowkey排序)
2、同一个rowkey的数据排序是按照列名字典排序
region
-》Hbase底层存储:keyvalue
-》region:hbase中的分区,hbase按照rowkey划分region
是hbase中regionserver存储的最小单元
table:order
[start,stop)
00-02 rowkey region1
02-04 rowkey region2
04-06 rowkey region3
06-08 rowkey region4
-》数据写入时,按照rowkey写入到对应的region中
01234343433_dfldlkfjd region1
-》读取数据时,根据rowkey的信息到对应的region中取
01234343433_dfldlkfjd
存储结构:
regionserver:负责存储每个region
1、有4个Region,有三个Regsion Server
Region1、Region2 存放到 Region Server 7
Region3 存放到 Region Server86
Region4 存放到 Region Server367
2、Region是regionserver中最小的移动单元意思是region:
regionserver中最小的移动单元不能将region的某一条数据放到regionServer中,
只能将整个region放入regionServer中去
1、一张表一开始只有一个分区,等数据越来越大时候,就会分裂成多个分区.
2、也可以创建表的时候就按照一定的算法来分配分区的个数,这就叫预分区