Hbase基本命令和协处理器-rowkey设计原则-hive和hbase结合

hbase表管理:
    表切割
        split 'ns1:t1','row1000'
    区域切割
        split 'REGION_NAME' , 'row500'

    区域合并
        merge 'ENCODED_REGIONNAME' ,''

    表移动
        move 'ENCODED_REGIONNAME','SERVER_NAME'

    紧凑表    //将storeFile中的多个小文件整合成单个文件
        compact        //minor_compact    力度较小,重启之后能看见效果
        major_compact    //        力度较大,即刻生效

REGION_NAME
ENCODED_REGIONNAME
SERVER_NAME    s102,16020,timestamp


元数据:
    hbase:meta    //元数据表,存放region和regionserver的映射
            //一个region由一个regionserver进行管理

    zk        //存放hbase:meta的元数据,指明hbase:meta和regionserver的映射
    

    定位region流程:
        client联系zk,定位hbase:meta的regionserver并请求数据
        通过hbase:meta表定位要寻找的region并请求数据

        定位完成会缓存请求数据,以便下次使用


    HFile调参:
        最小块大小,推荐在 8KB to 1MB之间
            顺序读写推荐大块,但不便于随机访问(因为需要解压更多的数据)
            小块便于随机读写,但是需要占用更多内存,但是创建起来更慢(因为块多,每次压缩都需要flush操作)
            由于压缩缓存,最小块大小应该在20KB-30KB.


cache和batch:
    主要减少rpc请求次数

    cache    //一次缓存多少行
    batch    //一次缓存多少列


过滤器:
    select from xx 'where'
    

    RowFilter
    FamilyFilter
    QualifierFilter
    ValueFilter
    SingleColumnValueFilter        //复杂过滤器,通过指定字段返回一整行数据


    比较器:
        BinaryComparator    //
        RegexStringComparator
        SubStringComparator    //



put优化:
    

    每次put操作,都会进行autoFlush,同时产生一个RPC,
    
    1、setAutoFlush
    2、put(List<Put>)
    3、setWriteToWAL(false)



组合过滤器:FilterList
    
    new FilterList(MUST_PASS_ONE)    or
               MUST_PASS_ALL    and


hbase计数器:
============================
    incr 'ns1:t4','row1','f1:count',      1
                不存在的列    步数
                作为自增字段
                
    相当于在内部维护的一个普通long型数值,以自增形式进行展现
    适用于统计点击事件。


    得到计数器的数量:
        get 'ns1:t4','row1','f1:count3'
        get_counter 'ns1:t4','row1','f1:count3'


get:
=============================
     Get get = new Get(Bytes.toBytes("row1"));
     get.addFamily()
     get.addColumn(Bytes.toBytes("f1"),Bytes.toBytes("count3"));
    

count:
=============================
    统计hbase中的行数,并不需要MR作业

    count 'ns1:t5', CACHE => 10000, INTERVAL => 10000
            缓存数据    打印间隔
            默认1000    默认1000

    
desc 'ns1:t1'
==============================
    在表中,不同的列族可以设定不同的属性

    alter:
        alter 'ns1:t4', 'f3'            //添加列族
        alter 'ns1:t4', 'delete' => 'f1'    //删除列族,delete必须小写


    
{NAME => 'f2', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT
L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}
{NAME => 'f3', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT
L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}


VERSIONS:版本数
    alter 'ns1:t4', NAME => 'f2', VERSIONS => 5    //设定制定列族版本数为5
    指定的是通过get能获取到的版本数

MIN_VERSIONS:最小版本数
    alter 'ns1:t4',NAME => 'f2', MIN_VERSIONS => '3' //设定最小版本数为3


TTL:time to live
    alter 'ns1:t4',NAME => 'f2', TTL => '10'        //数据存活时间(s)
    一般和MIN_VERSIONS使用,超过设定值,数据会自动删除直到和MIN_VERSIONS版本数相等


