Hbase

\S1. Hbase基本概念

一. 为什么要用hbase

  1. 相比于HDFS
  • HDFS适合批处理场景, 但不支持数据的随机查找
  • HDFS不支持数据的更新
  1. 相比于Hive
  • Hive适合批处理的数据分析场景
  • Hive不适合实时的数据访问
  1. Hbase的特点
    顺序写, 随机度, 可擦写, 可删除

二. Hbase概念模型特点

  1. Hbase vs Mysql
      • Hbase的列可以无限扩充
      • Hbase的列没有类型
      • Hbase的多个列构成一个列簇(column family)
    1. 主键 vs 索引
      • Hbase仅有一个主键
      • Hbase存储的每条记录根据主键进行排序
      • Hbase的值是多版本的, 每个版本的值称为Cell
      • Cell的数目(每个值的版本数)也没有限制
  2. Hbase模型特点
    1. 可扩展性强
      • 支持数十亿行, 数百万列
      • 支持数十万个版本
    2. 可以存储很稀疏的数据
      • 即使有90%的列是空值, Hbase也不会因此浪费存储空间
    3. 支持随机读
      • 根据主键会哦去一行数据
    4. 支持scan
      • 快速获取某些行区间内的数据
      • 快速获取某几列的数据
  3. 行健举例
    历史账单查询: userid+time+id
    网络爬虫: URL+爬去实践+优先级

三. Hbase物理模型

  1. 行式存储 vs 列式存储
    1. 行式数据库
      • 没建索引的行式数据库, 查询会产生大量IO
      • 建立索引和物理视图会话费大量时间和资源
      • 若要提升查询性能, 数据库必须被大量膨胀
    2. 列式数据库
      • 数据按列单独存放
      • 数据即是索引
      • 若只查询指定的几列, 可以大量降低IO
      • 每一列可由一个thread单独处理-查询的并发
      • 因为相同列的数据在一起存储, 数据类型一致, 特征相似, 方便高效压缩存储
  2. Hbase的列簇式存储
    • Hbase没有选择纯粹的列式存储, 因为Hbase支持上百万个列, 每个列单独形成文件的话会造成每个表的metadata信息多大, 而且会导致产生数百万个小文件, 降低查询效率
    • 采用列簇式存储: 同一个列簇的所有列的数据存放在一起; 不同列簇的数据在物理上分开
  3. 列簇是排好序的Cell构成的
    1. Cell的构成
      • row key
      • column family
      • qualifier(列)
      • timestamp
      • value
        (其中,前4个构成key)
    2. Cell排序规则
      • row key: 升序
      • column family: 升序
      • qualifier: 升序
      • timestamp: 降序
    3. Cell支持二分查找

四. Hbase划分子表

  1. Region模型
    • Hbase把一张大表拆分成多个子表, 每个子表成为一个Region
    • 不同Region放在不同机器上
    • 子表按照行健范围划分.
      不存在一个row key的数据被划分到2个不同region的情况
    • 每个Region都包含所有列表
  2. Region的存储思路
    • Region内部包含多个列簇, 每个列簇被一个Store存储
    • 每个Store把数据分为两部分: MemStore和StoreFile
    • MemStore只存储新增的和修改过的数据, 并在内存满的时候将数据刷新到StoreFile

五. Hbase的特点

  1. Hbase应用场景
    1. 用户画像
      • 用户画像中用户的特征有几十万个, 但大部分特征都是空的, 是一个稀疏的矩阵
      • mysql存储上亿行, 几十万列的情况会造成巨大浪费
    2. 网页搜索倒排索引
    3. 淘宝交易数据
  2. hbase是强一致性的
  3. 如果需要更新数据, 或进行随机读写, Hbase比hdfs更合适
  4. Hbase的字段部分数据类型, 全都按照字节存储, 需要上次应用系统按照类型翻译字节
  5. Hbase只有聚簇索引(主键索引),没有二级索引:
    • 聚簇索引: 把这个字段抽取出来, 在这个字段上遍历查找, 而不用去全表扫描, 减小磁盘IO
    • 二级索引: 把索引字段排序后进行索引
  6. null记录, 在Hbase中不占空间
  7. Hbase不是列式存储,而是列族式存储
    • 把经常需要一起读写的业务字段设置成一个列族

