HBase笔记

HBase

  • HBase全称: Hadoop DataBase
  • HBase的思想来源于google的BigTable论文, 适合存放千万级别以上的数据
  • Hbase完全依赖于HDFS, 用于存储数据
  • Hbase基于列, 而不是基于行
    • SELECT * FROM user WHERE id = 888;
    • SELECT uname from user WHERE id = 888;
  • 适合存放半结构化或者非结构化的数据
    • 结构化:
      • 我们定义了一个类(结构体), 由类创建的对象都保持着同意的结构
    • 非结构化的数据
      • 没有强制要求对象与对象之间的属性相同
      • 对象可以根据自己的需求定义自己的属性半结构化的数据
    • 半结构化的数据
      • 介于结构和非结构之间的数据存储方式
  • HBase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统, 使用Hbase技术可以在廉价PC Server 上搭建起大规模结构化存储集群。
    • 高可靠性: 防止单点故障(Zookeeper, failover机制)
    • 高性能: MapReduce计算
    • 面向列: 每个对象可以有自己的列。维护的时候直接找某一行数据的某一列
    • 可伸缩性: 基于HDFS, 所有可以在保证数据安全的前提下完成存储的扩容
    • 目标: 在廉价的PC上搭建出大规模集群
  • 它其实就是个数据库(安装, SQL, JDBC, 性能调优, 底层原理)