KEEP_DELETED_CELLS:保留删除数据
    alter 'ns1:t4', NAME => 'f2', KEEP_DELETED_CELLS => 'true'    //设定保留删除数据
    如果为false,则在重启hbase之后扫描不到删除的数据,及其之前时间戳的数据


    

    
    查看数据往期版本:
    =================================
        scan:
            scan 'ns1:t4', {RAW => true, VERSIONS => 2}    //原生扫描,返回所有版本数据,专家模式
            对于原生扫描,不能指定对应的列,列族可以

        get:
            get 'ns1:t4','row0',{COLUMN => 'f2:age', VERSIONS => 4}   //get 'ns1:t4','row0',{COLUM=>'f2:age',VERSIONS => 4}
            指定版本、时间戳获取数据


        get和scan:
        =======================================================
            1、    scan的原生扫描,不受版本号限制(VERSIONS)
                    scan 'ns1:t4', { ROW => true, VERSIONS => 10 }    //scan 'ns1:t4',{ROW  => true,VERSIONS =>10}
                get指定版本号,受版本号限制(VERSIONS)
                    get 'ns1:t4','row0',{COLUMN => 'f2:age', VERSIONS => 10}
            
            2、    删除数据。指定时间戳
                    delete 'ns1:t4','row0','f2:age',1522724676530

                scan的原生扫描,仍然能够读取删除数据
                    scan 'ns1:t4', { ROW => true, VERSIONS => 10 }
                    
                get指定版本号,在删除数据之前的数据均不能得到
                    get 'ns1:t4','row0',{COLUMN => 'f2:age', VERSIONS => 10}



Compression:
=============================
    LZO
    SNAPPY
    GZ
    NONE
    LZ4
    ZSTD

    hbase org.apache.hadoop.hbase.util.CompressionTest file:///home/centos/oldWAL lz4    //测试压缩算法是否有效

    设置列族使用压缩:
        0、创建表:
            create 'ns1:t4', 'f1','f2'

        1、禁用表:
            disable 'ns1:t4'

        2、修改
            alter 'ns1:t4', {NAME =>'f3', COMPRESSION => 'GZ'}

        3、启用表
            enable 'ns1:t4'

        4、major_compact强制表数据使用现有的压缩格式

    问题:    ERROR: org.apache.hadoop.hbase.NotServingRegionException: 
        Region ns1:t1,,1522634115455.77c55f893ecec3bbb2dfd02e3737c0c2. 
        is not online on s103,16020,1522736736293

    解决:  hbase的压缩,只能在表创建时候使用,当表中有数据,则会报错



close_region和Assign:
===============================
    1、close_region        //将指定区域和regionserver处于离线状态
                //close_region 'ENCODED_REGIONNAME'
                //close_region 'REGIONNAME'

    2、assign        //重新注册region
                //当region处于离线,则可以使用此方法将其重新注册
                //assign 'ENCODED_REGIONNAME'   //  encoded_regionname
                //assign 'REGIONNAME'          //regionname


        
dr.who:
==============================
    hadoop设置默认http用户,叫做dr.who
    
    0、关闭hdfs集群
        stop-dfs.sh

    1、修改hadoop的http静态用户名:core-site.xml
        nano /soft/hadoop/etc/hadoop/core-site.xml

        <property>
          <name>hadoop.http.staticuser.user</name>
          <value>centos</value>
        </property>

    2、分发配置文件
        xsync.sh /soft/hadoop/etc/hadoop/core-site.xml



hbase和hive组合使用:
===============================
    hbase的表可以通过hive进行管理,使用hive的分析函数进行数据分析
        
    hbase + 分析:
        
    创建hive和hbase表,并通过hive操作hbase
        create table hive_hbase( id string, name string , age string) 
        STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
        WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,f1:name,f1:age")
        TBLPROPERTIES ("hbase.table.name" = "hive_hbase");

        //:key,f1:name,f1:age
        //:key ======>  rowKey    =====> id 
        //f1:name ===>  f1:name =====> name

        //"hbase.table.name" = "hive_hbase"指定hive表在hbase中对应的表名


    在hive关联已有hbase表:
        create external table ns1_t2( rowid string, id string, name string , age string)         
        STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'          
        WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key, f1:id, f1:name,f1:age")
        TBLPROPERTIES ("hbase.table.name" = "ns1:t2"); 
        
        注意:关联已有hbase表,需要创建外部表


