一、回顾
	-》应用场景
		为了解决大数据实时存储而诞生的(hive/hdfs都是离线文件存储) 
		-》归档存储
		-》搜索引擎
		-》数据实时读写
公司大数据数据开发都会用HBase或者类似于NoSQL数据库,从整体的性能来说HBase
会更加优秀一点.

启动hadoop:

hdfs是nosql hdfs是nosql吗_hdfs是nosql

启动Zookeeper:

hdfs是nosql hdfs是nosql吗_zookeeper_02

HBase存储路径:

hdfs是nosql hdfs是nosql吗_zookeeper_03

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中的启动方式

hdfs是nosql hdfs是nosql吗_zookeeper_04

进入客户端

bin/hbase shell

DDL

namespace
	注意:对于hbase的namespace,你可以直接理解为表名的一部分
	只要访问非默认namespace下的表,都需要使用namespace:tablename的方式来操作

创建namespace

create_namespace 'ns_name';
create_namespace 'ns2';

hdfs是nosql hdfs是nosql吗_hbase_05

列举所有namespace

list_namespace

hdfs是nosql hdfs是nosql吗_zookeeper_06

删除namespace

drop_namespace 'ns_name'

hdfs是nosql hdfs是nosql吗_zookeeper_07

查看namespace

describe_namespace

hdfs是nosql hdfs是nosql吗_hdfs是nosql_08

查看时候可以给出许多的属性值:

hdfs是nosql hdfs是nosql吗_hbase_09

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:

hdfs是nosql hdfs是nosql吗_zookeeper_10

hdfs是nosql hdfs是nosql吗_hdfs是nosql_11

查看namespace:

hdfs是nosql hdfs是nosql吗_数据_12

列举

list:默认列举当前hbase中所有的用户表

        

hdfs是nosql hdfs是nosql吗_hdfs是nosql_13

删除      

drop 'ns:tbname'

  drop 'ts2'

 

hdfs是nosql hdfs是nosql吗_hbase_14

注意:
       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'

hdfs是nosql hdfs是nosql吗_hdfs是nosql_15

help  delete

hdfs是nosql hdfs是nosql吗_zookeeper_16

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

hdfs是nosql hdfs是nosql吗_hbase_17

注意:
		-》多版本情况下执行了更新
		-》老的版本的值依旧存在,在查询时,显示最新版本的值
		-》默认情况下:版本只存1份
		-》针对每个列簇中的列可以指定多个版本

查看多版本

hdfs是nosql hdfs是nosql吗_hdfs_18

创建表的时候针对不同的列簇设置版本个数:
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的多列

hdfs是nosql hdfs是nosql吗_数据_19

查询

只查询某一列:

hdfs是nosql hdfs是nosql吗_hdfs_20

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 => ''}

hdfs是nosql hdfs是nosql吗_hbase_21

注意:
				01-hbase中所有数据的读写都是依赖rowkey来进行数据读写
				02-hbase所有的数据读写都是前缀匹配 相当于40419271%

count统计行数

整张表中有多少行(rowkey)

面试题:在hbase中如何最快的统计出一张表中有多少行
         -》1、SQL语句(用Hive集成HBase)--慢
         -》2、count 'ns:tbname'--快
         -》3、协处理器--最快

hdfs是nosql hdfs是nosql吗_数据_22

三、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三者的导入导出

hdfs是nosql hdfs是nosql吗_hbase_23

  实现:将订单表从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

hdfs是nosql hdfs是nosql吗_hdfs是nosql_24

hdfs是nosql hdfs是nosql吗_hdfs是nosql_25

报错原因:MySQL这张so表中没有主键
指定了两个mapReduce处理数据,必然一个MapReduce只能处理一部分数据。
数据是通过主键来切分,没有主键就无法切割数据。
解决方案:1、--split-by rk \ 
		  2、将-m2改为-m1

hdfs是nosql hdfs是nosql吗_zookeeper_26

hdfs是nosql hdfs是nosql吗_zookeeper_27

统计插入表的数据:

hdfs是nosql hdfs是nosql吗_zookeeper_28

hdfs是nosql hdfs是nosql吗_hdfs是nosql_29

查看某一条rowKey的数据:

hdfs是nosql hdfs是nosql吗_数据_30

四、Hbase基本存储架构

hdfs是nosql hdfs是nosql吗_hdfs是nosql_31

这是主从节点,一般DataNode,NodeManager、RegionServer都是在同一台机器上

排列的顺序

-》hbase中所有的读写依赖于rowkey
-》在hbase中:rowkey和列标签写入后都按照字典顺序进行排序了

hdfs是nosql hdfs是nosql吗_hdfs_32

解析: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

hdfs是nosql hdfs是nosql吗_hdfs是nosql_33

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中去

hdfs是nosql hdfs是nosql吗_hbase_34

1、一张表一开始只有一个分区,等数据越来越大时候,就会分裂成多个分区.
2、也可以创建表的时候就按照一定的算法来分配分区的个数,这就叫预分区