HBase是谷歌BigTble的开源实现。谷歌的三篇论文拉开了大数据江湖的序幕,铸就了现在以Hadoop为主的大数据技术生态圈。而HBase是开源的大数据数据库,和传统的行式数据库不同的是,HBase是列式数据库。列式数据的特点是开源横向扩展,将一张表的数据存储在hadoop集群的不同datanode中,一张表的存储量可以达到T级别。这是行式关系型数据库无法实现的。本文主要讲解HBase的基本概念,只有概念清楚了才能更好的在我们的系统中使用HBase。

核心组件介绍

Table:可理解为传统数据库中的一个表,但因为SchemaLess的设计,它较之传统数据库的表而言,在设计上更加灵活。

Region:将表横向切割为一个个子表,子表在HBase中被称之为Region。

RegionServer:数据服务进程,Region必须部署在某一个RegionServer上才可以提供读写服务。

HFile:HBase数据库在底层分布式文件系统中的文件组织形式。

Column Family:一些列的集合。不同的Column Family数据被存储在不同的路径中。

MemStore:用来在内存中缓存一定大小的数据,达到设定的阈值后批量写入到底层文件系统中。数据是有序的。

下图清晰的展示了Table,Region,RegionServer,HFile,MemStore,Column Family在HBase的逻辑关系。

下图显示了HBase集群中的关键进程

Zookeeper:HBase集群的调度器,可以用于将HBase RegionServer信息注册到zookeeper中,查询HBase RegionServer状态信息,HMaster启动时会将HBase系统表-ROOT-加载到zookeeper集群中,通过zookeeper集群可以获取当前系统表.META.的存储所对应的RegionServer信息

Master,通过jps命令显示的进程名称是HMaster,在负责表管理操作,Region到各个RegionServer的分配以及RegionServer Failover的处理等。

RegionServer进程提供数据读写服务。

NameNode,Hadoop进程,处理来自Master的请求,H管理DFS文件系统的命名空间NameSpace。

DataNode,Hadoop数据节点进程,HBase的所有数据都存在Hadoop的DataNode中。

KeyValue数据存储结构

HBase所存储的数据是以KeyValue形式存放的,KeyValue有特定的数据结构,如下图所示,一个KeyValue可以理解成HBase表中的一个列,当一行存在多个列时,将包含多个KeyValue,同一行的KeyValue有可能存储在不同的文件中,但在读取时,会按需合并在一起返回给客户端。

用户写数据时,需要定义用户数据的RowKey,指定每一列所存放的Column Family,并且为其定义相应的Qualifier(列名),Value部分存放用户数据。Hbase中每一行可拥有不同的KeyValues,这就是HBase Schema-less的特点。

HBase中支持数据的多版本,通过带有不同时间戳的多个KeyValue版本来实现的,如下图所示。

HBase所保存的版本数据是可配置的,默认存放3个版本。在普通的读取流程中,旧版本的数据时不可见的,但通过制定版本数或者版本号的读取,可以获取旧版本数据。下图是普通读取刘恒与多版本读取流程的对比。

灵活的列定义

用户数据存入到HBase表中时,需要进行Qualifier(KeyValue/列)设计。一个最简单的设计是保持HBase的列与用户数据的列一致,如下图1的设计。这种设计,基本上与关系型数据库的设计是一致的,但这种设计会带来较大的数据冗余(KeyValue结构开销)。但HBase基于KeyValue的接口,决定了这种设计可以是非常灵活的,例如,我们也可以考虑为HBase的每一行只设置两个列,其中,Name为一个列,其他内容合并到一个列中,如下图2所示。

尽管我们在使用HBase表存放数据的时候,需要预先做好列的设计。但这个设计仅仅由应用层感知,HBase并没有存放任何的Schema信息来描述这个设计。也就是说,应用层需要知道为每一个表/每一行设计了什么样的列(KeyValue),然后在地区的时候做相应的解析。既然HBase中并没有Schema信息,name,每一行中的列,也可以是任意添加的。如下图所示,绿色背景的KeyValue为后续增加的。

Column Family

假设为表设置了两个列族,而且,定义了每一个列簇中要存放的列,如下图所示:
{Name} -> Column Family - A, {City,Phone,Gender} -> Column Familly-B。不同列簇的数据会被存储在不同的路径中。即,设置多个列簇时一行数据可能存在于两个路径中。整行读取的时候,需要将两个路径中的数据合并在一起蔡可以获取完整的一行记录。但如果仅仅读取Name一列的话,只需要读取Column Family-A即可。

最新文章

  1. OpenGL Insights 阅读有感 - Tile Based架构下的性能调校 翻译
  2. Android安全之Https中间人攻击漏洞
  3. 一款符合当前主流审美的Swing外观(Look and Feel)_测试版发布
  4. ios 学习线路(图片)(摘录)
  5. hdoj 5387(Clock)
  6. [Hive - Tutorial] Querying and Inserting Data 查询和插入数据
  7. 开源布局控件 WeifenLuo.WinFormsUI.Docking.dll使用
  8. 问题与对策:CSS的margin塌陷(collapse)
  9. php 二维数组以树形输出(转)
  10. js、java传值编码
  11. css画图形
  12. [置顶] EasyMock构建单元测试
  13. UpdateModel方法
  14. OA办公系统,一个沉淀企业文化的容器
  15. 设计模式——状态模式(C++实现)
  16. Python常用内置模块之xml模块
  17. java15
  18. 使用 alt_disk_copy 克隆 rootvg
  19. Linux USB Host-Controller的初始化代码框架分析【转】
  20. JDK1.8快速入门

热门文章

  1. 带拦截器配置的 struts.xml文件
  2. 解决类似umount target is busy挂载盘卸载不掉问题
  3. centos7搭建gitlab服务器、汉化
  4. prometheus rules
  5. 金融量化分析【day113】:聚宽自带策略
  6. Hadoop记录- Yarn Job MAX
  7. ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE(记忆化搜索)
  8. JavaScript null和undefined的区别
  9. 使用 functional interface 和 lambda 表达式来优化代码
  10. AngularJS DI(依赖注入)实现推测