\S2. 架构

一. 过滤器

  1. Filter简介
    • hbase为scan和get操作提供更加高级的filter
    • Filter可以根据qualifier,列簇,版本等条件对行进行过滤.减少返回的结果数量, 降低网络传输压力
    • 过滤操作在RegionServer上执行
  2. SingleColumnValueFilter: 实现列簇/列上的where语义
  3. RowFilter, 实现row key的正则表达式过滤
  4. FamilyFilter,
  5. QualifierFilter,
  6. FilterList, 实现查询条件and语法
    各种过滤器
    布隆过滤器
    Hbase架构

二. Compact原理

  1. Hbase基于Log-Structed Merge Tree架构的
  2. 传统的B^+树能够执行快速随机读取, 但随机写入因为要调整树形结构, 因此在大数据量下会变的很慢
    • 为什么B^+树的随机读取很快?
      B^+树是多路查找树, 所以要随机查找一个数值, 将节点调入内存的次数只和树的高度有关. 又因为B^+树的每个节点包含很多值, 所以节点调入内存时产生的磁盘IO是顺序IO, 又加快了节点调入内存的速度
  3. LSM tree如何快速执行随机写?
    • LSM tree首先在内存中维护一个有序的树形结构,类似B^+树,称作MemStore. 随机写入的数据会在MemStore中调整树型后插入这个有序树中.
    • 为了保证数据的可靠性, 在写入Memstore前会先以WAL(Write-Ahead-Log)的方式备份写日志
    • 当MemStore的数据量到达一定条件后, 会被刷新到磁盘上形成一个新文件"HFile". 因为这种写磁盘是顺序写, 没有旧文件被读取修改, 因此执行很快
    • "HFile"在LSM tree架构里又称sstable, 意为相似的有序文件.当执行随机读取时, 首先在MemStore中查找是否存在这个key, 是的话直接返回, 不是的话查找每个HFile中的记录. 因为HFile中的记录和Memstore一样也是有序的树形结构, 所以查找一个HFile的时间复杂度 O(logN) , 所有的HFile查找时间复杂度 k*O(logN). 因此, 如果HFIle的数量很多, 会使得查找速度变慢, 需要Compact操作
    • LSM tree主要是对写优化
      综上, 因为随机写入是分批量的顺序写入磁盘, 所以速度很快
  4. Bloom过滤器, 减少HFile的筛选
    为了减少随机读取时需要查找的HFile数量, 可使用Bloom过滤器先行判断带查找的key是否在这个HFile里. 如果Bloom过滤器返回False, 则key一定不在HFile里, 如果返回True, 仍有一定概率不在这个HFile里
  5. Compact
    • Minor compact
      将一些小的,相邻的HFile合并成一个大的HFile. 此过程不会处理过期或已删除的kv对
    • Major compact
      把一个Region下的所有HFile合并成一个大的HFile. 此过程会清理掉3类无意义的数据: 被删除的数据, TTL过期数据, 版本号超过限制的数据
      Major compact耗时很长, 通常关闭自动major compact, 改为业务低峰期时手动处理Major Compact

三. Bloom过滤器

  1. 上面的LSM tree架构中提到, 随机读时使用Bloom过滤器减少查找的HFile数量, 在Hbase就是使用Bloom过滤器判断该rowkey是否可能在该HFile中
  2. 算法描述
    • Bloom过滤器用于判断一个元素是否在一个集合内,是一种概率数据结构
      它返回"可能在集合内"和"绝不可能在集合内"2个结果. 集合中的元素越多, Bloom误判成可能在集合中的概率就越大
    • Bloom过滤器定义k个hash函数, 和一个长度为m的bit数组(bitmap,java中用BitSet表示).
      数组被初始化为全0数组, 每个哈希函数会把集合中的元素用射到数组的一个位置, 并把该位置的数组值置1.
      测试一个元素是否在集合中, 用预先定义的k个hash函数依次哈希该值, 得到k个位置, 查看数组中这k个位置的值是否全部是1, 有一个为0则返回"一定不在集合中"
      m的选择决定了Bloom过滤器误判概率的大小
    • k个hash函数应该选择互相之间少有重叠的, 比如"2次方hash,3次方hash"
  3. 概率解释
    • 误判成"可能存在"的概率
      假设hash函数会把一个值等概率的映射到数组的m个位置, 则依次hash后, 该位置的数组没有被置为1的概率为1-\frac{1}{m}
      k个不相关的hash函数均未把该位置置1的概率为{(1-\frac{1}{m})}^k
      插入n个元素后, 该位置仍为0的概率{(1-\frac{1}{m})}^{kn}
      即该位置为1的概率1-{(1-\frac{1}{m})}^{kn}
    • k的选择
      k只由误判的概率决定, 有k=-{log_2}P