HBase的数据结构

  • 针对于以前的关系型数据库, 只需要二维就可以获取指定的信息

    • 行ID
    • 列名称
  • 对于HBase需要四个维度才能定义一个数据

    • RowKey
      • 类似关系型数据库的ID
      • 用来唯一地表明对应列族的数据
      • 列族一般占用64K的数据长度, 但是可以动态分配
      • RowKey会默认按照字典序进行排序(待优化)
    • Timestamp
      • 时间戳, 或者数据的版本
      • 不同的列族可以有不同的时间版本
      • 默认version使用当前系统时间的毫秒数
      • 也可以自定义version, 但是需要考虑版本的设置策略防止出现重复的版本
      • HBase的数据存放在HDFS上
      • HDFS不支持数据的2修改, so对于修改操作即使新增操作
      • 不同的数据上有其对应的时间戳, 数据以时间戳为标准降序排列
      • 新插入的数据会优先被查询到, 根据用户设置的版本数据, 保留有效的时间戳
      • 数据的清除方式:
        • 超过版本树
        • 超过存储的时间
    • Column Family
      • 可以吧它作为有相同意义的列集合体
      • 通过列族才能找到对应的列
      • 一般项目中很少涉及超过3个列族
      • 在创建表的时候必须先给出列族
    • Qualifier
      • 是属于列族中的一个属性
      • 也可以被当做列族中的一个子列
      • 查询的时候, 通过rowkey找到列族, 通过列族再查找子列
        Cell
    • 通过以上四个维度最终定位的数据
    • 单元格由四个维度共同决定
    • 所有数据存储在Base上都是无数据类型的, 统一为字节数组

    HBase的系统架构

    • Client
      • 访问HBase的入口, 有多种连接方式
        • shell
        • java
        • mapreduce
      • 向HBase的服务器发送命令
        • DDL(Data Definition Language) - 数据模式定义语言
        • DML(Data Manipulation Language) - 数据操纵语言
        • DQL(Data Query Language) - 数据查询标准语法
      • 在客户端记录服务器的缓存信息, 留待下一次的使用
    • Zookeeper
      • 监控集群中的HMaster的运行情况, 保证集群在任何时候只有一个主Master
      • 当我们创建表的时候, 表的结构信息会存放在Zookeeper中, 作用是:
        • 防止放在HMaster上后遇到节点故障, 丢失数据
        • 让主从master共享数据
        • 更快的访问共享数据
      • HMaster管理HRegionServer, Zookeeper监听HRegionServer上线或者下线
      • Zookeeper保存了Region的地址
    • HMaster
      • 接受客户端的请求(DDL)
      • 监控RegionServer, 了解RegionServer的当前节点状态
      • 接受DDL请求之后, 会选择一个空闲(内存, 空间)的节点执行表的创建
      • 当发现HRegionServer掉线后, 会将其上的region切换到其他的HRegionServer
    • HRegionServer
      • 负责管理当前节点的Region
      • 一个HRegionServer有可能存在多个Region
      • 监控Region的大小, 达到阈值(10G), 将Region进行相对等分
        • 切分数据时, 以保证数据完整性为前提
      • 新分的Region交给另外的HRegionServer维护
      • 负责维护与客户端的IO请求
    • HLog(WAL日志)
      • WAL(Write Ahead Log) 提前写入日志
      • HLog隶属于HRegionServer
      • HRegionServer中的所有HRegion共享这个HLog
      • 当达到阈值的时候, 会优先写出日志, 然后将内存中的数据写出到Storefile
      • 写出之后再Hlog中记录一个检查点, 新增加到内存的时候都在该日志之后
      • HLog最终也会被写出到DFS上
    • HRegion
      • 初始情况下, 一个表对应一个Region, 随着数据增多, region有可能被切分
        • Region的预分区: 在建表时就提前创建N个Region
        • 这些Region会被分配至不同的HRegionServer
        • 即使表的数据2没有达到10G的阈值也会有多个HRegionServer提供服务
      • 一个表对应多个Region, 但是一个Region至对应一个表
      • 数据存放到表的时候会按照rowkey的字典序排列
      • so切分Region的时候, 新的Region也是有序的
    • Store
      • 一个Region由多个Store组成
      • 一个Store对应一个列族
      • Store由memstore和StoreFile组成
        • memstore
        • StoreFile: N
      • 当数据存放到数据库的时候, 数据应该存放到
        • 内存: 快,掉电易失
        • 硬盘: 持久化, 慢
        • 做任何操作之前, 先存放日志
        • 将数据写入到内存中, 然后找准时间将数据持久化到硬盘
        • 阈值 (内存的占比) (日志的条数)
    • MemStore
      • 基于内存的数据存储
      • 当新增数据的时候会先写入到日志, 然后写入到内存
      • 这样会提高数据插入速度
    • StoreFile
      • 将MemStore中的数据写出到DFS
      • 随着事件的推移, StoreFile的数量越来越多
      • 当一个数据被修改的时候, 并不会直接操作原来的StoreFile, 只是对这个记录做一个标识
      • 当StoreFile达到一定数量的时候, 会进行合并
      • 客户端进行数据检查时, 有限查找MemStore, 然后才去StoreFile

    HBase数据存储和读取的流程
    DDL语句

    • 客户端发送请求到HMaster
    • HMaster
      • 检查创建表的权限等信息是否足够
      • 寻找合适的HRegionServer
    • 将创建Region的任务下发给HRegionServer
    • 当表创建好之后, 在Zookeeper中保存两个信息
      • 表的数据结构
      • 存放Region与HRegionServer的对应关系

    DQL

    • 首先客户端发送请求查询数据
    • 查询数据对应的表 student rowkey=888
    • 查询对应的Region信息, 然后查找888对应的region
    • 查找Region对应的HRegionServer
      • 在HBase为了快速的定位到Region与HRegionServer
      • 于是专门定义了两张表, 他们两个有相同的表结构
        • .meta. 存放的都是table与region与regionserver的对应关系
          • meta随着表数量增多, region切分增多会导致
          • 切分: 去向不知
          • 不切: regionserver压力过大
            rowkey Info: regioninfo Info: server
            student,10,163067 s:10 e:19 family list{info, score} regionserver111
            student,20,163066 s:20 e:29 family list{info, score} regionserver222
            student,30,163064 s:30 e:39 family list{info, score} regionserver888
        • -root-
          • 只记录.meta.的位置
          • root的数据完全可控, 所以root路径是固定的
            rowkey Info: regioninfo Info: server
            .meta.,student,10,163067 regionserver111
            .meta.,super,10,163067 regionserver222
            .meta.,system,10,163067 regionserver888
      • 和Region所在的RegionServer建立连接
      • 因为Region中的数据都是有序的, 所以二分查找时间复杂度为O(logN)
      • 为了效率尽量将相近属性的列放在一个列族中

    DML-插入数据

    • 存储的数据最终以HFILE的形式存放在HDFS上
    • HFile的数据格式
      • 典型的一个三级的索引结构
      • trailer
        • dataindex
          • 357
          • 414
          • 505
            • 4:27
            • 4:55
            • byte[27]-->key(478)
            • byte[55]--<value(521)
          • 614
          • 717
          • ......
        • metablock
        • fileInfo
      • 如果插入数据的时候可以直接生成日志和对应的数据文件
      • 我们可以直接将日志写入到HLog, 文件拷贝到指定的位置
      • 免除了中间生成, 合并的过程, 效率会提高
原文地址:https://www.cnblogs.com/ronnieyuan/p/11553313.html