第二天:Hbase进阶

高清思维导图已同步Git:https://github.com/SoWhat1412/xmindfile,关注公众号sowhat1412获取海量资源

在这里插入图片描述

2. HBase安装

HBase = Hadoop database

1. Zookeeper正常部署

首先保证Zookeeper集群的正常部署,并启动之:

[atguigu@hadoop102 zookeeper-3.4.10]$ bin/zkServer.sh start
[atguigu@hadoop103 zookeeper-3.4.10]$ bin/zkServer.sh start
[atguigu@hadoop104 zookeeper-3.4.10]$ bin/zkServer.sh start

2 Hadoop正常部署

Hadoop集群的正常部署并启动:

[atguigu@hadoop102 hadoop-2.7.2]$ sbin/start-dfs.sh
[atguigu@hadoop103 hadoop-2.7.2]$ sbin/start-yarn.sh

3. HBase的解压

解压HBase到指定目录:

[atguigu@hadoop102 software]$ tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module

4. HBase的配置文件

修改HBase对应的配置文件。

  1. hbase-env.sh修改内容:
export JAVA_HOME=/opt/module/jdk1.8.0_144
export HBASE_MANAGES_ZK=false # 不用HBase自带的zk关联机制
  1. hbase-site.xml修改内容:
<configuration>
	<property>     
		<name>hbase.rootdir</name>     
		<value>hdfs://hadoop102:9000/hbase</value>   
	</property>

	<property>   
		<name>hbase.cluster.distributed</name>
		<value>true</value>
	</property>

   <!-- 0.98后的新变动,之前版本没有.port,默认端口为60000 -->
	<property>
		<name>hbase.master.port</name>
		<value>16000</value>
	</property>

	<property>   
		<name>hbase.zookeeper.quorum</name>
	     <value>hadoop102:2181,hadoop103:2181,hadoop104:2181</value>
	</property>

	<property>   
		<name>hbase.zookeeper.property.dataDir</name>
	     <value>/opt/module/zookeeper-3.4.10/zkData</value>
	</property>
</configuration>
  1. 修改regionservers跟HDFS中slaves类似:
hadoop102
hadoop103
hadoop104
  1. 软连接hadoop配置文件到hbase:
[atguigu@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml 
/opt/module/hbase/conf/core-site.xml
[atguigu@hadoop102 module]$ ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml 
/opt/module/hbase/conf/hdfs-site.xml

5. HBase远程发送到其他集群

[atguigu@hadoop102 module]$ xsync hbase/ 

6 HBase服务的启动

1.启动方式1

[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start master
[atguigu@hadoop102 hbase]$ bin/hbase-daemon.sh start regionserver

提示:如果集群之间的节点时间不同步,会导致regionserver无法启动,抛出ClockOutOfSyncException异常。
修复提示:
a、同步时间服务
请参看帮助文档:《Hadoop入门》
b、属性:hbase.master.maxclockskew设置更大的值

<property>
        <name>hbase.master.maxclockskew</name>
        <value>180000</value>
        <description>Time difference of regionserver from master</description>
 </property>

2.启动方式2推荐

[atguigu@hadoop102 hbase]$ bin/start-hbase.sh
对应的停止服务:
[atguigu@hadoop102 hbase]$ bin/stop-hbase.sh

7. 查看HBase页面

启动成功后,可以通过“host:port”的方式来访问HBase管理页面,例如:

http://hadoop102:16010 

3. HBase Shell 操作

Shell基本操作 指南

命名 描述 语法
help ‘命名名’ 查看命令的使用描述 help ‘命令名’
whoami 我是谁 whoami
version 返回hbase版本信息 version
status 返回hbase集群的状态信息 status
table_help 查看如何操作表 table_help
create 创建表 create ‘表名’, ‘列族名1’, ‘列族名2’, ‘列族名N’
alter 修改列族 添加一个列族:alter ‘表名’, ‘列族名’ ;删除列族:alter ‘表名’, {NAME=> ‘列族名’, METHOD=> ‘delete’}
describe 显示表相关的详细信息 describe ‘表名’
list 列出hbase中存在的所有表 list
exists 测试表是否存在 exists ‘表名’
put 添加或修改的表的值 put ‘表名’, ‘行键’, ‘列族名’, ‘列值’ ; put ‘表名’, ‘行键’, ‘列族名:列名’, ‘列值’
scan 通过对表的扫描来获取对用的值 scan ‘表名’ ; 扫描某个列族: scan ‘表名’, {COLUMN=>‘列族名’} 扫描某个列族的某个列: scan ‘表名’, {COLUMN=>‘列族名:列名’} ; 查询同一个列族的多个列: scan ‘表名’, {COLUMNS => [ ‘列族名1:列名1’, ‘列族名1:列名2’, …]}
get 获取行或单元(cell)的值 get ‘表名’, ‘行键’ get ‘表名’, ‘行键’, ‘列族名’
count 统计表中行的数量 count ‘表名’
incr 增加指定表行或列的值 incr ‘表名’, ‘行键’, ‘列族:列名’, 步长值
get_counter 获取计数器 get_counter ‘表名’, ‘行键’, ‘列族:列名’
delete 删除指定对象的值(可以为表,行,列对应的值,另外也可以指定时间戳的值) 删除列族的某个列: delete ‘表名’, ‘行键’, ‘列族名:列名’
deleteall 删除指定行的所有元素值 deleteall ‘表名’, ‘行键’
truncate 重新创建指定表 truncate ‘表名’
enable 使表有效 enable ‘表名’
is_enabled 是否启用 is_enabled ‘表名’
disable 使表无效 disable ‘表名’
is_disabled 是否无效 is_disabled ‘表名’
drop 删除表 drop的表必须是disable的 disable
shutdown 关闭hbase集群(与exit不同)
tools 列出hbase所支持的工具
exit 退出hbase shell

基本操作

  1. 进入HBase客户端命令行
[atguigu@hadoop102 hbase]$ bin/hbase shell
  1. 查看帮助命令
hbase(main):092:0> help 'delete'
Put a delete cell value at specified table/row/column and optionally
timestamp coordinates.  Deletes must match the deleted cell's
coordinates exactly.  When scanning, a delete cell suppresses older
versions. To delete a cell from  't1' at row 'r1' under column 'c1'
marked with the time 'ts1', do:

  hbase> delete 'ns1:t1', 'r1', 'c1', ts1
  hbase> delete 't1', 'r1', 'c1', ts1
  hbase> delete 't1', 'r1', 'c1', ts1, {VISIBILITY=>'PRIVATE|SECRET'}

The same command can also be run on a table reference. Suppose you had a reference
t to table 't1', the corresponding command would be:

  hbase> t.delete 'r1', 'c1',  ts1
  hbase> t.delete 'r1', 'c1',  ts1, {VISIBILITY=>'PRIVATE|SECRET'}
hbase(main):093:0> 

hbase(main):001:0> help
COMMAND GROUPS:
  Group name: general
  Commands: processlist, status, table_help, version, whoami

  Group name: ddl 数据库的增删改查操作
  Commands: alter, alter_async, alter_status, clone_table_schema, create, describe, disable, disable_all, drop, drop_all, enable, enable_all, exists, get_table, is_disabled, is_enabled, list, list_regions, locate_region, show_filters

  Group name: namespace  类似与mysql中的database操作
  Commands: alter_namespace, create_namespace, describe_namespace, drop_namespace, list_namespace, list_namespace_tables

  Group name: dml 数据库跟表格的一些操作
  Commands: append, count, delete, deleteall, get, get_counter, get_splits, incr, put, scan, truncate, truncate_preserve
.......
For more on the HBase Shell, see http://hbase.apache.org/book.html
  1. 查看当前数据库中有哪些表
hbase(main):002:0> list
TABLE                                                                                                                                                                                                                                         
sowhat                                                                                                                                                                                                                                        
mygraph                                                                                                                                                                                                                                       
user 

表的操作

  1. 创建表
    注意:创建表时只需要指定列族名称,不需要指定列名。
# 语法
create '表名', {NAME => '列族名1'}, {NAME => '列族名2'}, {NAME => '列族名3'}
# 此种方式是上上面的简写方式,使用上面方式可以为列族指定更多的属性,如VERSIONS、TTL、BLOCKCACHE、CONFIGURATION等属性
create '表名', '列族名1', '列族名2', '列族名3'

create '表名', {NAME => '列族名1', VERSIONS => 版本号, TTL => 过期时间, BLOCKCACHE => true}
# 示例
create 'tbl_user', 'info', 'detail'
create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}
create 'sowhat','info'
  1. 插入数据到表
    put 表名,序列号key,列族:列名,字段值
hbase(main):003:0> put 'sowhat','1001','info:sex','male'
hbase(main):004:0> put 'sowhat','1001','info:age','18'
hbase(main):005:0> put 'sowhat','1002','info:name','Janna'
hbase(main):006:0> put 'sowhat','1002','info:sex','female'
hbase(main):007:0> put 'sowhat','1002','info:age','20'
  1. 扫描查看表数据
hbase(main):008:0> scan 'sowhat'
hbase(main):012:0> scan 'sowhat'
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male                                                                  
 1002                                    column=info:age, timestamp=1592444470614, value=20                                                                    
 1002                                    column=info:name, timestamp=1592444462987, value=Janna                                                                
 1002                                    column=info:sex, timestamp=1592444466848, value=female  
---
hbase(main):009:0> scan 'sowhat',{STARTROW => '1001', STOPROW  => '1001'}  指定范围 左闭右开[start,end)这样的格式,必须大写!
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male  
---
hbase(main):010:0> scan 'sowhat',{STARTROW => '1001'}
ROW                                      COLUMN+CELL                                                                                                           
 1001                                    column=info:age, timestamp=1592444447588, value=18                                                                    
 1001                                    column=info:sex, timestamp=1592444439067, value=male                                                                  
 1002                                    column=info:age, timestamp=1592444470614, value=20                                                                    
 1002                                    column=info:name, timestamp=1592444462987, value=Janna                                                                
 1002                                    column=info:sex, timestamp=1592444466848, value=female     
---
  1. 查看表结构
hbase(main):011:0> describe 'sowhat'   desc  'sowhat' 也可以
Table sowhat is ENABLED                                                                                                                                        
sowhat                                                                                                                                                         
COLUMN FAMILIES DESCRIPTION                                                                                                                                    
{NAME => 'info', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'fal
se', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_
MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536'}    
  1. 更新指定字段的数据
hbase(main):012:0> put 'sowhat','1001','info:name','Nick'
hbase(main):013:0> put 'sowhat','1001','info:age','100'
hbase(main):013:0> scan 'sowhat'
ROW                                                          COLUMN+CELL                                                                                                                                                                      
 1001                                                        column=info:age, timestamp=1592445694183, value=100                                                                                                                              
 1001                                                        column=info:name, timestamp=1592445681869, value=Nick                                                                                                                            
 1001                                                        column=info:sex, timestamp=1592444439067, value=male                                                                                                                             
 1002                                                        column=info:age, timestamp=1592444470614, value=20                                                                                                                               
 1002                                                        column=info:name, timestamp=1592444462987, value=Janna                                                                                                                           
 1002                                                        column=info:sex, timestamp=1592444466848, value=female                                                                                                                           
2 row(s)
  1. 查看“指定行”或“指定列族:列”的数据
hbase(main):025:0> get 'sowhat','1001'
COLUMN                                                       CELL                                                                                                                                                                             
 info:age                                                    timestamp=1592445694183, value=100                                                                                                                                               
 info:name                                                   timestamp=1592445681869, value=Nick                                                                                                                                              
 info:sex                                                    timestamp=1592444439067, value=male                                                                                                                                              
1 row(s)
Took 0.0215 seconds                                                                                                                                                                                                                           
hbase(main):026:0> get 'sowhat','1001','info:name'
COLUMN                                                       CELL                                                                                                                                                                             
 info:name                                                   timestamp=1592445681869, value=Nick                                                                                                                                              
1 row(s)
Took 0.0146 seconds 
  1. 统计表数据行数
hbase(main):027:0> count 'sowhat'
2 row(s)
Took 0.0558 seconds                                                                                                                                                                                                                           
=> 2
  1. 删除数据
    删除某rowkey的全部数据:
hbase(main):016:0> deleteall 'sowhat','1001'

删除某rowkey的某一列数据:

hbase(main):017:0> delete 'sowhat','1002','info:sex'
  1. 清空表数据
hbase(main):032:0> truncate 'sowhat'
Truncating 'sowhat' table (it may take a while):
Disabling table...
Truncating table...
Took 2.0702 seconds                                                                                                                                                                                                                           
hbase(main):033:0> scan 'sowhat'
ROW                                                          COLUMN+CELL                                                                                                                                                                      
0 row(s)

提示:清空表的操作顺序为先disable,然后再truncate,在HBase 2.2版本上操作时候没显示必须disable。
10. 删除表
首先需要先让该表为disable状态:

hbase(main):019:0> disable 'sowhat'

然后才能drop这个表:

hbase(main):020:0> drop 'sowhat'

提示:如果直接drop表,会报错:ERROR: Table sowhat is enabled. Disable it first.
11. 变更表信息
默认情况下,列族只存储一个版本的数据,如果需要存储多个版本的数据,则需要修改列族的属性。修改后可通过desc命令查看。

put 'sowhat','1001','info:name','Nick'
put 'sowhat','1001','info:name','Nick1'
put 'sowhat','1001','info:name','Nick2'
put 'sowhat','1001','info:name','Nick3'
put 'sowhat','1001','info:name','Nick4'
hbase(main):022:0> alter 'sowhat',{NAME=>'info',VERSIONS=>3}
hbase(main):022:0> get 'sowhat','1001',{COLUMN=>'info:name',VERSIONS=>3}

COLUMN                                                       CELL                                                                                                                                                                             
 info:name                                                   timestamp=1592446266614, value=Nick4                                                                                                                                             
 info:name                                                   timestamp=1592446264202, value=Nick3                                                                                                                                             
 info:name                                                   timestamp=1592446262438, value=Nick2                                                                                                                                             
1 row(s)
put 'sowhat','1001','info:name', 'Nick0', 1592446266615  put数据的时候指定时间
  1. alter 增删列族
# 语法 
alter '表名', '列族名'

# 示例
alter 'tbl_user', 'address'

# 语法 
alter '表名', {NAME=> '列族名', METHOD=> 'delete'}

# 示例
alter 'tbl_user', {NAME=> 'address', METHOD=> 'delete'}

# 修改f1列族的版本为5
alter 't1', NAME => 'f1', VERSIONS => 5

# 修改多个列族,修改f2为内存,版本号为5
alter 't1', 'f1', {NAME => 'f2', IN_MEMORY => true}, {NAME => 'f3', VERSIONS => 5}

# 也可以修改table-scope属性,例如MAX_FILESIZE, READONLY,MEMSTORE_FLUSHSIZE, DEFERRED_LOG_FLUSH等。
# 例如,修改region的最大大小为128MB:
alter 't1', MAX_FILESIZE => '134217728'
  1. 查看所有数据类型
scan 'sowhat',{RAW=>TRUE,VERSIONS=>10}

在这里插入图片描述

4. HBase数据结构

1. RowKey

跟nosql数据库一样RowKey就是用来检索记录的主键,访问HBase 表中的行只有如下三种方式。

  1. 通过单个RowKey访问
get 'sowhat','1001'
  1. 通过RowKey的range访问
scan 'sowhat',{STARTROW => '1001', STOPROW  => '1003'} 
  1. 全表扫描
    RowKey行键 (RowKey)可以是任意字符串(最大长度是64KB,实际应用中长度一般为 10-100bytes),在HBASE内部,RowKey保存为字节数组。存储时,数据按照RowKey的字典序(byte order)排序存储。设计RowKey时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)
scan 'sowhat'

2. Column Family

列族:HBASE表中的每个列,都归属于某个列族。列族是表的schema的一部分(而列不是),必须在使用表之前定义。列名都以列族作为前缀。例如 courses:historycourses:math都属于courses 这个列族。

3. Cell

由{rowkey, column Family:columu, version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。
关键字:无类型字节码

4. Time Stamp

HBase 中通过rowkeycolumns确定的为一个存贮单元称为cell。每个 cell都保存 着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是 64位整型。时间戳可以由HBase(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版 本冲突,就必须自己生成具有唯一性的时间戳。每个 cell中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面
为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBase提供 了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段 时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

5. 命名空间

命名空间的结构:
在这里插入图片描述

  1. Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在default默认的命名空间中。
  2. RegionServer group:一个命名空间包含了默认的RegionServer Group。
  3. Permission:权限,命名空间能够让我们来定义访问控制列表ACL(Access Control List)。例如,创建表,读取表,删除,更新等等操作。
  4. Quota:限额,可以强制一个命名空间可包含的region的数量。

4. HBase 原理

HBase是一个写比读快的 框架

写原理

在这里插入图片描述
在这里插入图片描述
比如执行给table1里面rowkey=11050的数据插入数据则看如下操作。

  1. 先跟ZK 询问 /hbase/meta-region-server里面的 meta数据存储位置。
  2. 客户1找到的位置到对应的机器上查找regions数据存储概要。一般一行就是存储该数据的表明,rowkey开始位置,rowkey结束位置,根据合适的范围查找到对应的 regionServer,然后再根据数据信息 找到对应的region,然后数据写到WAL中,再到MemCache,再到HFile(KV格式存储)。

写流程:

  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
  2. 访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 将数据顺序写入(追加)到 WAL
  5. 将数据写入对应的 MemStore,数据会在 MemStore 进行排序
  6. 向客户端发送 ack;
  7. 等达到 MemStore 的刷写时机后,将数据刷写到 HFile
  8. 在web页面查看的时候会随机的给每一个region生成一个随机编号。

PS ZK数据查找跟更新的 流程

zk ==> meta ==> regionserver ==> RegionIP 

HBase0.9版本前 meta数据又要被切分 -root-

zk ==> -root- ==>  meta ==> regionserver ==> RegionIP 

读原理

在这里插入图片描述

  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
  2. 访问对应的 Region Server,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey, 查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该 table 的 region 信息以 及 meta 表的位置信息缓存在客户端的 meta cache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将 查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不 同的类型(Put/Delete)。
  5. 将从文件HFile中查询到的数据块(Block,HFile 数据存储单元,默认大小为 64KB)缓存到 Block Cache。
  6. 将合并后的最终结果,然后返回时间最新的数据返回给客户端。
  7. hbase中两种缓存机制 memstore和blockcache详解

重点:不要理解为读数据先从MemStore中读取,然后读BlockCache中,如果没有再从HFile中读取,然后将数据写入到BlockCache中。因为如果下面这样的操作怎么办?

  • 创建表,写入数据,刷新到磁盘中,

create stu ‘info’
put ‘stu’,‘info:name’,‘sowhat’
flush
bin/hbase org.apache.hadoop.hbase.io.hfile.HFile -a -b -e -k -p -f 列族文件在HDFS中路径, 目的确保数据刷新到本地了

在这里插入图片描述

  • 插入一个比 sowhat时间早的数据,

put ‘stu’,‘info:name’,‘sowhat1412’,早点的时间戳。

  • 直接scan查询可以看到 结果还是sowhat,说明数据每次都是把磁盘数据读取了放到BlockCache中,然后跟MemCache数据合并!比较时间戳,返回时间戳最新的数据。也就是每次都要涉及到磁盘到读取。

结论:HBase 把磁盘跟内存数据一起读,然后把磁盘数据放到BlockCache中,BlockCache是磁盘数据的缓存。读比写慢的工具。

Scanner

查询流程的形象图
在这里插入图片描述

Flush

一般情况下一个Region中有多个列族,而整个region中有列族跟store是一 一对应的。对于用户来说数据写到MemStore中就算完成了,但是对于底层代码来说只有数据刷到硬盘中才算彻底搞定了!因为数据是要写入到WAL(Hlog)中再写入到MemStore中的,所以刷写的时候,也有WAL个数的配置。配置文件

  1. WAL 个数 .

当 WAL 文件的数量超过 hbase.regionserver.max.logs,region 会按照时间顺序依次进行刷写,直到 WAL 文件数量减小到 hbase.regionserver.max.log 以下(该属性名已经废弃
现无需手动设置,最大值为 32)。比如我的堆内存0.4= 1T,那么我的Hlog文件可能也是大小1T,这样如果一个HLog文件大小为512M 则可能出现 10242个,所以需合理配置。

  1. hbase.regionserver.global.memstore.size

regionServer的全局memstore的大小,超过该大小会触发flush到磁盘的操作,默认是堆大小的40%,而且regionserver级别的 , flush会阻塞客户端读写。

  1. hbase.regionserver.global.memstore.size.lower.limit

可以理解为一个安全的设置,有时候集群的“写负载”非常高,写入量一直超过flush的量,这时,我们就希望memstore不要超过一定的安全设置。 在这种情况下,写操作就要被阻塞一直到memstore恢复到一个“可管理”的大小, 这个大小就是默认值是堆大小 * 0.4 * 0.95,也就是当regionserver级别的flush操作发送后,会阻塞客户端写,一直阻塞到整个regionserver级别的memstore的大小为 堆大小 * 0.4 *0.95为止

  1. hbase.regionserver.optionalcacheflushinterval

内存中的文件在自动刷新之前能够存活的最长时间,默认是1h,表示最后一条数据后的1小时。

  1. hbase.hregion.memstore.flush.size

单个region里memstore的缓存大小,超过那么整个HRegion就会flush,默认128M

StoreFile Compaction

由于 memstore 每次刷写都会生成一个新的 HFile,且同一个字段的不同版本(timestamp) 和不同类型(Put/Delete)有可能会分布在不同的 HFile 中,因此查询时需要遍历所有的 HFile。 为了减少 HFile 的个数,以及清理掉过期和删除的数据,会进行 StoreFile Compaction。

Compaction 分为两种,分别是 Minor CompactionMajor Compaction。Minor Compaction会将临近的若干个较小的 HFile 合并成一个较大的 HFile,但不会清理过期和删除的数据。 Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期和删除的数据。
在这里插入图片描述

数据删除时间

create ‘stu4’,‘info’
put ‘stu4’,‘1001’,‘info:name’,‘xianyi’
put ‘stu4’,‘1001’,‘info:name’,‘yuyang’
flush ‘stu4’ 刷新一个文件
put ‘stu4’,‘1001’,‘info:name’,‘xianyu’ 显示
flush ‘stu4’ 增加个文件
put ‘stu4’,‘1002’,‘info:name’,‘xianyi’ 显示
flush ‘stu4’
compact 三个以上的文件调用小文件合并会自动触发大文件合并,
scan ‘stu4’,{RAW=>TRUE,VERSIONS=>10}
只会显示两个文件

数据删除只有在flush 跟上面的大合并(Major compaction)的时候执行。

  1. flush 可以删除在同一个内存中的数据,flush只会操作当前内存。并且写入本地后 内存数据会丢失。
  2. Major compaction 大合并时候会自动把所以数据排序删除旧数据。

put ‘stu4’,‘1001’,‘info:name’,‘zhangsan’
put ‘stu4’,‘1001’,‘info:name’,‘lisi’
put ‘stu4’,‘1001’,‘info:name’,‘wangwu’
flush ‘stu4’
put ‘stu4’,‘1001’,‘info:name’,‘zhaoliu’ 此时查看可以看到zhaoliu
delete ‘stu4’,‘1001’,‘info:name’ 目的是删除1001的 name属性!
scan ‘stu4’,{ROW=>TRUE,VERSIONS=>10} 会显示zhaoliu 但显示已经删除了。此时flush ‘stu4’ 再查看数据,会发现Type=DeleteColumn还存在。没有删除掉,因为这个DeleteColumn还要用来删除flush 磁盘里的zhangsan,lisi,wangwu这三个数据。 而删除的标准就是调用大合并的时候!

Region Split

在这里插入图片描述
默认情况下,每个 Table 起初只有一个 Region,随着数据的不断写Region 会自动进 行拆分。刚拆分时,两个子 Region 都位于当前的 Region Server,但出于负载均衡的考虑, HMaster 有可能会将某个 Region 转移给其他的 Region Server。

Region Split 时机:

  1. 当 1 个 region 中的某个 Store 下所有 StoreFile 的总大小超过 hbase.hregion.max.filesize(默认10G), 该 Region 就会进行拆分(0.94 版本之前)。
  2. 当 1 个 region 中的某个 Store 下所有 StoreFile 的总大小超过 Min(R^2 * “hbase.hregion.memstore.flush.size”,hbase.hregion.max.filesize"),该 Region 就会进行拆分,其 中 R 为当前 Region Server 中属于该 Table 的个数(0.94 版本之后)。hbase.hregion.memstore.flush.size=128M

第一次的阈值是128,
切分后结果64 , 64
第二次阈值512M
64,512 ⇒ 54 + 256 + 256
最后会形成一个 64M…10G 的这样Region队列,会产生数据倾斜问题。
解决方法:提前做好Region组的规划,0-1k,1k-2k,2k-3k这样的。

官方不建议用多个列族,比如有CF1,CF2,CF3,但是 CF1数据很多而CF2跟CF3数据很少,那么当触发了region切分的时候,会把CF2跟CF3分成若干小份,不利于系统维护。

参考

HBase配置文件

©️2020 CSDN 皮肤主题: 猿与汪的秘密 设计师: 上身试试 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值