在HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入,删除,查询数据都需要先找到相应的RegionServer。什么叫相应的RegionServer?就是管理你要操作的那个Region的RegionServer。Client本身并不知道哪个RegionServer管理哪个Region,那么它是如何找到相应的RegionServer的?本文就是在研究源码的基础上揭秘这个过程。
在前面的文章“HBase存储架构”中我们已经讨论了HBase基本的存储架构。在此基础上我们引入两个特殊的概念:-ROOT-和.META.。这是什么?它们是HBase的两张内置表,从存储结构和操作方法的角度来说,它们和其他HBase的表没有任何区别,你可以认为这就是两张普通的表,对于普通表的操作对它们都适用。它们与众不同的地方是HBase用它们来存贮一个重要的系统信息——Region的分布情况以及每个Region的详细信息。
好了,既然我们前面说到-ROOT-和.META.可以被看作是两张普通的表,那么它们和其他表一样就应该有自己的表结构。没错,它们有自己的表结构,并且这两张表的表结构是相同的,在分析源码之后我将这个表结构大致的画了出来:
我们来仔细分析一下这个结构,每条Row记录了一个Region的信息。
首先是RowKey,RowKey由三部分组成:TableName, StartKey 和 TimeStamp。RowKey存储的内容我们又称之为Region的Name。哦,还记得吗?我们在前面的文章中提到的,用来存放Region的文件夹的名字是RegionName的Hash值,因为RegionName可能包含某些非法字符。现在你应该知道为什么RegionName会包含非法字符了吧,因为StartKey是被允许包含任何值的。将组成RowKey的三个部分用逗号连接就构成了整个RowKey,这里TimeStamp使用十进制的数字字符串来表示的。这里有一个RowKey的例子:
Table1,RK10000,12345678
然后是表中最主要的Family:info,info里面包含三个Column:regioninfo, server, serverstartcode。其中regioninfo就是Region的详细信息,包括StartKey, EndKey 以及每个Family的信息等等。server存储的就是管理这个Region的RegionServer的地址。
所以当Region被拆分、合并或者重新分配的时候,都需要来修改这张表的内容。
到目前为止我们已经学习了必须的背景知识,下面我们要正式开始介绍Client端寻找RegionServer的整个过程。我打算用一个假想的例子来学习这个过程,因此我先构建了假想的-ROOT-表和.META.表。
我们先来看.META.表,假设HBase中只有两张用户表:Table1和Table2,Table1非常大,被划分成了很多Region,因此在.META.表中有很多条Row用来记录这些Region。而Table2很小,只是被划分成了两个Region,因此在.META.中只有两条Row用来记录。这个表的内容看上去是这个样子的:
.META.
现在假设我们要从Table2里面插寻一条RowKey是RK10000的数据。那么我们应该遵循以下步骤:
1. 从.META.表里面查询哪个Region包含这条数据。
2. 获取管理这个Region的RegionServer地址。
3. 连接这个RegionServer, 查到这条数据。
好,我们先来第一步。问题是.META.也是一张普通的表,我们需要先知道哪个RegionServer管理了.META.表,怎么办?有一个方法,我们把管理.META.表的RegionServer的地址放到ZooKeeper上面不久行了,这样大家都知道了谁在管理.META.。
貌似问题解决了,但对于这个例子我们遇到了一个新问题。因为Table1实在太大了,它的Region实在太多了,.META.为了存储这些Region信息,花费了大量的空间,自己也需要划分成多个Region。这就意味着可能有多个RegionServer在管理.META.。怎么办?在ZooKeeper里面存储所有管理.META.的RegionServer地址让Client自己去遍历?HBase并不是这么做的。
HBase的做法是用另外一个表来记录.META.的Region信息,就和.META.记录用户表的Region信息一模一样。这个表就是-ROOT-表。这也解释了为什么-ROOT-和.META.拥有相同的表结构,因为他们的原理是一模一样的。
假设.META.表被分成了两个Region,那么-ROOT-的内容看上去大概是这个样子的:
-ROOT-
这么一来Client端就需要先去访问-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。这个地址被存在ZooKeeper中。默认的路径是:
/hbase/root-region-server
等等,如果-ROOT-表太大了,要被分成多个Region怎么办?嘿嘿,HBase认为-ROOT-表不会大到那个程度,因此-ROOT-只会有一个Region,这个Region的信息也是被存在HBase内部的。
现在让我们从头来过,我们要查询Table2中RowKey是RK10000的数据。整个路由过程的主要代码在org.apache.hadoop.hbase.client.HConnectionManager.TableServers中:
private HRegionLocation locateRegion(final byte [] tableName,
final byte [] row, boolean useCache)
throws IOException{
if (tableName == null || tableName.length == 0) {
throw new IllegalArgumentException(
“table name cannot be null or zero length”);
}
if (Bytes.equals(tableName, ROOT_TABLE_NAME)) {
synchronized (rootRegionLock) {
// This block guards against two threads trying to find the root
// region at the same time. One will go do the find while the
// second waits. The second thread will not do find.
if (!useCache || rootRegionLocation == null) {
this.rootRegionLocation = locateRootRegion();
}
return this.rootRegionLocation;
}
} else if (Bytes.equals(tableName, META_TABLE_NAME)) {
return locateRegionInMeta(ROOT_TABLE_NAME, tableName, row, useCache,
metaRegionLock);
} else {
// Region not in the cache – have to go to the meta RS
return locateRegionInMeta(META_TABLE_NAME, tableName, row, useCache, userRegionLock);
}
}
这是一个递归调用的过程:
获取Table2,RowKey为RK10000的RegionServer
=>
获取.META.,RowKey为Table2,RK10000, 99999999999999的RegionServer
=>
获取-ROOT-,RowKey为.META.,Table2,RK10000,99999999999999,99999999999999的RegionServer
=>
获取-ROOT-的RegionServer
=>
从ZooKeeper得到-ROOT-的RegionServer
=>
从-ROOT-表中查到RowKey最接近(小于)
.META.,Table2,RK10000,99999999999999,99999999999999的一条Row,并得到.META.的RegionServer
=>
从.META.表中查到RowKey最接近(小于)Table2,RK10000, 99999999999999的一条Row,并得到Table2的RegionServer
=>
从Table2中查到RK10000的Row
到此为止Client完成了路由RegionServer的整个过程,在整个过程中使用了添加“99999999999999”后缀并查找最接近(小于)RowKey的方法。对于这个方法大家可以仔细揣摩一下,并不是很难理解。
最后要提醒大家注意两件事情:
- 在整个路由过程中并没有涉及到MasterServer,也就是说HBase日常的数据操作并不需要MasterServer,不会造成MasterServer的负担。
- Client端并不会每次数据操作都做这整个路由过程,很多数据都会被Cache起来。至于如何Cache,则不在本文的讨论范围之内。
分享到:
相关推荐
#### 一、HBase数据读写流程 **1.1 创建表** 在HBase中,创建表是一项关键任务,通常由`Master`节点完成。这一过程涉及到以下步骤: - **获取Master地址**: 客户端首先需要从ZooKeeper(简称`ZK`)获取`Master`的...
HBase 的读写过程可以分为两部分:写数据流程和读数据流程。 写数据流程 写数据流程主要包括以下步骤: 1. 客户端将数据写入到 RegionServer 的 HLog 中。 2. RegionServer 将数据写入到 MemStore 中。 3. 当 ...
用户可以在MapReduce程序中访问HBase中的数据,也可以将MapReduce作为批量加载数据到HBase中的手段。 ### HBase安全 HBase的安全章节讲述了如何安全地访问HBase集群,包括安全客户端访问、访问控制和安全批量加载...
编译后的 HBaseClient 包含了所有必要的类和库,可以无缝集成到Java项目中,简化了开发流程。 在 HBaseClient-Download-master 压缩包中,我们可以期待找到以下内容: 1. **源代码**:可能包含 HBaseClient 的源...
- **REST Gateway**: 支持HTTP RESTful API,允许任何支持HTTP协议的客户端访问HBase。 - **Pig和Hive**: 提供高级语言支持,简化数据统计处理流程。 - **Sqoop**: 用于轻松地将关系型数据库管理系统(RDBMS)中的数据...
10. **生态集成**:HBase与其他大数据组件(如Hadoop、Spark、Flink等)有良好的集成,可以在大数据处理流程中发挥关键作用。 HBase在大数据领域中的应用广泛,特别是在实时分析、日志处理、物联网数据存储等方面。...
- MapReduce可以直接访问HBase:MapReduce作业可以作为客户端直接访问HBase,进行数据处理。 3. **HBase的特性描述** - 高可靠性:HBase具有自动故障恢复机制,能够在发生故障时自动将数据复制到其他节点。 - ...
总的来说,HBase的源码分析涉及到客户端与服务器的交互、RPC通信机制、数据存储流程以及系统架构等多个层面。理解这些核心机制对于优化HBase性能、排查问题以及进行二次开发都至关重要。通过对HBase源码的深入学习,...
通过对HBase 1.2.0源码的阅读,可以深入了解这些机制的实现细节,比如Region分配算法、数据读写的内部流程、Bloom Filter的构建和使用、以及Compaction策略的设定等。这将有助于开发者更好地优化HBase应用,解决实际...
- **C/C++ Apache HBase Client**:提供 C/C++ 开发者使用的 HBase 客户端接口。 #### 十二、HBase 性能调优 - **操作系统**:指导如何调整操作系统设置以优化 HBase 性能。 - **网络**:说明网络配置如何影响 ...
HBase的源码通常包括多个模块,如`hbase-client`, `hbase-server`, `hbase-common`等。这些模块分别负责客户端API、服务器端服务和通用功能。通过解压源码,我们可以看到每个模块的源文件组织方式,了解其模块划分...
通过本教程的学习,读者将能够理解并掌握Hadoop与Hbase的基本操作流程。 #### 二、运行环境要求 ##### 2.1 支持的平台 虽然文档中没有明确指出支持的具体操作系统平台,但考虑到Hadoop与Hbase主要是在Linux环境下...
HBase 是一个适合于非结构化数据存储的数据库,它的目标是提供一个易于构建在 Hadoop 之上的数据表,具有实时读写、随机访问大数据的功能。 #### 二、HBase的核心概念 1. **Region** - Region 是 HBase 中最小的...
4. **HBase Thrift**: 提供了一个Thrift接口,使得非Java语言也能访问HBase。通过Thrift,你可以用Python、C++、Ruby等语言与HBase通信。研究源码有助于掌握服务端和客户端之间的通信协议。 5. **HBase Client**: ...
8. HBase-client 8.1 log4j HBase客户端的日志管理使用log4j框架,用户可以调整日志级别以适应不同需求。 8.2 configuration 配置是HBase的重要部分,包括设置连接参数、优化性能等,需要根据实际环境进行调整。 ...
9. **读写流程**:HBase的读写操作涉及Client、Zookeeper和RegionServer。读操作通过Zookeeper找到数据所在的RegionServer,然后直接从RegionServer获取数据;写操作先写入内存,然后定期刷入HDFS,实现高并发和低...
访问 HBase 的官方网站或通过 Apache Maven 下载最新的 HBase 源码包或二进制包。解压后,将其放置在所有节点的相同路径下。 3. **配置 HBase** 打开 `conf/hbase-site.xml` 文件,配置以下关键参数: - `hbase....
- **客户端**:提供访问Hbase的API,缓存区域位置信息以优化访问效率。 - **HMaster**:负责表的元数据管理、区域分配、负载均衡和失效恢复。 - **ZooKeeper**:协调集群,存储HMaster选举、ROOT表和.META.表的位置...
2. **Java API (JDBC & HBase Client)**: - Java API是HBase的基础接口,包括HBaseAdmin、HTable、HConnection等类,用于管理表、执行读写操作等。 - JDBC(Java Database Connectivity)为HBase提供了一个标准...