`
18901888895
  • 浏览: 6702 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HBase查找一条数据的过程

阅读更多

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.可以被看作是两张普通的表,那么它们和其他表一样就应该有自己的表结构。没错,它们有自己的表结构,并且这两张表的表结构是相同的,在分析源码之后我将这个表结构大致的画了出来:

578x196

我们来仔细分析一下这个结构,每条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.

574x372

现在假设我们要从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-

571x169

399x228

  

  

这么一来Client端就需要先去访问-ROOT-表。所以需要知道管理-ROOT-表的RegionServer的地址。这个地址被存在ZooKeeper中。默认的路径是:

/hbase/root-region-server

等等,如果-ROOT-表太大了,要被分成多个Region怎么办?嘿嘿,HBase认为-ROOT-表不会大到那个程度,因此-ROOT-只会有一个Region,这个Region的信息也是被存在HBase内部的。

现在让我们从头来过,我们要查询Table2中RowKey是RK10000的数据。整个路由过程的主要代码在   

 

[java] view plaincopy
 
  1. org.apache.hadoop.hbase.client.HConnectionManager.TableServers中:  
  2. private HRegionLocation locateRegion(final byte [] tableName,  
  3.      
  4. final byte [] row, boolean useCache)  
  5. throws IOException{  
  6.      
  7. if (tableName == null || tableName.length == 0) {  
  8.      
  9. throw new IllegalArgumentException(  
  10.      
  11. “table name cannot be null or zero length”);  
  12.      
  13. }  
  14.      
  15. if (Bytes.equals(tableName, ROOT_TABLE_NAME)) {  
  16.      
  17. synchronized (rootRegionLock) {  
  18.      
  19. // This block guards against two threads trying to find the root  
  20.      
  21. // region at the same time. One will go do the find while the  
  22.      
  23. // second waits. The second thread will not do find.  
  24.      
  25. if (!useCache || rootRegionLocation == null) {  
  26.      
  27. this.rootRegionLocation = locateRootRegion();  
  28.      
  29. }  
  30.      
  31. return this.rootRegionLocation;  
  32.      
  33. }  
  34.      
  35. else if (Bytes.equals(tableName, META_TABLE_NAME)) {  
  36.      
  37. return locateRegionInMeta(ROOT_TABLE_NAME, tableName, row, useCache,  
  38. metaRegionLock);  
  39.      
  40. else {  
  41.      
  42. // Region not in the cache – have to go to the meta. RS  
  43.      
  44. return locateRegionInMeta(META_TABLE_NAME, tableName, row, useCache, userRegionLock);  
  45.      
  46. }  
  47.      
  48. }  


  

 

这是一个递归调用的过程:

获取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,则不在本文的讨论范围之内。

引用:http://www.shangxueba.com/jingyan/tc454-1136.html

分享到:
评论

相关推荐

    HBase查询的深入研究

    在实际查询过程中,HBase会通过poll方法从队列头部取出storefile,读取并返回第一条记录。然后,它会比较队列中剩余storefile的第一条记录和当前storefile的第二条记录。如果前者更大,就返回当前storefile的第二条...

    Hbase技术介绍

    HBase采用了独特的数据模型,包括行键(RowKey)、时间戳(Timestamp)、列簇(ColumnFamily)等元素,其中行键是表的主键,用于唯一标识一条记录,并决定了数据的物理存储顺序;时间戳则用于版本控制,支持数据的...

    HBASE基础应用的介绍

    - 行键(Row Key):用于唯一标识一条记录。 - 列族(Column Family):数据被组织成列族,每个列族可以包含多个列。 - 列限定符(Column Qualifier):用于进一步区分同一列族下的不同列。 - 时间戳(Timestamp):...

    hbase-2.2.0-bin.tar.gz

    3. 时间戳:每条记录都有一个时间戳,这使得HBase可以保存多版本数据。用户可以设置保留多少个版本,以便追溯历史数据。 4. 分布式架构:HBase利用Hadoop的HDFS作为底层存储,通过Region Server进行数据分区,实现...

    hbase-chd发行版

    1. 行键(Row Key):HBase使用行键来唯一标识每条记录,支持高效的索引和查找操作。 2. 列族(Column Family):数据按列族组织,每个列族包含一系列列,列族内的列可以动态添加。 3. 时间戳:每个值都有时间戳,...

    java代码使用thrift2操作hbase示例

    使用`Put`对象表示一条插入记录,指定行键和列族(Column Family),然后将`Put`对象添加到`Table`对象的批处理操作中。调用`table.put(Put[])`提交所有更改。 5. **单条查找**:使用`Get`对象来指定行键和列族,...

    hbase二级索引

    HBase的表数据是按照RowKey排序存储的,RowKey是唯一标识一条记录的关键字,因此对RowKey的查询是非常高效的。但当我们的查询条件不是基于RowKey时,查询性能就会显著下降,这就需要二级索引来辅助。 二级索引的...

    小镜子之hbase学习

    4. 时间戳:HBase为每条数据记录了时间戳,允许多版本数据存储,用户可以通过时间戳查询历史数据。 二、HBase架构 HBase的架构基于Google的Bigtable模型,主要由Master节点、RegionServer节点和ZooKeeper构成。 1...

    hbase 理论基础教程

    HBase是一个开源的非关系型分布式数据库(NoSQL),它参考了谷歌的BigTable建模,实现海量稀疏数据的存储。HBase是Apache软件基金会的Hadoop项目的一部分,运行于HDFS文件系统之上,因此可以实现容错性存储。HBase的...

    weibo_hbase_

    例如,发布一条微博,将微博内容、作者等信息写入“Status”列族。 2. 数据查询:通过Get或Scan操作进行数据检索。比如,按用户ID查找所有该用户的微博,或者按时间范围筛选特定时间段内的微博。 五、性能优化 1. ...

    hbase期末复习重点

    3. **时间戳(Timestamp)**:每条记录都有一个时间戳,用于区分同一列族下的不同版本数据。HBase默认保留多个版本,可以根据需要配置。 4. **Region**:Region是HBase中数据的物理分片,每个Region包含一个或多个...

    HBase Introduction

    HBase模型中的数据以键值对的形式存储,每一条记录都由四个基本元素构成:行键(row key)、列族(column family)、列限定符(column qualifier)和时间戳(timestamp)。行键是用于快速检索某一行的键,列族是列的集合,列...

    3.代码_大数据电信客服项目_exclaimedihy_Hadoop项目_数据可视化_

    在本项目中,Kafka可能作为数据处理管道的一部分,接收Flume发送过来的数据,然后将它们分发到后续的处理阶段,如数据分析或者存储到HBase。 数据可视化是项目的重要组成部分,前端页面的构建使得分析结果能够直观...

    Hbase.docx

    HBase作为一种高度可扩展的NoSQL数据库,通过采用LSM树、B+树等高效的数据结构,以及精心设计的读写流程,能够在大规模数据集中实现高性能的读写操作。无论是对于实时数据分析还是大数据存储场景,HBase都展现出了其...

    nosql实验二-HBase的表结构设计.docx

    - **时间戳**:HBase 自动为每条数据记录时间戳,便于版本控制和历史数据追踪。 - **分区键**:RowKey 设计至关重要,因为它决定了数据的物理分布和访问性能。RowKey 应该尽可能地反映数据的访问模式。 - **数据模型...

    云HBaseSQL及分析PhoenixSpark.pdf

    HBase设计用于存储稀疏数据集,通过行键(row key)进行快速查找,特别适用于大数据的随机读写场景。然而,原生的HBase API较为底层,不便于业务人员直接进行SQL语句的编写和使用,这就催生了对SQL层的支持,以便...

    Hadoop平台技术 模块5 分布式数据库Hbase-单元设计.docx

    4. 删除数据:`delete`命令用于删除单条数据,`deleteall`删除指定列族的所有数据。 5. 表管理:包括`disable`、`enable`、`drop`等操作,用于禁用、启用或删除表。 【HBase Java API应用】 对于开发人员,HBase...

    大数据-使用flume+kafka+HBase+spark+ElasticSearch的用户轨迹查询大数据项目.zip

    综上,这个项目展示了大数据处理的一条典型链路,从数据采集、传输、存储到分析和查询,涵盖了多个关键技术。通过整合这些工具,项目实现了对用户轨迹的高效管理和深入分析,为企业决策提供了强有力的数据支持。

    关系型和非关系型数据库的区别? 关系型数据库的优点 容易理解,因为它采用了关系模型来组织数据 可以保持数据的一致性 数据更

    当一条MySQL语句被提交时,其执行过程如下: 1. 客户端发起请求。 2. 连接器验证用户身份并赋予相应的权限。 3. 查询缓存检查是否已有相同的查询结果,如果有则直接返回,否则继续执行。 4. 分析器进行词法和语法...

    学生信息管理系统

    用户选择一条记录后,系统会调用CRecordset的Delete方法来移除选定的数据库条目。 查询功能是系统的核心,可以通过学号、姓名等条件进行模糊或精确查找。MFC的CRecordset类提供了多种查询方式,如SQL的SELECT语句,...

Global site tag (gtag.js) - Google Analytics