HBASE总结:出自Google论文的发表

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后缀格式的文件:每行数据以逗号分割的