1. 如果有几百亿条数据,如何在hbase表中存放
1、首先你有没有那么多台服务器的集群,如果只是几台,你要想够不够,你的hbase 有几百亿,那么你hdfs上的数据可能要有两个备份,你这几百亿条是如何生成的,肯定是maprece跑出来导入到hbase中把,那么原始数据你要不要留,如果留,加上备份就要三份,所以节点的多少要确定。
2、几百亿其实挺多的,hbase 的设计一定要跟你的业务相关,hbase他不能完全像关系型数据库那样去随意查询,到达一定量级,如果设计的不好也是非常之慢的,甚至将hbase搞到崩溃。所以你先去网上看看rowkey的设计原则,比如长度原则等等,然后根据自己业务,哪些查询经常用到,哪些不会用到,想要用hbase实现那种非常灵活的类似关系数据库的查询是不理智的。
3、楼上的兄弟说得对,还有region热点的问题,如果你的hbase数据不是那种每天增量的数据,建议跑个maprece对你的数据进行各评判,看看如何能将数据尽可能均匀的分配到每个region中,当然这需要预先分配region
4、几百亿条数据,如果对rowkey进行模糊过滤一定非常非常之慢,所以可以考虑二级索引或者协处理器
2. hbase数据库是关系型数据库吗
Hive 存储格式和关系型数据库之间进行导入导出
最近更新时间:2020-09-29 15:54:18
前往 GitHub 编辑
1. 开发准备
2. 将关系型数据库导入到 Hive 中
3. 将 Hive 导入到关系型数据库中
使用 HDFS 中的 Hive 数据
使用 Hcatalog 进行导入
4. 将 orc 格式的 Hive 表格导入到关系型数据库中
确认已开通腾讯云,并且创建了一个 EMR 集群。在创建 EMR 集群的时候需要在软件配置界面选择 Sqoop,Hive 组件。
Sqoop 等相关软件安装在路径 EMR 云服务器的/usr/local/service/路径下。
- [root@172 ~]# su hadoop[hadoop@172 ~]# cd /usr/local/service/hive
- [hadoop@172 hive]$ hive
- hive> create database hive_from_sqoop;
- OK
- Time taken: 0.167 seconds
- [hadoop@172 hive]# cd /usr/local/service/sqoop
- [hadoop@172 sqoop]$ bin/sqoop-import --connect jdbc:mysql://$mysqlIP/test --username root -P --table sqoop_test_back --hive-database hive_from_sqoop --hive-import --hive-table hive_from_sqoop
$mysqlIP:腾讯云关系型数据库(CDB)的内网地址。
test:MySQL 数据库名称。
--table:要导出的 MySQL 表名。
--hive-database:Hive 数据库名。
--hive-table:导入的 Hive 表名。
- hive> select * from hive_from_sqoop;OK1 first 2018-07-03 16:07:46.0 spark2 second 2018-07-03 15:30:57.0 mr3 third 2018-07-03 15:31:07.0 yarn4 forth 2018-07-03 15:39:38.0 hbase5 fifth 2018-07-03 16:02:29.0 hive6 sixth 2018-07-03 16:09:58.0 sqoopTime taken: 1.245 seconds, Fetched: 6 row(s)
- [root@172 ~]# su hadoop[hadoop@172 ~]# cd /usr/local/service/hive
- #!/bin/bashMAXROW=1000000 #指定生成数据行数for((i = 0; i < $MAXROW; i++))doecho $RANDOM, "$RANDOM"done
- [hadoop@172 hive]$ ./gen_data.sh > hive_test.data
- [hadoop@172 hive]$ hdfs dfs -put ./hive_test.data /$hdfspath
- [hadoop@172 hive]$ bin/hivehive> create database hive_to_sqoop; #创建数据库 hive_to_sqoopOK
- Time taken: 0.176 secondshive> use hive_to_sqoop; #切换数据库OK
- Time taken: 0.176 secondshive> create table hive_test (a int, b string)hive> ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';#创建数据表 hive_test, 并指定列分割符为’,’
- OK
- Time taken: 0.204 secondshive> load data inpath "/$hdfspath/hive_test.data" into table hive_test; #导入数据
- [hadoop@172 hive]$ mysql -h $mysqlIP –p
- Enter password:
- mysql> create table table_from_hive (a int,b varchar(255));
- [hadoop@172 hive]$ cd ../sqoop/bin
- [hadoop@172 bin]$ ./sqoop-export --connect jdbc:mysql://$mysqlIP/test --username root -P
- --table table_from_hive --export-dir /usr/hive/warehouse/hive_to_sqoop.db/hive_test
- [hadoop@172 hive]$ cd ../sqoop/bin
- [hadoop@172 bin]$ ./sqoop-export --connect jdbc:mysql://$mysqlIP/test --username root -P
- --table table_from_hive --hcatalog-database hive_to_sqoop --hcatalog-table hive_test
- [hadoop@172 hive]$ mysql -h $mysqlIP –p #连接 MySQLEnter password:mysql> use test;
- Database changed
- mysql> select count(*) from table_from_hive; #现在表中有1000000条数据+----------+| count(*) |+----------+| 1000000 |+----------+1 row in set (0.03 sec)
- mysql> select * from table_from_hive limit 10; #查看表中前10条记录+-------+----------+| a | b |
- +-------+----------+
- | 28523 | "3394" || 31065 | "24583" |
- | 399 | "23629" || 18779 | "8377" |
- | 25376 | "30798" || 20234 | "22048" |
- | 30744 | "32753" || 21423 | "6117" |
- | 26867 | "16787" || 18526 | "5856" |
- +-------+----------+
- 10 rows in set (0.00 sec)
- [hadoop@172 bin]$ ./sqoop-export --help
我的收藏
本页目录:
本文介绍了使用腾讯云 Sqoop 服务将数据在 Mysql 和 Hive 之间相互导入导出的方法。
1. 开发准备
2. 将关系型数据库导入到 Hive 中
本节将继续使用上一节的用例。
进入 EMR 控制台,复制目标集群的实例 ID,即集群的名字。再进入关系型数据库控制台,使用 Ctrl+F 进行搜索,找到集群对应的 MySQL 数据库,查看该数据库的内网地址 $mysqlIP。
登录 EMR 集群中的任意机器,最好是登录到 Master 节点。登录 EMR 的方式请参考登录 Linux 实例。这里我们可以选择使用 WebShell 登录。单击对应云服务器右侧的登录,进入登录界面,用户名默认为 root,密码为创建 EMR 时用户自己输入的密码。输入正确后,即可进入命令行界面。
在 EMR 命令行先使用以下指令切换到 Hadoop 用户,并进入 Hive 文件夹:
新建一个 Hive 数据库:
使用 sqoop-import 命令把上一节中创建的 MySQL 数据库导入到 Hive 中:
执行指令需要输入您的 MySQL 密码,默认为您创建 EMR 集群时设置的密码。执行成功后,可以在 Hive 中查看导入的数据库:
3. 将 Hive 导入到关系型数据库中
Sqoop 支持将 Hive 表中的数据导入到关系型数据库中。先在 Hive 中创建新表并导入数据。
登录 EMR 集群中的任意机器,最好是登录到 Master 节点。在 EMR 命令行先使用以下指令切换到 Hadoop 用户,并进入 Hive 文件夹:
新建一个 bash 脚本文件 gen_data.sh,在其中添加以下代码:
并按如下方式执行:
这个脚本文件会生成1,000,000个随机数对,并且保存到文件 hive_test.data 中。
使用如下指令把生成的测试数据先上传到 HDFS 中:
其中 $hdfspath 为 HDFS 上的您存放文件的路径。
连接 Hive 并创建测试表:
$hdfspath 为 HDFS 上的您存放文件的路径。
成功后可使用quit命令退出 Hive 数据仓库。连接关系型数据库并创建对应的表格:
其中 $mysqlIP 为该数据库的内网地址,密码为您创建集群时设置的密码。
在 MySQL 中创建一个名为 test 的表格,MySQL 中的表字段名字和 Hive 中的表字段名字必须完全一致:
成功创建表格后即可退出 MySQL。
使用 Sqoop 把 Hive 数据仓库中的数据导入到关系型数据库中有两种方法,可以直接使用 HDFS 存储的 Hive 数据,也可以使用 Hcatalog 来进行数据的导入。
使用 HDFS 中的 Hive 数据
切换进入 Sqoop 文件夹,然后使用以下指令把 Hive 数据库中的数据导出到关系型数据库中:
其中 $mysqlIP 为您的关系型数据库的内网 IP 地址,test 为关系型数据库中的数据库名,--table 后跟的参数为您的关系型数据库的表名,--export-dir 后跟的参数为 Hive 表中的数据在 HDFS 中存储的位置。
使用 Hcatalog 进行导入
切换进入 Sqoop 文件夹,然后使用以下指令把 Hive 数据库中的数据导出到关系型数据库中:
其中 $mysqlIP 为您的关系型数据库的内网 IP 地址,test 为关系型数据库中的数据库名,--table 后跟的参数为您的关系型数据库的表名,--hcatalog-database 后面跟的参数是要导出的 Hive 表所在的数据库的名称,--hcatalog-table 后面跟的参数是要 Hive 中要导出的表的名称。
操作完成后可以进入关系型数据库查看是否导入成功:
更多关于 sqoop-export 命令的参数可以通过如下命令查看:
4. 将 orc 格式的 Hive 表格导入到关系型数据库中
3. 北大青鸟java培训:Hbase知识点总结
hbase概念:非结构化的分布式的面向列存储非关系型的慧羡开源的数据库,根据谷歌的三大论文之一的bigtable高宽厚表作用:为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
能干什么:存储大量结果集数据,低延迟的随机查询。
sql:结构化查询语言nosql:非关系型数据库,列存储和文档存储(查询低延迟),hbase是nosql的一个种类,其特点是列式存储。
非关系型数据库--列存储(hbase)非关系型数据库--文档存储(MongoDB)非关系型数据库--内存式存储(redis)非关系型数据库--图形模型(graph)hive和hbase区别?Hive的定位是数据仓库,虽然也有增删改查,但其删改查对应的是整张表而不是单行数据,查询的延迟较高。
其本质是更加方便的使用mr的威力来进行离线分析的一个数据分析工具。
HBase的定位是hadoop的数据库,电脑培训http://www.kmbdqn.cn/发现是一个典型的Nosql,所以HBase是用来在大量数据中进行低延迟的随机查询的。
hbase运行方式:standalonedistrubited单节点和伪分布式?单节点:单独的进程运行在同一台机器前慧拍上hbase应用场景:碧首存储海量数据低延迟查询数据hbase表由多行组成hbase行一行在hbase中由行健和一个或多个列的值组成,按行健字母顺序排序的存储。
4. HBase从入门到精通11:HBase数据保存过程和Region分裂
本节来介绍一下HBase的数据保存过程和Region分裂过程的相关知识。
HBase中表的数据是存储在RegionServer上的一个个Region中的,表的一个列族对应于一个Region。Region是按照数据行键Rowkey的字典序来存储数据的。假如我们有一张表Bigdata,该表有一个列族Info,该列族下有一个列Name,且为了便于说明,假设行键和Name相同,按照行键字典序保存数据的过程如下图所示:
HBase保存数据的流程有以下几个步骤:
HBase表的列族在创建之初只有一个Region,随着插入数据的增多Region变得越来越大。过大的Region使得查询效率降低,因此当Region的大小超过某一阈值时,HBase将执行Region的分裂操作:即将一个大Region拆分成两个相等规模的小Region。具体的Region分裂过程如下图所示:
HBase的Region分裂过程需要注意以下几个问题:
虽然Region分裂后可以提高HBase的读写性能,但是Region分裂过程会对集群网络造成很大的压力,尤其是要分裂的Region尺寸过大、数目过多时,甚至可以使整个集群瘫痪。例如,当年京东的Region分裂事件,造成整个集群瘫痪9个小时以上,无法对外提供服务,经济损失可想而知。
因此,应该根据实际需求将Region分裂的阈值设置的合理一些,太小会频繁触发分裂,太大分裂时会对网络传输造成一定的压力。
5. hbase的作用
HBase 是典型的 NoSQL 数据库,通常被描述成稀疏的、分布式的、持久化的,由行键、列键和时间戳进行索引的多维有序映射数据库,主要用来存储非结构化和半结构化的数据。因为 HBase 基于 Hadoop 的 HDFS 完成分布式存储,以及 MapRece 完成分布式并行计算,所以它的一些特点与 Hadoop 相同,依靠横向扩展,通过不断增加性价比高的商业服务器来增加计算和存储能力。
HBase 虽然基于 Bigtable 的开源实现,但它们之间还是有很多差别的,Bigtable 经常被描述成键值数据库,而 HBase 则是面向列存储的分布式数据库。
下面介绍 HBase 具备的显着特性,这些特性让 HBase 成为当前和未来最实用的数据库之一。
容量巨大
HBase 的单表可以有百亿行、百万列,可以在横向和纵向两个维度插入数据,具有很大的弹性。
当关系型数据库的单个表的记录在亿级时,查询和写入的性能都会呈现指数级下降,这种庞大的数据量对传统数据库来说是一种灾难,而 HBase 在限定某个列的情况下对于单表存储百亿甚至更多的数据都没有性能问题。
HBase 采用 LSM 树作为内部数据存储结构,这种结构会周期性地将较小文件合并成大文件,以减少对磁盘的访问。
扩展性强
HBase 工作在 HDFS 之上,理所当然地支持分布式表,也继承了 HDFS 的可扩展性。HBase 的扩展是横向的,横向扩展是指在扩展时不需要提升服务器本身的性能,只需添加服务器到现有集群即可。
HBase 表根据 Region 大小进行分区,分别存在集群中不同的节点上,当添加新的节点时,集群就重新调整,在新的节点启动 HBase 服务器,动态地实现扩展。这里需要指出,HBase 的扩展是热扩展,即在不停止现有服务的前提下,可以随时添加或者减少节点。
高可靠性
HBase 运行在 HDFS 上,HDFS 的多副本存储可以让它在岀现故障时自动恢复,同时 HBase 内部也提供 WAL 和 Replication 机制。
WAL(Write-Ahead-Log)预写日志是在 HBase 服务器处理数据插入和删除的过程中用来记录操作内容的日志,保证了数据写入时不会因集群异常而导致写入数据的丢失;而 Replication 机制是基于日志操作来做数据同步的。
6. 计算机里面Hbase作用是什么
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
模型
主要讨论逻辑模型和物理模型
(1)逻辑模型
Hbase的名字的来源是Hadoop database,即hadoop数据库。
主要是从用户角度来考虑,即如何使用Hbase。
(2)物理模型
主要从实现Hbase的角度来讨论
HBase数据模型
逻辑结构
逻辑上,HBase 的数据模型同关系型数据库很类似,数据存储在一张表中,有行有列。但从 HBase 的底层物理存储结构(K-V)来看,HBase 更像是一个 multi-dimensional map
7. hbase和关系型数据库的区别
Mongodb用于存储非结构化数据,尤其擅长存储json格式的数据。存储的量大概在10亿级别,再往上性能就下降了,除非另外分库。
Hbase是架构在hdfs上的列式存储,擅长rowkey的快速查询,但模糊匹配查询(其实是前模糊或全模糊)不擅长,但存储的量可以达到百亿甚至以上,比mongodb的存储量大多了。
8. 怎样将关系型数据表转换至hbase数据表
首先需要把关系型数据库的数据表的数据增加由 “纵向延伸”,转变为HBase数据表的“横向延伸”
一、Hbase的存储结构
a) HBase以表(HTable)的形式存储数据
b) HTable包括很多行,每行通过RowKey唯一标记,行按照RowKey的字典序排列,表在行的方向上分割为多个HRegion
c) 每行包括一个RowKey和多个Column Family,数据按照Column Family进行物理切割,即不同Column Family的数据放在不同的Store中,一个Column Family放在一个Strore中
d) HRegion由多个Store组成。一个Store由物理上存在的一个MemStrore(内存中)和多个StoreFile(HFile)中
二、设计原则:
(1)rowkey
a) rowkey是hbase的key-value存储中的key,通常使用用户要查询的字段作为rowkey ,查询结果作为value ,HBase中RowKey是按照字典序排列的
(2)Column Family的设计需遵循:
a) 不同Column Family的数据,在物理上是分开的,尽量避免一次请求需要拿到的Column分布在不同的Column Family中;
b) CF的数量尽量要少,原因是过多的columnfamily之间会互相影响
(3) column
对于column需要扩展的应用,column可以按普通的方式设计,但是对于列相对固定的应用,最好采用将一行记录封装到一个column中的方式,这样能够节省存储空间。封装的方式推荐protocolbuffer。
9. hbase 的数据存储及Region变化(flush compaction spilt)和性能调优
1. 对表做预分区处理(即在建表时指定Region数量和拆分边界);
2.配置hbase.hregion.max.filesize为50GB
以fileServer为例,在使用默认的split策略-- 的情况下,16个预分区Region, 则单个Resion容量达到 min(32,50),即32GB时分裂。
3.修改Linux最大文件句柄数
因为hbase是以文件的形式存储数据,最大文件句柄数影响着hbase的并发量。
用root权限修改/etc/security/limits.conf文件,增加以下内容(前面的*不能忽略):
* soft nproc 10240
* hard nproc 10240
* soft nofile 10240
* hard nofile 10240
编辑/etc/pam.d/common-session,加入一行
session required pam_limits.so
编辑/etc/profile,加入
ulimit -SHn 51200
重新登陆,生效
4.HRegionServer挂掉异常和解决:
is not online on......
常规解决方案:
删除zk中hbase的缓存
重启hbase
使用上述解决方案后本次异常依旧存在,并且HMaster和HRegionServer都不断的自动挂掉。
HMaster报错:
解决方案:
新增配置(看情况决定使用不使用,建议在HMaster不能启动时排除错误使用)(让启动hbase时只让HMaster去进行日志split,缺点是恢复数据时候速度慢):
<property>
<name>hbase.master.distributed.log.splitting</name>
<value>false</value>
</property>
删除WAL文件(会丢数据):
6. RPC请求的最大线程数
hbase.regionserver.handler.count 默认是10,在服务器测试时建议设置到50(经测试在单个Region Server时无用,单个RegionServer 最多在6个线程put时保持稳定)
7.日志分割(hbase出错后恢复数据)
MemStore中大量更新丢失时,对数据进行恢复时会做日志分割
hbase.regionserver.hlog.splitlog.writer.threads 日志分割的线程数, 默认为3 ,建议设定为10
8.Region Server频繁掉线
出现Hbase Region Server频繁掉线的情况,表现为在多线程put的情况下,忽然Hbase Region Server掉线
猜测是GC或者split过程中没有及时和ZK通信,导致与ZK连接时间超时,zk返回dead region到master,当Hbase Region恢复正常后,找不到wal,产生如下报错。
zookeeper.session.timeout :默认值是3分钟
但是 hbase regionserver和zookeeper的timeout不是单方面决定的,是取决于hbase的zookeeper.session.timeout和zookeeper的MaxSessionTimeout中的最小值
配置hbase:
zookeeper.session.timeout
600000
配置zookeeper:
tickTime=30000
9.内存及GC优化
在测试的过程中依旧出现Hbase Region Server掉线的情况,报错如下
2021-02-0318:49:14,091INFO[sync.0]wal.FSHLog: Slow sync cost:1955ms, current pipeline: []
2021-02-0318:49:14,091WARN[regionserver/botsc/192.168.0.107:16020.append-pool5-t1]wal.MetricsWAL: regionserver/botsc/192.168.0.107:16020.append-pool5-t1 took1953ms appending an edit to wal; len~=109
2021-02-0318:49:14,106ERROR[sync.3]wal.FSHLog:Errorsyncing, request close of WAL
java.io .IOException:io.grpc.StatusRuntimeException: CANCELLED: Failed to stream message
at seaweed.hdfs.SeaweedOutputStream.(SeaweedOutputStream.java:78)
at seaweed.hdfs.SeaweedOutputStream.(SeaweedOutputStream.java:263)
at seaweed.hdfs.SeaweedOutputStream.flushInternalAsync(SeaweedOutputStream.java:243)
at seaweed.hdfs.SeaweedOutputStream.flush(SeaweedOutputStream.java:129)
at java.io .FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io .DataOutputStream.flush(DataOutputStream.java:123)
at org.apache.hadoop.hbase.regionserver.wal.ProtobufLogWriter.sync(ProtobufLogWriter.java:170)
at org.apache.hadoop.hbase.regionserver.wal.FSHLog$SyncRunner.run(FSHLog.java:1286)
at java.lang.Thread.run(Thread.java:748)
修改hbase的配置文件hbase-env.sh,GC优化如下:
export HBASE_HEAPSIZE=21384
export master_heapsize=8292
export regionserver_heapsize=21384
export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC -XX:=60 -XX:+UseParNewGC -XX:ParallelGCThreads=6"
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Xmx8g -Xms8g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:=70"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Xmx20g -Xms20g -Xmn1g -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC -XX:=70"
10. HBase存储架构
上图是HBase的存储架构图。
由上图可以知道,客户端是通过Zookeeper找到HMaster,然后再与具体的Hregionserver进行沟通读写数据的。
具体到物理实现,细节包括以下这些:
首先要清楚HBase在hdfs中的存储路径,以及各个目录的作用。在hbase-site.xml 文件中,配置项 <name> hbase.rootdir</name> 默认 “/hbase”,就是hbase在hdfs中的存储根路径。以下是hbase0.96版本的个路径作用。1.0以后的版本请参考这里: https://blog.bcmeng.com/post/hbase-hdfs.html
1、 /hbase/.archive
HBase 在做 Split或者 compact 操作完成之后,会将 HFile 移到.archive 目录中,然后将之前的 hfile 删除掉,该目录由 HMaster 上的一个定时任务定期去清理。
2、 /hbase/.corrupt
存储HBase损坏的日志文件,一般都是为空的。
3、 /hbase/.hbck
HBase 运维过程中偶尔会遇到元数据不一致的情况,这时候会用到提供的 hbck 工具去修复,修复过程中会使用该目录作为临时过度缓冲。
4、 /hbase/logs
HBase 是支持 WAL(Write Ahead Log) 的,HBase 会在第一次启动之初会给每一台 RegionServer 在.log 下创建一个目录,若客户端如果开启WAL 模式,会先将数据写入一份到.log 下,当 RegionServer crash 或者目录达到一定大小,会开启 replay 模式,类似 MySQL 的 binlog。
5、 /hbase/oldlogs
当.logs 文件夹中的 HLog 没用之后会 move 到.oldlogs 中,HMaster 会定期去清理。
6、 /hbase/.snapshot
hbase若开启了 snapshot 功能之后,对某一个用户表建立一个 snapshot 之后,snapshot 都存储在该目录下,如对表test 做了一个 名为sp_test 的snapshot,就会在/hbase/.snapshot/目录下创建一个sp_test 文件夹,snapshot 之后的所有写入都是记录在这个 snapshot 之上。
7、 /hbase/.tmp
当对表做创建或者删除操作的时候,会将表move 到该 tmp 目录下,然后再去做处理操作。
8、 /hbase/hbase.id
它是一个文件,存储集群唯一的 cluster id 号,是一个 uuid。
9、 /hbase/hbase.version
同样也是一个文件,存储集群的版本号,貌似是加密的,看不到,只能通过web-ui 才能正确显示出来
10、 -ROOT-
该表是一张的HBase表,只是它存储的是.META.表的信息。通过HFile文件的解析脚本 hbase org.apache.hadoop.hbase.io.hfile.HFile -e -p -f 可以查看其存储的内容,如下所示:
以上可以看出,-ROOT-表记录的.META.表的所在机器是dchbase2,与web界面看到的一致:
11、 .META.
通过以上表能找到.META.表的信息,该表也是一张hbase表,通过以上命令,解析其中一个region:
以上可以看出,adt_app_channel表的数据记录在dchbase3这台reginserver上,也与界面一致,如果有多个region,则会在表名后面加上rowkey的范围:
通过以上描述,只要找到-ROOT-表的信息,就能根据rowkey找到对应的数据,那-ROOT-在哪里找呢?从本文一开始的图中可以知道,就是在zookeeper中找的。进入zookeeper命令行界面:
可以看出-ROOT-表存储在 dchbase3 机器中,对应界面如下:
以上就是HBase客户端根据指定的rowkey从zookeeper开始找到对应的数据的过程。
那在Region下HBase是如何存储数据的呢?
以下就具体操作一张表,查询对应的HFile文件,看HBase的数据存储过程。
在HBase创建一张表 test7,并插入一些数据,如下命令:
查看wal日志,通过 hbase org.apache.hadoop.hbase.regionserver.wal.HLog --mp -p 命令可以解析HLog文件,内容如下:
查看HFile文件,内容如下:
由此可见,HFile文件就是存储HBase的KV对,其中Key的各个字段包含了的信息如下:
由于hbase把cf和column都存储在HFile中,所以在设计的时候,这两个字段应该尽量短,以减少存储空间。
但删除一条记录的时候,HBase会怎么操作呢?执行以下命令:
删除了rowkey为200的记录,查看hdfs,原来的HFile并没有改变,而是生成了一个新的HFile,内容如下:
所以在HBase中,删除一条记录并不是修改HFile里面的内容,而是写新的文件,待HBase做合并的时候,把这些文件合并成一个HFile,用时间比较新的文件覆盖旧的文件。HBase这样做的根本原因是,HDFS不支持修改文件。