hbase协处理器:
===================================
    在服务端帮助客户端完成自定义的计算操作

    监听客户端的请求,可以对应相应的"事件"进行相应的操作
                                //////////flush
                                /......
    协处理器类型:
        observer    //观察者,最常用
                //
            regionObserver
                //最常用,负责数据的增删改查
            MasterObserver
                //监控ddl操作,表的创建,库的创建
            WALObserver
                //监控预写日志

                

        endpoint    //终端,在phoenix中含有此协处理器
                //类似于RDBMS中的存储过程


    协处理器的执行过程:
        一个表中可以添加若干协处理器,
            执行过程:system_copro ====> user1_copro ====> user2_copro =====> ...
                    高优先级
                
    
    CoprocessorEnvironment类:
        在协处理器中以参数形式传入,可以通过此参数获取到诸如HTable实例

    
      <property>
        <name>hbase.coprocessor.region.classes</name>
        <value>com.oldboy.hbase.MyCoprocessor</value>
        <description>逗号分隔的完整类名集,加载regionObserver</description>
      </property>

      <property>
        <name>hbase.coprocessor.region.classes</name>
        <value></value>
        <description>逗号分隔的完整类名集,加载MasterObserver</description>
      </property>

      <property>
        <name>hbase.coprocessor.region.classes</name>
        <value></value>
        <description>逗号分隔的完整类名集,加载WALObserver,配置文件未找到</description>
      </property>


BaseRegionObserver:
=================================
    设计模式:适配器模式    //预实现


加载协处理器的步骤:
====================================
    0、修改pom文件,添加
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase-server</artifactId>
            <version>1.2.6</version>
        </dependency>


    1、将代码打包并放在/soft/hbase/lib/下,并分发
        xsync.sh xxx

    2、关闭hbase
        stop-hbase.sh
    
    3、修改/soft/hbase/conf/hbase-site.xml,添加
         <property>
            <name>hbase.coprocessor.region.classes</name>
            <value>com.oldboy.hbase.MyCoprocessor</value>
            <description>逗号分隔的完整类名集,加载regionObserver</description>
          </property>

    3.5、分发配置文件
        xsync.sh /soft/hbase/conf/hbase-site.xml
    
    4、启动hbase
        start-hbase.sh

    5、测试操作,在s102-s104观察日志文件
        xcall.sh "cat ~/observer.log"



RowKey设计原则:
================================
    
    hbase:row + col 没数据,就是没有数据

    RDBMS:row + col 没数据,用null来补充


    id    name    age
rdbms    1    tom    null


rowKey搜索:
    从key的最左开始搜索:
        key:row1/f1:age/1522634241444/Put/vlen=1/seqid=22
        value:1

    搜索性能:从rowKey到value,搜索性能逐级降低

高表和宽表:
    由于hbase的搜索性能,建议使用高表代替宽表
    

rowKey设计原则:
=========================
    rowKey最长64K,建议不超过16字节
     
    1、使用组合键:
        eg:userId_msgId做为rowKey        //用户接受信息场景

        userid        msgid        userinfo    msg
        1        1
                2
                3
                43
                5

    2、在组合键基础上使用子串对比进行检索,自定义查询粒度
        SubStringComparator


    3、在组合键基础上可以通过调整字段顺序来改变权重
        eg:userId_msgId ====> msgId_userId


    
    
    4、salt,盐析            //避免数据倾斜
        使用定长加密方式,将rowKey打散,如md5加密   散列,防止热点问题(类似数据倾向情况)

        eg:ns1:t6,,1522739236028.f8874782c841bafa796da0678512e4df.  作为rowKey             

    
    5、使用随机数设置rowKey        //避免数据倾斜,但是数据太散,搜索效率得不到提升
        md5(timestamp)

    
    
    
    
    6、使用大数-id的方法,倒序排序        //原因是由于hbase的字节排序
        eg:Long.MaxValue -  id
        
        1        1000 -  1    999(有序)
        10        1000 -  10    990
        2        1000 -  2    998

    7、格式化数据串
        0  ===> 00000
        10 ===> 00010