大数据 | NoSQL--列存储
大数据 | NoSQL–列存储
亲爱的读者朋友大家晚上好,上次我们介绍了 NoSQL 的键值存储体系,这次我们来看看 NoSQL 的列族存储~
列存储
简介
- 每个存储块包含的数据只有一个列
- 例如:$Hadoop$ / Hbase
- http://hadoop.apache.org/
- $Yahoo$ , $Facebook$
- 例如: $Ingres\ VectorWise$
- 集成列存储与 $SQL$ 数据库
- http://www.ingres.com/products/vectorwise
- 在下列情况下比行和文件存储更有效
- 多个行 / 记录 / 文件同时被插入,此时更新的列块可以聚合
- 只检索访问的一行 / 记录 / 文件一些列
Hbase引入
Hbase 是一种面向列的(稀疏),基于 HDFS 的(海量),高性能(快速)分布式数据库系统:利用 $Hadoop$ $HDFS$作为其文件存储系统,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统;利用$Hadoop$ $MapReduce$来处理 HBase 中的海量数据;利用 $Zookeeper$ 作为协同服务。

$Client$ 是读写数据的客户端;$Zookeeper$ 负责保存 $root\ region$ 的位置、$Master$选举、$Region$ $Server$ 以及$Region$上下线的感应;$Region$ $Server$ 是表的具体操作的场所;$Master$ 是 $Region$ 的分配以及 $balance$;$HDFS$是存放数据的地方。
对比RDBMS
Hbase | RDBMS | |
---|---|---|
数据类型 | 只有字符串 | 丰富的数据类型 |
数据操作 | 简单的增删查改 | 各种各样的函数,表连接 |
存储模式 | 基于列存储 | 基于表格结构和行存储 |
数据保护 | 更新后旧版本仍然会保留 | 替换 |
可伸缩性 | 轻易的进行增加节点,兼容性高 | 需要中间层,牺牲功能 |
Hbase
总体结构
($refer$ https://blog.csdn.net/gdkyxy2013/article/details/77323551)

HBase架构中的客户端Client
$Client$ 有以下几点作用:
1. 整个HBase集群的访问入口;
2. 使用HBase RPC机制与HMaster和HRegionServer进行通信;
3. 使用HMaster进行通信进行管理类操作;
4. 与HRegionServer进行数据读写类操作;
5. 包含访问HBase的接口,并维护cache来加快对HBase的访问。
协调服务组件Zookeeper
$Zookeeper$ 的作用如下:
1. 保证任何时候,集群中只有一个HMaster;
2. 存储所有的HRegion的寻址入口;
3. 实时监控HRegionServer的上线和下线信息,并实时通知给HMaster;
4. 存储HBase的schema和table元数据;
5. Zookeeper Quorum存储-ROOT-表地址、HMaster地址。
主节点HMaster
$HMaster$ 的主要功能如下:
1. HMaster没有单节点问题,HBase中可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master在运行,主要负责Table和Region的管理工作。
2. 管理用户对表的增删改查操作;
3. 管理HRegionServer的负载均衡,调整Region分布(在命令行里面有一个tools,tools这个分组命令其实全部都是Master做的事情);
4. Region Split后,负责新Region的分布;
5. 在HRegionServer停机后,负责失效HRegionServer上Region迁移工作。
Region节点HRegionServer
$HRegionServer$ 的功能如下:
1. 维护HRegion,处理HRegion的IO请求,向HDFS文件系统中读写数据;
2. 负责切分运行过程中变得过大的HRegion;
3. Client访问HBase上数据的过程并不需要Master参与(寻址访问zookeeper和HRegionServer,数据读写访问HRegionServer),HMaster仅仅维护着table和Region的元数据信息,负载很低。
看了上面关于各个组件的介绍,我们现在用大白话概括一下各个组件的主要作用。数据被分配到多个 $HRegionServer$ 上进行存储和管理;$Master$ 决定数据在哪个 $HRegionServer$ 中,可以控制不同$HRegionServer$ 之间的负载均衡,因此 $Master$ 中其实存放了表到 $HRegionServer$ 的映射;$Zookeeper$ 又决定了 $Master$ 是谁,并且存储了所有关于 $Master$、$HRegionServer$、$table$的元信息,是最终的$controller$。
水平扩展
我们来看下$RegionServer$的结构,每个$RegionServer$有多个$Region$,每个$Region$又有多个$StoreFile$。

当数据量增大,读写性能会下降,我们通过水平扩展降低服务器的负载。在传统方案中,我们分库分表、迁移数据,但是这样做比较费时费力,还容易出错。在Hbase的方案中,我们直接新增机器即可,且性能平稳。
- 当$storeFile$多了后,也就是实际需要的$storeFile$没有这么多,HBase 会自动$compact$,也就是将不同的$storeFile$合并;
- 当$rows$多了后,HBase 会自动将$region$进行分割;
- HBase 会定时对$Region$ $Server$的$Region$进行$balance$;
- 一个新的$Region\ Server$下线,$Master$会重新分配其负责的 $Region$ 到其他的 $Region\ Server$;
- 一个 $Region\ Server$ 上线,当 $Master$ 进行 $balance$ 时会迁移一些 $Region$ 到新的 $Region\ Server$。
高性能随机读写
高性能随机读写依靠的是底层的数据结构,在Hbase中,不同的列被分开存储,当我们想要查询某个数据时,通过 $key\ value$ 的方式定位一条具体的数据。$key$ 由四部分组成:表的主键,列族的名字,列的名字,版本号(时间戳)。
case
数据读取流程~*$Client$读取$tableA$中第$1$行数据*

- 从$Zookkeeper$中获取$ROOT$表的$Region$服务器$R$
- 从$Region\ Server\ R$中根据表的名称索引找到$META$表所在的$Region$服务器$M1$
- $Client$根据表名和行关键字找到对应的$Region$服务器$U1$
- 使用接口从$U1$进行数据读取 / 向$U1$写入数据
表结构操作过程~新建表、删除表、增删属性

- $Client$通过$Shell$指令或$API$接口向$Master$ $Server$发出请求
- 创建表
- 默认情况在空间可用的 $RegionServer$上新增 $1$ 个$Region$
- 更新$META$表
- 所有后续的写入操作都会将数据存入此$Region$中,直到 $Region$ 尺寸达到一定程度分裂为两个$Region$,并不断重复
- 动态增加列族
- $Master\ Server$会根据用户请求,查找到可用的$Region\ Server$,并在相应的$Region\ Server$上为新的列族创建$storeFile$