四. zookeeper中的meta表

  1. meta表的作用

    • 我们知道HBase的表是会分割为多个Region的,不同Region分布到不同RegionServer上。
    • Region 是 HBase中分布式存储和负载均衡的最小单元。
      所以当我们从客户端读取,写入数据的时候,我们就需要知道数据的Rowkey是在哪个Region以及我们需要的Region是在哪个RegionServer上。而这正是HBase Meta表所记录的信息。
  2. meta表也是一张Hbase的表

    • meta表也是一张Hbase表, 有rowkey, 列族, 列
    • hbase的所有查询操作, 都要先访问meta表, 找到自己所查记录的表和rowkey在哪个Region上, 再到那个Region上执行memstore或hfile的查找
  3. meta表的rowkey

    • meta表的rowkey组成结构: table名 + region的start key + 时间戳
    • 上述3者的MD5值也是HBase在HDFS上的region名
  4. meta表的列族和列

    • 最主要的Family:info
    • info里面包含三个列:regioninfo, server, serverstartcode。
      其中regioninfo就是Region的详细信息,包括StartKey, EndKey 以及每个Family的信息等。server存储的就是管理这个Region的RegionServer的地址。所以当Region被拆分、合并或者重新分配的时候,都需要来修改这张表的内容。
  5. Hbase数据查询过程:

    1. 客户端连接zookeeper, 查找meta表在哪个机器上
    2. 查询meta表, 根据每个region的startKeyendKey找到region所在的server
    3. 到指定Server上查找该region
    4. meta标的信息会被缓存起来, 便于下次查找

五. HBase的master-slave架构

  • HMaster
    • 每个HregionServer都与HMaster保持心跳通信.
    • HMaster负责给HRegionServer分配HRegion
    • 当一台HRegionServer宕机, HMaster会把这个RegionServer的Region标记为未分配, 然后再把他们分配到其他HRegionServer中
    • HMaster的功能: HMaster主要负责TableRegion的管理工作
      • 管理用户对Table级别的增删改查
      • 负责HRegionServer的负载均衡, 调整Region在每台机器的分布
      • 在Region分片后, 负责新的Region分配
      • 在HRegion Server停机后, 负责失效的HRegionServer上的Regions迁移
  • HRegionServer
    • 用户通过访问HRegionServer获取这些数据
    • 一台机器上面一般只运行一个HRegionServer
    • 一个HRegionServer上面有多个HRegion,一个HRegion 也只会被
    • 一个HRegionServer维护

\S3. Rowkey设计

1. Rowkey

唯一标识一行记录的主键, Hbase按照RowKey的字典顺序全局排序

2. 稀疏矩阵

Hbase中表的数据按照稀疏方式存储. 因为不想传统数据库组织数据形式, Hbase的列组成很灵活, 行与行之间不遵循相同的列定义

3. Region

Hbase不同于spark的hash code分区, 使用"key range"划分子表"Region". Region是Hbase负载均衡的基本单元, Region增大到一定大小后会自动分裂

4. column family

Region是对Hbase表的横向切割, 则Column Family是对表的纵向切割. 每个column都要归属于一个Column Family, 这个归属关系是在写数据时指定的而不是建表时预先定义的

5. kv形式存储

