HBASE:出自Google论文的发表
[列式存储、多版本(timestamp)的、nosql数据库]
hbase架构图:要能手画出来
**HBase没有单节点故障(因为zookeeper),可以有多个Hmaster,跟namenode一样,同一时刻只有一个hmaster在工作
HBase的功能:
*hadoop数据库:
1.存储数据
2.检索数据
*和RDBMS[关系型数据库]相比:
1.海量数据:数据条目数--上亿
2.检索的速度:准时性、秒级别
*基于hdfs: hdfs的优势
1.数据安全性[副本机制]
2.普通商用PC server就ok
1.Table中的所有行都是按照rowkey的字典序排列
2.Table在行的方向上分割为多个Region
3.Region是按照大小分割的,每个表开始只有一个region[会有一个starkey和endkey,前毕后包],随着数据增多,region不断增大,当增大到一定阀值时,region就会等分为两个新的region,之后会有越来越多的region。
4.Region是HBase中分布式存储和负载均衡的最小单位,不同region分不到不同的RegionServer上.
5.Region虽然是分布式存储的最小单元,但是不是存储的最小单元。
存储的最小单元是cell,{rowkey,column,version}
*唯一性
*数据没有类型,以字节码形式存储
region由一个或多个store组成,每个store保存一个column family;
每个store又由一个memStore和0至多个storeFile组成;
memStore存储在内存中,storeFile存储在hdfs上
hbase 旧版本的web监听端口 60010,新版本是16010
HBASE数据写入流程:
put ---> cell
step0: 先进行记录 --->HLog 【WAL(write ahead logging:日志预写功能)】 loc:hdfs
存储的log数据类型是sequenceFile
——- WAL的作用是防止写入内存时,region挂掉,数据丢失
step1: 写入memStore loc:内存
step2: 当内存达到一定阈值时,写入storeFile ---> loc: hdfs
HBASE 用户读取数据流程:
1)先到memStore里面去读
2)然后到BlockCache里面读 --> *每个RegionServer只有一个BlockCache*
3)最后到HFile里面读取数据
4)然后对数据进行Merge --> 最后返回数据集
MemSore和BlockCache
*HBase上的RegionServer的内存分为两部分:
1.Memstore --> 用来 写
写请求会先写入Memstore,RegionServer会给每个Region提供一个Memstore,当Memstore写满64M以后,会启动flush舒心到磁盘。
2.BlockCache --> 用来读
读请求先到Memstore中查询数据,查不到就到BlockCache中查询,再差不读奥就会到磁盘上读,并把读的结果放入BlockCache。
BlockCache达到上限后,会启动淘汰机制,淘汰掉最老的一批数据
*在注重读取响应时间的场景下,可以将BlockCache设置大些,Memstore设置小些,以加大缓存的命中率。
数据检索的三种方式:
1.get rowkey --- 最快的方式
2.scan range --- 用的最多的方式 【一般先range扫描,然后get】
3.scan ---全表扫描,基本不用
HBase中有类似于RDBMS中Database的概念
命名空间:
*用户自定义的表的命名空间,默认情况下 ---> default
*系统自带的元数据的表的命名空间 ---> hbase
HBase数据迁移
使用 MapReduce把文件生成hdfs上的HFile,然后进行bulk load into hbase table
**HBase表RowKey的设计**:
**现实环境中出现的问题:
*默认情况下创建一张HBase表,自动会为表创建一个Region [startkey,endkey) 前毕后包
*无论在测试环境还是生产环境中,创建完表以后会往表中导入大量数据
步骤:
file/datas -> HFile -> bulk load into hbase table
此时Region只有一个,而region是被RegionServer管理的,
当导入数据量慢慢增大后Region就会被split成两个Region,
但是此时RegionServer很可能就会挂掉,此时就会出现问题...
解决方案[举例]:
创建表时,多创建一些Region(依据表的rowkey进行设计 + 结合业务)
比如说:有5个region,他们被多个RegionServer管理
再插入数据时,会向5个Region中分别插入数据,这样就均衡了
**具体解决方案:
表的RowKey设计中:
**如何在海量数据中,查询到我想要的数据???
核心思想:
1.依据RowKey查询最快
2.对RowKey进行范围查询range
3.前缀查询
比如:startkey:15221467820_20180409000053 和 endkey:15221467828_20180419000053
这时只会比较15221467820 和 15221467828 而后面的_2018.. 则不会进行匹配
解决方法:
a).HBase的预分区:
Region的划分依赖于RowKey,预先预估一些RowKey(年月日时分秒)[最常用的就是这两种,其他的方法rowkey设计都不能自定义]
1. create 'tb1','cf1',splits => ['20180409000000','20180419000000','20180429000000']
2. create 'tb1','cf1',splits_file => '/root/data/logs-split.txt'
[这种情况就是把分段的rowkey写入了文件里]
这样就分为了4个Region,因为它会把头和尾也算进去
b).根据业务来对RowKey的设计:
举例:移动运营商电话呼叫查询详单:
RowKey:
phone + time
15221467820_20180409010000
infor:
上海 主叫 152216888888 30 国内通话 0.00
area active opposite_phone talk_time model price
依据查询条件:
phone + (start_time - end_time)
代码:
scan
startrow
15221467820_20180409000000
stoprow
15221467820_20180419000000
保证了实时性
HBase数据存储二级索引[索引表]的设计以及数据同步解决方案:
基于以上的移动运营商电话呼叫查询详单:
二级索引表:
RowKey:
opposite_phone
columnFamily对应的colume:
主表的RowKey
主表和索引表的同步:
>> phoenix
>> jdbc 方式才能同步
>>先在solr里创建索引表
solr //在solr中创建索引表
国外有个框架交 lily
cloudera search 封装了lily,只要配置下cloudera
cloudera search会在主表插入数据时,自动更新solr里的索引表
HBase之 表的属性:
面试会问到:**每个RegionServer只有一个HLog和一个BlockCache
1.HBase的表的压缩[HFile compression]--表的属性:
**在企业中通常使用snappy格式进行压缩,可以减少容量的存储,和减少io流,提高传输效率
跟hive一样,需要一些编译jar包,然后放到lib的native里
[这里使用软连接 ln -s /xx/xx /xx 具体看官方文档],还有一些参数的配置,才能使用
创建表的时候:
create 'user',{NAME='cf1',COMPRESSION=>'SNAPPY'}
2. HBase 标的属性:IN_MEMORY=>'false'、BLOCKCACHE=>'true'
HBase为什么查询这么快 就是因为这些表的属性的存储机制!!
通常我们自定义创建的表的相应列簇下的IN_MEMORY属性都是false!
通过describe 'hbase:meta'可以查询到 IN_MEMORY=>'true' BLOCKCACHE => 'true',
意为meta元数据存放于blockcache的inmemory内存中
IN_MEMORY队列存放HBase的meta表元数据信息,因为meta存储了用户表的
通常 BLOCKCACHE 这个属性的设置要慎用,比如我们查询后的数据后续还会用到这时可以设置为true
如果后续用不到这些数据就要设置此属性为false
HBase的Cache分等级:
默认情况下:整个BlockCache的内存分配
1.IN_MEMORY 1/4 in_memory 用于存储hbase的meta元数据信息 2.Single 1/4 single就是用的次数较少的数据
3.Muti 1/2 muti就是用的次数较多的数据
如果BlockCache的内存到达阈值,会先清理single然后清理muti,in_memory的内存不会被清理!
HBase表的compaction
随着写入数据的不断增加,hbase会把小的hfile进行合并,以以减少IO查询次数,合并有两种:
1.minor compaction
Minor Compaction是指选取一些小的、相邻的StoreFile将他们合并成一个更大的StoreFile,
在这个过程中不会处理已经Deleted或Expired的Cell。一次Minor Compaction的结果是更少并且更大的StoreFile。
2.major compaction
Major Compaction是指将所有的StoreFile合并成一个StoreFile,这个过程还会清理三类无意义数据:被删除的数据、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,Major Compaction时间会持续比较长,会阻塞数据的吸入和查询!!!,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此线上业务都会将关闭自动触发Major Compaction功能,改为手动在业务低峰期触发。
HBase和Hive集成:
此时实质上Hive就是HBase的一个客户端!
应用场景:
日志文件 --> hive --> hive-hbase-table --> insert .. select ...
电商订单查询之HBase:
1.用户下单后-->存到RDBMS[关系型数据库]中 即未完成的订单
2.订单完成后-->数据迁移到HBase中
查询比如三个月内的订单:
1.主表[订单显示表]:
rowkey: userid_orderCreateTime_orderId
cfname: orderInfor
[本来userid+orderCreateTime就可以保证唯一性,加orderId的原因是为了二次查询]
2.订单详情表:
rowkey: orderId_orderItemId
cfname: itemInfor
3.索引表:
比如用户输入订单号:我们后台Redis或者MongoDB里会有相对应的订单编码
获取到订单编码然后到索引表中去查
索引表的rowkey:订单编号 column: 主表的rowkey
就可以到hbase主表中查询订单
补充文件类型 .tsv[tab] .csv[comma]:
user.tsv tsv后缀格式的文件:每行数据以tab 制表符分割的
user.csv csv后缀格式的文件:每行数据以逗号分割的