2023年11月26日发(作者:)
Hbase之滤器Filter
3.基本命令之过滤器Filter
10.过滤器Filter
在Hbase中,get 和 scan 操作都可以使⽤过滤器来设置输出的范围,类似 SQL ⾥的 Where 查询条件。
使⽤ show_filter 命令可以查看当前 HBase ⽀持的过滤器类型,如下图所⽰。
使⽤上述过滤器时,⼀般需要配合⽐较运算符或⽐较器使⽤,如下⾯两个表所⽰。
使⽤过滤器的语法格式如下所⽰:
列族与列过滤器
针对列族进⾏过滤的过滤器为 FamilyFilter,其语法结构与 RowFilter 类似,不同之处在于 FamilyFilter 是对列族名称进⾏过滤的。
ValueFilter 过滤器可以利⽤ get 和 scan ⽅法对单元格进⾏过滤,但是使⽤ get ⽅法时,需要指定⾏键。
SingleColumnValueFilter 和 SingleColumnValueExcludeFilter 过滤器扫描的结果是相反的, 都需要在过滤条件中指定列族和列的名
称。
其他过滤器
还有⼀些其他的过滤器,其过滤⽅式和⽰例如下表所⽰。
ColumnCountGetFilter 过滤器限制每个逻辑⾏返回多少列,⼀般不⽤在 scan ⽅法中,Timestamps Filter 匹配相同时间戳的数据。
InclusiveStopFilter过滤器设置停⽌⾏,且包含停⽌的⾏,上表中⽰例最终展⽰数据为⾏键 0001〜0003 范围内的数据。PageFilter 设
置每页最多显⽰多少逻辑⾏, ⽰例中显⽰三个逻辑⾏。
ColumnPaginationFilter过滤器对⼀个逻辑⾏的所有列进⾏分页显⽰。
#scan ,
使⽤过滤器⾏健前缀过滤器只有这⼀个有属性
scan 'test2:emp', {ROWPREFIXFILTER => '2'}
#scan
使⽤空值⾏健过滤器,只返回⾏健
scan 'test2:emp',{FILTER=>'KeyOnlyFilter()'}
scan 'test2:emp',{FILTER =>org.apache.hadoop.hbase.filter.KeyOnlyFilter.new()}
#scan ,binary:
使⽤⾏健过滤器帮助数据类型转化
scan 'test2:emp',{FILTER=>"RowFilter(>,'binary:1')"}
scan 'test2:emp',{FILTER =>"RowFilter(!=,'binary:10001')"}
#scan
使⽤列名过滤器
scan 'test2:emp',{FILTER =>"QualifierFilter(>=,'binary:baseinfo:name')"}
#scan
列名前缀过滤器
scan 'test2:emp',{FILTER =>"ColumnPrefixFilter('name')"}
#scan
使⽤⼦串过滤器
scan 'test2:emp',{FILTER =>"ValueFilter(=,'binary:zhao')"}
#scan
使⽤多种过滤器进⾏条件结合
scan 'test2:emp',{FILTER =>"(ValueFilter(=,'binary:hello')) OR (RowFilter (>,'binary:10'))"}
#scan page
使⽤过滤器,限制每页展⽰数量
scan 'test2:emp',{STARTROW=>'1',ENDROW=>'5',FILTER =>'PageFilter(3)'}
#scan
使⽤⾏健过滤器,进⾏正则表达式的匹配
scan 'test2:emp', {FILTER => org.apache.hadoop.hbase.filter.RowFilter.new(org.apache.hadoop.hbase.filter.CompareFilter::CompareOp.valueOf('EQUAL'
),org.apache.hadoop.hbase.filter.RegexStringComparator.new('.*1.*'))}
存储结构
系统表
hbase:namespace 命名空间,逻辑抽象分组,类似于关系型数据库⾥⾯的database。
hbase:meta META表,存储⾃定义表的Region分布。
注意:既然是表,数据量达到⼀定程度,也会分区。
因此Hbase设计中还存在⼀个叫做-ROOT-表(新版本中是以⽂件的形式存储在Zookeeper中)的来记录META表的Region分布情况。
例如:
#建表
create 'bd1901:emp1','f1','f2'
create 'bd1901:emp2','f1','f2',SPLITS=>['1000','2000','3000']
#查询meta数据
scan 'hbase:meta',{COLUMNS=>'info:server',LIMIT=>5}
scan 'hbase:meta',{ROWPREFIXFILTER => '5'}
案例:
数据准备:
1.建表语句:
create 'bd1901:test2','cf1',SPLITS=>['1000','2000','3000','4000']
该表预定义分区为5--->5条数据保存到META表(很⼤,分区)
-ROOT-表(不会再进⾏分区,新版本是直接存储在ZK中⽂件)
表数据存储格式样例:
RowKey info:Server info:regionInfo
table,StartKey,Time IP startKey-endKey
数据为:
abc:test1,,T cmm1:16020 -
.......
bd1901:test2,,T cmm1:16023 -1000
bd1901:test2,1000,T cmm1:16022 1000-2000
bd1901:test2,2000,T cmm1:16020 2000-3000
bd1901:test2,3000,T cmm1:16023 3000-4000
bd1901:test2,4000,T cmm1:16022 4000-
bd1901:test3,,T cmm1:16022 -10
bd1901:test3,10,T cmm1:16023 10-30
bd1901:test3,30,T cmm1:16020 30-
hbase:namespace,,T cmm1:16020 -
.......
ztest:emp1,,T cmm1:16023 -
⽂件数据存储格式样例:
RowKey startRowKey-endRowKey IP
1 abc:test1,,T-bd1901:test2,2000,T cmm1:16020
2 bd1901:test2,3000,T-ztest:emp1,,T cmm1:16022
向Zookeeper发送读请求
例如:
get 'bd1901:test3','20'
优先从本地缓存中读取数据
2.缓存中没有找到的情况下,会根据⼆级寻址⽅式查找该条数据位于哪⼀个Region,获取该HRegion所在的HRegionServer服务器的位置信息(即IP地址)。
向数据分区服务器发送读请求
1.优先从MemStore中读取数据(内存缓冲 64M)
写进去的数据(刚insert之后⽴刻select)
2.优先从BlockCache中读取数据 块缓存
会将经常检索的数据以及该数据前后的数据都会存储到该块缓存中,以提⾼查询效率。
3.如果以上两个内存中都没有读取到数据,则借助于IO操作从HDFS⽂件中读取数据。
5.⼆级寻址
Hbase旧版本寻找某⼀个表的某⼀个RowKey对应数据的采⽤的是三级寻址。
新版本更新为⼆级寻址。
向Zookeeper发送读/写请求,读取Zookepper中的/hbase/meta-region-server节点信息(即-ROOT-表),获取到META表中该
表该RowKey所在HRegionServer的位置信息。
向该位置信息发送读/写请求,读取META表信息,进⼀步获取该表该RowKey所对应的HRegionServer的位置信息。
所谓的三级寻址,即-ROOT-表存储在HRegionServer中,需要先借助于Zookeeper查找-ROOT-表的位置信息,再执⾏以上两步。
6.基本命令
1.热点问题
读写操作集中在某⼏个Region中,就会造成热点问题。
解决办法:
1.建表时预定义分区(根据实际数据量的预估表分区个数)
设置为随机产⽣(使⽤算法⽣成 hash,md5等)
2.写数据操作
put '命名空间:表名','RowKey','列族:列','值'[,'时间戳’]
1.按照⼆级寻址⽅式查找写数据对应的HRegionServer位置信息
2.将数据写⼊到MemStore以及WAL(Write Ahead Log预写式⽇志,也叫做HLog)两个地⽅,全部写⼊完成,写操作完成。
re中默认可以缓存的数据⼤⼩为64M,数据写满之后,会被flush到HFile⽂件中。
4.当StoreFile⽂件数达到⼀定量之后,会将多个StoreFile合并为⼀个⼤的StoreFile。
5.当单个StoreFile⼤⼩达到⼀个阀值之后,会触发此Region的分裂操作。
6.⼀分为⼆,⽗Region下线,两个⼦Region上线,ZK通知HMaster。
7.单个Region处理的读数据会被分流到两个Region中进⾏处理。
8.写数据仍然只能有⼀个Region负责(参考热点问题,RowKey值会进⾏排序存储)。
#获得某⼀个特定值
get '命名空间:表名','RowKey','列族:列'
#获得前3个版本的数据
get '命名空间:表名','RowKey',{COLUMN=>'列族:列',VERSIONS=>3}
#获得某个时间段数据,不⼀定是时间最新的数据
get '命名空间:表名','RowKey',{TIMERANGE=>[28, 31]}
#scan 扫描某张表 select *
scan '命名空间:表名'
#scan 扫描 表中某⼀列
scan '命名空间:表名',{COLUMNS=>'列族:列'}
#scan 使⽤limit 进⾏⾏数限制
scan '命名空间:表名',{COLUMNS=>'列族:列',LIMIT=>5}
#scan 指定从某⼀⾏开始扫描
scan '命名空间:表名',{COLUMNS=>'列族:列',LIMIT=>5,STARTROW=>'20001'}
#scan 扫描所有版本
scan '命名空间:表名','列族:列',{VERSIONS=>5}
#在hbase 对于hfile没有进⾏过合并操作之前
#scan 超出版本限制也能访问到
scan '命名空间:表名','列族:列',{VERSIONS=>5,RAW=>true}
#scan 使⽤过滤器 ⾏健前缀过滤器,只有这⼀个有属性
scan '命名空间:表名', {ROWPREFIXFILTER => '条件'}
#scan 使⽤空值⾏健过滤器,只返回⾏健(结合HbaseAPI查看Hbase⽀持的过滤器)
scan '命名空间:表名',{FILTER=>'KeyOnlyFilter()'}
在hbase shell客户端表⽰hbase⽀持的过滤器的构造参数规则如下:
1 数值 数字
2 eOp ⽐较符 > <
3 ByteArrayComparable 'binary:1000'
4 byte[] '字符'
例如:
1.#scan 使⽤⾏健过滤器,binary: 帮助数据类型转化
scan '命名空间:表名',{FILTER =>"RowFilter(!=,'binary:10001')"}
2.#scan 使⽤列名过滤器
scan '命名空间:表名',{FILTER =>"QualifierFilter(>=,'binary:baseinfo:name')"}
3.#scan 使⽤⼦串过滤器
scan '命名空间:表名',{FILTER =>"ValueFilter(=,'binary:zhao')"}
4.#列名前缀过滤器
scan '命名空间:表名',{FILTER =>"ColumnPrefixFilter('name')"}
5.#scan 使⽤多种过滤器进⾏条件结合
scan '命名空间:表名',{FILTER =>"(ValueFilter(=,'binary:hello')) OR (RowFilter (>,'binary:10'))"}
6.#scan 使⽤page过滤器,限制每页展⽰数量
scan '命名空间:表名',{FILTER =>()}
7.#scan 使⽤⾏健过滤器,进⾏正则表达式的匹配
scan '命名空间:表名', {FILTER => (CompareFilter::f('EQUAL'),('.*ll.*'))}
4.删除数据操作
格式:delete delete 't1','rowkey001','f1:col1’ truncate 删除数据不是直接将数据删除,⽽是将数据标记为墓碑标记。被标记为墓碑标记的数据只有当Hbase出现⼤合并的时候,才会将该数据删除。 1.⼩合并,读取完整⼀⾏,可能需要很多HFile,把这些Hfile合并成⼀个HFile,提⾼了读取⼀⾏的速度,⼩合并是轻量级的,可以频繁操作 (hbase⾃⾝控制)。 Region Store(CF1) 1个MemStore *StoreFile(HFile) HFile1 RowKey','CF:Q,value1 value2 value3 HFile2 ,


发布评论