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


第二天:Hbase进阶_数据

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}

第二天:Hbase进阶_hadoop_02

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:history​​​,​​courses:math​​都属于courses 这个列族。

3. Cell

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

关键字:​​无类型​​、​​字节码​​。

4. Time Stamp

HBase 中通过​​rowkey​​和​​columns​​确定的为一个存贮单元称为cell。每个 cell都保存 着同一份数据的​​多个版本​​。版本通过​​时间戳​​来索引。时间戳的类型是 64位整型。时间戳可以由HBase(在数据写入时自动 )赋值,此时时间戳是精确到毫秒 的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版 本冲突,就必须自己生成具有唯一性的时间戳。每个 cell中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面

为了避免数据存在过多版本造成的的管理 (包括存贮和索引)负担,HBase提供 了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段 时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

5. 命名空间

命名空间的结构:

第二天:Hbase进阶_数据_03


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

4. HBase 原理

HBase是一个写比读快的 框架

写原理

第二天:Hbase进阶_表名_04

第二天:Hbase进阶_hbase_05

比如执行给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

读原理

第二天:Hbase进阶_数据_06


  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中路径, 目的确保数据刷新到本地了


第二天:Hbase进阶_表名_07

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


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


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

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

Scanner

查询流程的形象图

第二天:Hbase进阶_hbase_08

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 Compaction​​ 和 ​​Major Compaction​​。Minor Compaction会将临近的若干个较小的 HFile 合并成一个较大的 HFile,但​​不会​​清理过期和删除的数据。 Major Compaction 会将一个 Store 下的所有的 HFile 合并成一个大 HFile,并且会清理掉过期和删除的数据。

第二天:Hbase进阶_hbase_09

数据删除时间


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

第二天:Hbase进阶_表名_10

默认情况下,每个 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配置文件