大数据技术:第四部分:分布式存储系统HBase


1. 分布式存储系统HBase

1.1 HBase总体概述

1.1.1 简介

HBase:一个分布式、多版本、面向列的开源数据库,能支持上亿行、百万列的大规模数据集的管理。

1.1.2 关系型数据库

关系型数据库:建立在关系模型基础之上的数据库,由多张能互相连接的二维行列表构成。

关系数据库的优点:

  • 保持数据的一致性;
  • 由于以标准为前提,数据更新的开销小;
  • 可以进行join等复杂查询;
  • 存在很多实际成果和专业技术信息。

关系数据库的缺点:

  • 大量数据的写入处理;
  • 为有数据更新的表做索引或表结构变更;字段不固定时的应用;
  • 处理数据非常稀疏的表(浪费空间);
  • 为维护一致性付出巨大的性能代价。

1.1.3 不同形态数据的流行变化情况

1.1.4 HBase与关系数据库比较

1.1.5 非关系型数据库

非关系型数据库,又被称为NoSQL(Not Only SQL),意为不仅仅是SQL(Structured Query Language,结构化查询语言)

非关系数据库分类:

  • Column-Oriented
  • Key-Value
  • Document-Oriented
  • Graph database
  • Time Series database

1.1.5.1 Column Oriented

1.1.5.2 Key-Value Stores

1.1.5.3 Document Stores

1.1.5.4 Graph Database

HBase生态

1.2 HBase数据模型


总结:

  • HBase是一个稀疏、多维度、排序的映射表。
    • 索引;
      • 行键;
      • 列族;
      • 列;
      • 限定符;
      • 时间戳。
    • 每个值是一个未经解释的字符串;
    • 竖直方向有一个唯一的、可排序的行键;
    • 水平方向由一个或者多个列族组成;
      • 列族支持动态扩展,可以很轻松地添加一个列族或列;
      • 无需预先定义列的数量以及类型,所有列均以字符串形式存储,用户需要自行进行数据类型转换。
    • HBase中执行更新操作时,并不会删除数据旧的版本,而是生成一个新的版本,旧有的版本仍然保留;
    • 列式存储。

1.3 HBase体系架构

主从架构

1.3.1 Client

  • 提供访问HBase接口;
  • 缓存中维护已经访问过的Region位置信息,加快数组访问过程。

1.3.2 Zookeeper

ZooKeeper是一个开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

HBase使用zookeeper作为其协同服务组件。
主要负责:

  • HBase regionserver 向zookeeper注册,提供HBase regionserver状态信息(是否在线);
  • HMaster选举;
  • 保存root region地址;
  • master和region之间的心跳信息传递。

1.3.3 HMaster

主要负责Table表和HRegion的管理工作:

  • 管理用户对Table表的增、删、改操作;
  • 管理HRegion服务器的负载均衡,调整HRegion分布;
  • 在HRegion分裂后,负责新HRegion的分配;
  • 在HRegion服务器停机后,负责失效HRegion服务器上的HRegion迁移。

1.3.4 HRegion Server

HBase中的工作节点进程。

HRegion:HBase中数据的一个上层抽象概念,所有被写入HBase的数据都会经过HRegion的封装,并管理这些数据,由RegionServer管理。

1.3.5 表和Region

  • Region是以行键排序的连续存储空间,是HBase中扩展和负载均衡的基本单元;
  • 在建表时,一张表只有一个Region,随着数据的不断增多,Region会开始进行拆分,其拆分是按照行键值进行拆分的,以行键的中间值为分隔点对数据进行切分;
  • Region拆分操作非常快,因为拆分之后的Region读取的仍然是原存储文件,直到“合并”过程把存储文件异步地写到独立的文件之后,才会读取新文件。

Region存储:

  • 每个Region的最佳大小取决于单台服务器的有效处理能力;
  • 每个Region最佳大小一般几个GB;
  • 每个Region服务器存储大约10-1000个Region;
  • 同一个Region不会被拆开存到多个Region服务器上。

1.3.6 Store

  • 每一个Region有一个或多个Store组成
    • Region:Store=1:1 or 1:n
  • 每一个ColumnFamily对应一个Store
    • Store:ColumnFamily=1:1
  • 每一个Store由一个MemStore和多个StoreFile组成
    • Store:memStore:SoreFile=1:1:n

1.3.6 MemStore

  • HBase将最近接收到的数据缓存在内存中(in Memstore),在持久化到HDFS之前完成排序,然后再快速的顺序写入HDFS;
  • 在持久化写入之前,对于某些CF的一些数据,Memstore缓存了数个对该Cell的更新,在写入HFile的时候,仅需要保存一个最新的版本就好了,其他的都可以直接抛弃;
  • 作为一个内存级缓存,缓存最近增加数据。一种显而易见的场合是,新插入数据总是比老数据频繁使用。

1.3.7 Hlog

  • 每一个RegionServer对应一个或多个Hlog;
    • RegionServer:Hlog=1:1 or 1:n
  • Hlog是Hbase实现WAL(Write ahead log)的一个实例。

