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