Hbase中每行的每一列数据都以key-value形式存储. key相同的任意数量的独立key-value形成逻辑上的一行数据

Hbase行键设计

往往组合多个字段在一起作为rowkey, RowKey中的第一个字段称之为"先导字段"

1. 反转

如果先到字段本身会带来热点问题, 但该字段的尾部却具有良好的随机性; 此时可将先导字段做反转处理

2. 加盐

在rowkey前面加上长度固定的随机Bytes

3. 哈希

将rowkey哈希后生成固定长度的byte串. 由于hash有很好的离散度, 所以可保障数据被均匀分散到各个region. hash rowkey既适合于随机写入, 也适合于知道rowkey后的随机查询, 带在查询一个范围内的rowkey时会有性能问题, 因为原本连续的rowkeyhash后被离散到多个region

列的设计

hbase中的每一列都是key-value形式的. 定义列就是要定义出列簇和列标识符. 列簇和列标识符应该尽量短


一条数据的HBase之旅,简明HBase入门教程-开篇

一. 前言

  1. Region是一个连续范围内的rowkey空间, 连续指Region中的rowkey在start key到end key范围内排序
  2. Region之间不会产生交叉, 一个rowkey只能属于一个Region, 被一个RegionServer管理
  3. meta表中, 使用3层B树找到某个表的某个rowkey所在的Region
  4. 当初次创建一张表时, Hbase只会分配一个Region给这张表. 这意味着初始时, 所有的request都会通往一个RegionServer上

二. PRE-SPLITTING

  1. 为什么使用预先划分?
    上面讲到, 一张表初始创建时, 因为只有一个Region, 所以所有的请求都会发往一个RegionServer, 造成压力巨大. 如果创建表时就制定Region的数量, 并按照一定的规则将rowkey发往不同的Region, 就会在初始就使用集群的分布式功能

  2. 预划分的start key和end key生成策略
    预划分需要计算表的分割点"split points", 有两种默认的预划分算法:

    • HexStringSplit:
      如果rowkey是ASCII码表示的, 可以使通过MD5生成或者其他产生均匀分布的16进制表示法. rowkey范围为"00000000" => "FFFFFFFF"的范围, 左侧补0来使rowkey长度相同. 它把rowkey均匀分配到Region上, 这中做法会造成更大的空间使用量, 且不够直观
    • UniformSplit:
      如果rowkey是字节数组,可以用UniformSplit的方式进行,按照原始byte值(从0x00~0xFF)右边以00填充。以这种方式分区的表在插入的时候需要对rowkey进行一个技巧性的改造, 比如原来的rowkey为rawStr,则需要对其取hashCode,然后进行按照比特位反转后放在最初rowkey串的前面
    Integer.reverse(Integer.valueOf(Integer.valueOf(i).hashCode())))
    
  3. 通常使用预划分建表指定region数量以及region划分算法, 后面使用Region自动划分

三. AUTO SPLITTING

  1. 什么时候执行自动划分
    无论是否开启了pre-spliting, 一旦Region到一定限制, 就会自动化分为2个Region. 有3种预定义的自动划分策略
    • ConstantSizeRegionSplitPolicy
    • IncreasingToUpperBoundRegionSplitPolicy
    • KeyPrefixRegionSplitPolicy.

四. Force-split(手工切分)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容

  • 一、简介 Hbase:全名Hadoop DataBase,是一种开源的,可伸缩的,严格一致性(并非最终一致性)的分...
    菜鸟小玄阅读 2,357评论 0 12
  • 一、HBase简介 Hbase是什么 HBase是一种构建在HDFS之上的分布式、面向列、多版本、非关系型的数据库...
    便利蜂数据平台阅读 971评论 0 4
  • 参考:https://www.jianshu.com/p/569106a3008f 最近在逐步跟进Hbase的相关...
    博弈史密斯阅读 843评论 1 1
  • HBase存储架构图 HBase Master 为Region server分配region 负责Region s...
    kimibob阅读 5,551评论 0 52
  • 简介 HBase —— Hadoop Database的简称,Google BigTable的另一种开源实现方式,...
    编码前线阅读 274评论 0 0