Q:什么是WAL(Write-Ahead Log)预写日志?
A:RegionServer会将更新操作(如 Put,Delete)先记录到 WAL中,然后将其写入到Store的MemStore(MemStore是内存中的数据缓冲区),最终MemStore会将数据写入到持久化的HFile中(MemStore 到达配置的内存使用阈值)。

Q:如果没有WAL预写日志?
A:当RegionServer宕掉的时候:
- MemStore还没有写入到HFile
- StoreFile还没有保存
数据就会丢失。

1.3.8 meta和root

元数据表:.META.表,存储了Region和RegionServer的映射关系。

  • 当HBase表很大时, .META.表也会被分裂成多个Region,用于保存所有用户数据的Region位置信息
    根数据表:-ROOT-表,记录所有元数据的具体位置。
  • -ROOT-表只有唯一一个Region,名字是在程序中被写死的
  • Zookeeper文件记录了-ROOT-表的位置

层次 名称 作用
第一层 Zookeeper 记录-ROOT-表位置信息
第二层 -ROOT-表 记录.META.表的Region位置信息
第三层 .META.表 记录用户数据表的Region位置信息

1.4 HBase运行机制

1.4.1 数据写流程

  1. Client获取数据写入的Region所在的RegionServer;
  2. 请求写Hlog(WAL);
  3. 请求写Memstroe;
  4. 到达一定的内存阀值的时候,Memstore中的数据会被刷到HFile中。

缓存刷新:

  • 全局内存控制;
  • MemStore达到上限;
  • RegionSever的Hlog数量达到上限;
  • 手工触发;
  • 关闭RegionSever触发;
  • Region使用Hlog恢复完数据后触发。

1.4.2 数据读流程

  1. Client:Zookeeper->-ROOT-->.META.(Region)->RegionServer->region
  2. 找数据
    1. MemStore
    2. StoreFile->HFile

1.4.3 StoreFile合并

Q:为什么要合并?
A:每次刷写都生成一个新的StoreFile,数量太多,影响查找速度。

Store是Region服务器的核心。多个StoreFile合并成一个单个StoreFile过大时,又触发分裂操作,1个父Region被分裂成两个子Region。

1.4.5 错误恢复机制

HBase系统为每个RegionServer配置了一个HLog文件——预写式日志(Write Ahead Log)

用户更新数据必须先写入日志后,才能写入MemStore缓存。

1.5 HBase应用优化

1.5.1 HBase应用案例

系统由车载硬件设备、云服务端构成。

  1. 定时采集车辆的各种状态信息(车载硬件设备-->服务端);
  2. 将数据进行解析,校验(服务端-->国家汽车监测平台和地方汽车监测平台);
  3. 解析后的明文数据和原始报文数据(服务端-->系统(数据库))。
  • 车辆的数据和其他数据需要通过web页面或rest API接口进行查询访问
  • 半年内的数据查询响应时间在毫秒级别内

参数

  • 10万台车辆同时在线;
  • 车辆正常情况下平均每分钟发送两个数据报文到监控平台;
  • 若车辆处于报警状态,则平均一秒钟发送一次数据报文;
  • 数据情况:
    • 平均一台车每天会产生20MB的数据;
    • 车辆数据报文平均大小为1KB(车载硬件设备-->服务端);
    • 解析后的数据包大小为7KB(服务端-->国家汽车监测平台和地方汽车监测平台);
    • 系统每天会产生2TB的数据,2.9亿行的数据(服务端-->系统(数据库))。
  • 系统并发量:
    • 3300的持续并发量;
    • 10万个长连接;
    • 每秒3.3MB的原始数据需要被解析;(车载硬件设备-->服务端);
    • 每秒23.1MB的解析数据需要被存储。(服务端-->系统(数据库))。

技术选型

  • 必须能够支持海量数据的不间断写入,而且能够存储PB级别的数据,具有高扩展性、高可靠性等;
  • 能够支持简单的关键字查询,响应时间在秒级别内;
  • 能够兼容大数据生态产品(如Spark、Hive、Hadoop等),同时支持离线和准实时OLAP;
  • 优先选择有雄厚实力的商业公司支持的云平台,最大限度减少运维成本。

系统架构

1.5.2 HBase Row Key设计

1.5.3 HBase优化

  • InMemory
    • 创建表的时候,可以通过HColumnDescriptor.setInMemory(true)将表放到Region服务器的缓存中,保证在读取的时候被cache命中。
  • Max Version
    • 创建表的时候,可以通过HColumnDescriptor.setMaxVersions(int maxVersions)设置表中数据的最大版本数,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)。
  • Time To Live
    • 创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置表中数据的存储生命期,过期数据将自动被删除,例如如果只需要存储最近两天的数据,那么可以设置setTimeToLive(2 * 24 * 60 * 60)。

1.6 Hbase 配置编程

1.6.1 HBase常用配置

  • hbase.rootdir
  • hbase.cluster.distributed
  • hbase.zookeeper.quorum
  • hbase.regionserver.hlog.blocksize

1.6.2 HBase API

1.6.3 HBase shell命令

使用Apache HBase Shell

1.6.4 Java API

HBase里的Java API