HBase中的Client如何路由到正确的RegionServer
在 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,则不在本文的讨论范围之内。
相关推荐
通过Java API或HBase Shell创建表,插入数据,执行查询、扫描等操作。 4.3 性能优化 根据业务需求调整HBase配置,如Region大小、Compaction策略、BlockCache设置等,提升系统性能。 五、学习资源 参考链接:[博客...
在实际查询过程中,HBase会通过poll方法从队列头部取出storefile,读取并返回第一条记录。然后,它会比较队列中剩余storefile的第一条记录和当前storefile的第二条记录。如果前者更大,就返回当前storefile的第二条...
- **HBase**: 基于列族的存储模型,列族内的数据物理上连续存储,便于查询特定列族。 - **数据类型**: - **传统数据库**: 支持丰富的数据类型和复杂的数据结构。 - **HBase**: 主要支持简单的字符串数据类型。 - ...
- **多版本控制**:支持数据的历史版本追踪,每个单元格的数据可以有多条记录,每条记录都有一个时间戳。 - **灵活的数据模型**:支持动态列扩展,无需预先定义表结构,可以随时添加新的列族和列标识。 **2、数据...
在Java开发中,HBase是一种基于Google Bigtable设计的开源分布式数据库,主要用于处理大规模数据存储。HBase提供了高效的随机读写能力,是Apache Hadoop生态系统的一部分。为了在Java环境中与HBase进行交互,我们...
4. **查询与分析**:同样,通过Spring Boot应用,我们可以对存储在HBase中的数据进行查询和分析。 综上所述,"springboot_hbase_kafka.rar"项目展示了如何利用Spring Boot构建一个高效的大数据处理系统,结合HBase...
- 时间戳:每条数据都有时间戳,支持多版本,方便回溯和审计。 - 空间效率:只存储非空数据,节省存储空间。 - 实时读写:HBase提供低延迟的实时读写能力,适合大数据实时分析场景。 - 索引支持:通过RowKey进行...
- **单条数据扫描**:介绍如何通过扫描器获取单条记录。虽然这种方式不常用,但在某些特定场景下可能会用到。 - **全表扫描**:讲解如何使用扫描器对整个表进行扫描,并从中获取所需数据。需要注意的是,由于HBase的...
- 支持的导入方式多样,包括单条数据、批量数据、多线程并行导入以及定时全量和增量导入。 2. **环境要求** - 软件需求:至少需要JDK 1.7,兼容Elasticsearch的1.x, 2.x, 5.x, 6.x, 7.x及以上版本,同时支持...
4. 删除数据:`delete`命令用于删除单条数据,`deleteall`删除指定列族的所有数据。 5. 表管理:包括`disable`、`enable`、`drop`等操作,用于禁用、启用或删除表。 【HBase Java API应用】 对于开发人员,HBase...
- NoSQL数据库:HBase属于NoSQL数据库的一种,它不使用传统的SQL语言进行数据操作。 2. **MapReduce与HBase的关系** - MapReduce与HBase不是强关联关系:HBase可以独立于MapReduce运行。 - MapReduce可以直接...
- **时间戳**:每条记录都有一个时间戳,这使得HBase能够存储和检索历史版本的数据。 ### HBase操作 HBase支持以下几种基本操作: - **插入数据**:使用put命令向HBase表中插入数据。 - **查询数据**:使用get...
- 行键(Row Key):用于唯一标识一条记录。 - 列族(Column Family):数据被组织成列族,每个列族可以包含多个列。 - 列限定符(Column Qualifier):用于进一步区分同一列族下的不同列。 - 时间戳(Timestamp):...
HDFS 是 Hadoop 的分布式文件系统,而 HBase 是基于 Hadoop 的一个分布式、列族式的数据库,适用于实时查询大规模数据集。 在大数据处理中,数据的导入导出是常见的操作。HDFS 用于存储大量数据,而 HBase 提供了...
3. **Timestamp**:每条数据都有一个版本号,即时间戳,这有助于维护数据的历史版本。 4. **Region**:随着数据的增长,单个表会被分割成多个区域(Region)。每个Region包含一个特定范围内的Row Key,由Region ...
HBase采用了独特的数据模型,包括行键(RowKey)、时间戳(Timestamp)、列簇(ColumnFamily)等元素,其中行键是表的主键,用于唯一标识一条记录,并决定了数据的物理存储顺序;时间戳则用于版本控制,支持数据的...
在大数据处理领域,Apache HBase是一个分布式的、版本化的NoSQL数据库,它构建于Hadoop之上,特别适合处理海量结构化数据。这篇博客“Hbase调用Java API实现批量导入操作”聚焦于如何利用Java编程语言高效地向HBase...
- Row Key 用于唯一标识一条记录,它是 HBase 中最重要的概念之一。 - 访问数据的方式主要有三种:通过单个 Row Key 查询;通过 Row Key 的范围查询;或者进行全表扫描。 - Row Key 在内部以字节数组的形式存储,...
在HBase中,数据以表的形式组织,表中的数据按行存储,每行数据都有一个唯一的行键(RowKey)。 HBase的核心组件包括HMaster和HRegionServer。 HMaster是HBase的主服务器,负责协调集群中的所有活动。它主要负责...