YongSir

专业程序员伪装者

Hbase面面观

引子

大数据处理和存储框架Hadoop,除了最重要的HDFS和MapReduce/Spark计算框架之外,还需要很多辅助组件,比如需要分布式协调系统zookeeper来做热备,维护元数据命名空间, Sqoop作数据导入导出等等。这些都是从整个系统上的工具,而作为数据持久化的存储系统的HDFS,自然也发展出了很多自己的辅助组件,其中HBase无疑是最耀眼的

是什么?

简单的,HBase是一种类数据库的存储层工具,其用于组织和管理结构化数据的存储,由于需要服务HDFS,自然它也是分布式的,并且是一种 列式的分布数据库 ,最早由Goolge的BigTable论文中提出。虽然依托于HDFS很容易让人想起另一个结构数据工具Hive,但二者的区别和设计目的是不同的,在生态中的所处位置也不一样,这一点在Hive初探文章中有所探讨,总体来说,Hive是MepReduce层的工具,而Hbase是在结构化存储层,直接连接hdfs,还有诸如:

  • Hive并不适用于实时数据查询处理,而这是HBase的强项
  • Hive部署不依托Zookeeper,而HBase需要
  • Hive的交互有SQL,而HBase不直接提供

相对于Hive的比较,更有趣的是HBase根传统数据库,比如mySQL这样的行式数据库的不同

HBase解决了那些HDFS的问题呢?HDFS本身就拥有良好的容错和扩展性,常常被扩展到上百节点,但仍然存在着作为文件系统,相较于结构化存储系统固有的天然劣势:如果我们只关心文件中的一部分数据,想对部分数据进行操作,文件系统只能通过对整个文件进行扫描来实现,所以HDFS:

  • 不支持数据查找
  • 不适合增量式数据处理
  • 不支持数据更新

如果是单纯的离线存储也就罢了,但现实往往有实时性的需求,所以才有了HBase对HDFS的补充,HBase可以支持:插入/删除/查询等单条/部分数据的操作,便于高效过滤和读写数据

也正是由于其设计目的限制,让HBase拥有了一些跟传统数据库完全不同的实现,这就是列式无模式稀疏的数据组织方式。

列式? 🤔因吹死停

先来看看一组数据,如果是在传统RDBMS中如mySQL是这样存储的:
| id | name | nickName | password | time |
| :–: | :——: | :——: | :——: |:——: |
| 001 | zhangsan | zzss | p11zzz | 20161212 |
| 002 | lisi | lsls | 333lll | 20161213 |

每一行的是一个完整数据单元,每一列对应于都是一个具体数据。但是在没有建立索引的情况下,读取整行,在遍历查找数据,会付出巨大IO;而索引和视图的建立,付出的IO和性能也不容忽视;最重要的是为满足多样的查询需求,数据库要不可避免的大量扩大膨胀,才能满足性能需求。而这些问题HBase是怎样处理的呢,如果上述数据在HBase中是怎样存储的呢?

数据模型




















RowKey Value (CF Qualifier Version)
001 name{“real”: “zhangshan”, “nick” : “zzss” }
info{“pwd” : “333lll”}
001 name{“real”: “lishi”, “nick” : “lsls” }
info{“pwd” : “333lll”}
RowKey CF:Column-Key Timestamp CellValue
001 name:real 123456789 zhangsan
001 name:nick 123456789 zzss
002 name:real 123456789 lishi
002 name:nick 123456789 lsls
001 info:pwd 123456789 p11zzz
002 info:pwd 123456789 333lll

上述是一个一种物理存储的形式,不太容易看明白,如果表述为逻辑存储形式:

从上述的物理和逻辑排布中,能看出在HBase中:
只有一中索引标识那就是RowKey

传统行数据库的问题

构架,为什么能做到实时?

  • 预写入日志:WALs

HDFS的物理目录结构

在Hbase的设置文件中,具体设置:
<name>hbase.rootdir</name>

常见操作

  • 2种方式

    • JDBC API
    • CLI
  • 读hdfs

  • 写hdfs

核心使用

  • 热点问题:客户点直接访问集群少数节点,导致节点机器超载,性能下降甚至region不可用,从而影响同RegionServer下的其他region
  • rowKey的设计
  • 窄表和宽表
  • 负载均衡

一个案例