栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

HBase基础知识(个人总结)

HBase基础知识(个人总结)

    声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章
              2. 由于是个人总结, 所以用最精简的话语来写文章
              3. 若有错误不当之处, 请指出

基础知识:

数据种类:

    结构化数据 比如MySQL这种关心型数据库里的数据, 操控起来方便半结构化数据 有特定语法格式的数据, 比如json非结构化数据 视频,音频,文本 这种难以处理的数据

关系型数据库 & 非关系型(NoSQL)数据库:

    数据类型不同: 关系型数据库的数据类型是二维表格, NoSQL数据库的数据类型没有确定形式, 很灵活, 有KV型, 列式, 文档型等等关系型数据库支持SQL语法, 而NoSQL数据库不支持SQL语法

行式数据库 & 列式数据库

    存储方式不同:

    比如有A列和B列, 数据有A1, A2, A3, B1, B2, B3

    行式存储为: [A1, B1, A2, B2, A3, B3]; 列式存储为: [A1, A2, A3, B1, B2, B3]

    擅长领域不同: 行式数据库适用于查询, 列式数据库适用于聚合统计

    从存储方式上可以看出, 行式存储的某一行的不同列之间紧挨着, 适合查询一整行数据;

    ​ 列式存储的某一列的不同行之间紧挨着, 适合查询一整列的数据

    而大数据场景, 大多数时都是数据的统计。我们经常只是需要其中某一列进行聚合统计,而不关心其他列的数据

    压缩效果不同, 列式存储压缩效果更好

OLTP & OLAP

OLTP: 联机事务处理, 一般是那种 后端的关系型数据库(存储数据少, 行式数据库MySQL等)

OLAP: 联机事务分析, 一般是那种 大数据的NoSQL数据库(存储数据多, 列式数据库如Hbase/ClickHouse, Presto)

架构:

有RowKey, 列族, 列, Region, StoreFile(HFile), Cell, 命名空间, 表

增改为Put, 删除为Delete(本质也是Put), 关键字段timestap就代表着版本

结构图:

一个Region是多行相邻数据, 按列族(对应StoreFile)存储,

自带的命名空间:

    hbase 存放的是Hbase内置的表default 表是用户默认使用的命名空间

Hbase定义表时只需要声明列族即可, 不需要声明具体的列, 字段可以动态、按需指定。因此适合应对字段变更的场景。

BlockCache是用来优化读操作的缓存, MemCache是为了优化写操作的缓冲(到刷写时机了批量写到磁盘)

WAL预写日志:

    Hbase的WAL只是为了备份数据, flush和compact的时候并不用它(flush用的是内存数据, compact用的是HFile)

    Hadoop的EditLog除了是用来备份数据, 与FsImage合并时也要用到它

hbase truncate不要乱用, 它会同时删除元数据信息如分区键规则, 协处理器倒是不会删掉

LSM:

Hbase和ClickHouse这种内存+磁盘的架构, 即用的是LSM结构(日志结构的合并树)

思想: 假定内存足够大,因此不需要每次有数据更新就必须将数据写入到磁盘中,而可以先将最新的数据驻留在内存中;

​ 等到积攒到足够多之后,再归并排序将数据合并追加到磁盘

与B+树相比:

    牺牲读性能(读取时可能需要访问较多的磁盘文件)提高写性能(刷写落盘前有一个内存缓冲区)

补偿读性能的优化:

    Bloom Filter 读HFile时使用布隆过滤器compact 小树合并为大树

架构角色:

    HMaster

    负责DDL操作: 对于表结构 create, delete, alter

    负责管理调度: 分配regions到每个RegionServer(并做负载均衡和故障转移)

    ​ 监控每个RegionServer的状态

    HRegion Server

    管理Region, WAL, 负责table数据的实际读写, 执行Flush 和 Compaction

    ZooKeeper

    Hbase通过ZooKeeper来做Master的高可用

    监控RegionServer

    Client请求ZooKeeper meta表位于哪个RegionServer

    HDFS

读流程:

    Client先访问ZooKeeper,获取hbase:meta表位于哪个Region Server

    访问对应的Region Server,获取hbase:meta表,

    根据namespace:table:rowkey,查询出目标数据位于哪个Region Server中的哪个Region

​ 并将该表的 Region信息&meta表的位置信息 缓存在客户端的meta cache

    与目标Region Server进行通讯先在MemStore中查询目标数据,再去Block Cache中查询目标数据,如果找不到的话再去查询Store File(HFile)将查询到的新的数据块(HFile的数据存储单元, 默认大小为64KB)缓存到Block Cache返回这两次查到的 最新版本的数据
写流程:

1)Client先访问ZooKeeper,获取hbase:meta表位于哪个Region Server

2)访问对应的Region Server,获取hbase:meta表,

​ 根据namespace:table:rowkey, 查询出目标数据所在表位于哪个Region

​ 并将该表的 Region信息&meta表的位置信息 缓存在客户端的meta cache

3)与目标Region Server进行通讯

4)将数据顺序写入(追加)到HLog(WAL), 做备份

5)将数据写入对应的MemStore,数据会按RowKey在MemStore进行排序, 便于以后的查找缩小范围

6)Region Server向客户端发送ack

7)等达到MemStore的刷写时机后,将数据刷写到HFile

MemStore Flush刷写时机:

    某个MemStore的大小达到了hbase.hregion.memstore.flush.size(默认128M)


    什么时候阻止继续往某个MemStore写数据?

    当MemStore的大小达到了hbase.hregion.memstore.flush.size(默认125M) * hbase.hregion.memstore.block.multiplier(默认4), 即500M时

    某个RegionServer中所有MemStore的总大小达到

    堆内存大小 * hbase.regionserver.global.memstore.size(默认0.4)

    * hbase.regionserver.global.memstore.size.lower.limit(默认0.95), 即0.38倍堆大小时

    则按照所有MemStore由大到小的顺序依次进行刷写, 直到所有memstore的总大小减小到低于上述临界值

    这种情况下可见, HFile里的数据timestap未必是最小的, 那查数据时, 即便MemStore中找到了该数据也仍要去访问HFile文件(但会借助于布隆过滤器), 因为timestap大的才是最新数据


    什么时候阻止继续往所有MemStore写数据?

    当某个RegionServer中MemStore的总大小达到

    堆内存大小 * hbase.regionserver.global.memstore.size(默认值0.4), 即0.4倍堆大小时

    到达自动刷写的时 hbase.regionserver.optionalcacheflushinterval(默认1小时)

    当WAL文件的数量超过hbase.regionserver.max.logs,会按照timestap从小到大顺序依次进行刷写, 直到WAL文件数量减小到低于上述临界值(该属性名已废弃, 现无需手动设置,最大为32)

读写特点:

Hbase的读写类似, 即便是写(增删改)数据也要先查找数据所在表位于哪个RegionServer中的哪个Region

而HDFS的写, 既然是写(增加)数据, 就不会提前位于DataNode中

StoreFile Compaction:

StoreFile底层是HFile

是为了减少HFile的个数,以及清理掉 过期和删除 的老数据

    Minor Compaction

    将临近的若干个较小的HFile合并成一个较大的HFile, 并清理掉 过期和删除 的数据

    Major Compaction

    将一个Store下的所有的HFile合并成一个大HFile, 并清理掉 过期和删除 的数据

Region Split:

起初表只有一个Region(如果不自己预分区的话),

为了更好的负载均衡 以及增加存储利用率,HMaster有可能会将某个Region转移给其他的Region Server

切分规则:

0.94版本之后, 2.0版本之前:

​ 阈值为min(R^3 * initialSize,hbase.hregion.max.filesize"), 即min(R^3 * 256M, 10G)

​ R为当前Region Server中属于该表的Region个数

​ 示例:

第一次split:1^3 * 256 = 256MB

第二次split:2^3 * 256 = 2048MB

第三次split:3^3 * 256 = 6912MB

第四次split:4^3 * 256 = 16384M > 10GB,因此取较小的值10GB

后面每次split的size都是10GB了

2.0版本新策略:

    如果当前RegionServer上该表只有1个Region,则按照2 * hbase.hregion.memstore.flush.size切分,

    否则按照hbase.hregion.max.filesize切分。

预分区:

目的: 自定义分区后, 根据数据的RowKey可以迅速得知它属于哪一个Region

比如按 100,200,300分区键 去预分区, 则有(-∞, 100], (100,200], (200,300],(300,+∞) 这4个分区,

一条数据是拿Rowkey和分区键 按照字典序比较的

设定预分区的方法:

    手动设定预分区

    create ‘staff1’,‘info’,‘partition1’,SPLITS => [‘100’,‘200’,‘300’]

    生成16进制序列预分区(0-15, 16个分区键)

    create ‘staff2’,‘info’,‘partition2’,{NUMREGIONS => 15, SPLITALGO => ‘HexStringSplit’}

    按照文件中设置的规则预分区(常用):

    vim splits.txt

    aaaa

    bbbb

    cccc

    dddd

    create ‘staff3’,‘partition3’,SPLITS_FILE => ‘splits.txt’

    使用JavaAPI创建预分区

    //自定义算法,产生一系列Hash散列值存储在二维数组中, byte[]相当于String, bytre[][]相当于String[]
    byte[][] splitKeys = 某个散列值函数
    //创建HbaseAdmin实例
    HbaseAdmin hAdmin = new HbaseAdmin(HbaseConfiguration.create( ));
    //创建HTableDescriptor实例
    HTableDescriptor tableDesc = new HTableDescriptor(tableName);
    //通过HTableDescriptor实例和散列值二维数组创建带有预分区的Hbase表
    hAdmin.createTable(tableDesc, splitKeys);
    
RowKey设计:

目的: 让数据均匀的分布, 防止数据倾斜

_小于所有数字

| 是大于很多字符, 只小于}

设计原则:

    rowkey长度原则

    rowkey散列原则

    rowkey唯一原则

方案:

    生成随机数、hash、加密

    例如原本rowKey为1001的,SHA1后变成:dd01903921ea24941c26a48f2cec24e0bb0e8cc7

    日期时间反转(个位变化频率低, 高位变化频率低, 所以原数据分布有规律会数据密集, 而反转后就没规律了)

    20170524000001转成10000042507102

    20170524000002转成20000042507102

    随机字符串拼接

    20170524000001_a12e

    20170524000001_93i7

高可用:

vim conf/backup-masters, 里面写上备机ip

内存优化:

不建议分配非常大的堆内存, 一般配16~36G

因为:

    在(0.4-0.38)*堆大小 这段内存回收时, RegionServer是禁止写数据的, 堆内存过大会增大其值, 导致增加了禁止写数据的时间

    Linux系统运行和其他软件运行也需要内存, 不能全分给Hbase了

参数优化

    ZooKeeper会话超时时间
    ZooKeeper.session.timeout 默认值为90000毫秒(90s)。当某个RegionServer挂掉了, 90s之后Master才能察觉到。

    可适当减小此值,以加快Master响应,可调整至600000毫秒。

    设置RPC监听数量
    hbase.regionserver.handler.count 默认值为30

    可以根据客户端的请求数进行调整,读写请求较多时,增加此值。

    手动控制Major Compaction的周期

    hbase.hregion.majorcompaction 默认值:604800000秒(7天)

    若关闭自动Major Compaction,可将其设为0

    优化HFile大小
    hbase.hregion.max.filesize 默认值10737418240(10GB), 如果一个HFile(列族)的大小达到这个数值, 则这个Region就会被切分为两个Region

    如果要运行Hbase的MR任务, 可以减小此值

    因为一个Region对应一个MapTask,如果单个Region过大,会导致MapTask执行时间过长。

    优化Hbase客户端缓存大小
    hbase.client.write.buffer 默认值2097152bytes(2M)

    增大该值可以减少RPC调用次数

    指定scan.next扫描Hbase所获取的行数
    hbase.client.scanner.caching

    BlockCache占用RegionServer堆内存的比例
    hfile.block.cache.size 默认0.4

    读请求比较多的情况下, 可适当调大

    MemStore占用RegionServer堆内存的比例
    hbase.regionserver.global.memstore.size 默认0.4

    写请求较多的情况下,可适当调大

    优化数据的写入效率, 开启压缩

    mapreduce.map.output.compress 设为true

    mapreduce.map.output.compress.codec 指定压缩方式

Hive对比Hbase:

速度上:

Hive 查询 和 增加数据 速度缓慢, 因为要走MR等引擎Hbase 查询 和 增加数据 快, 因为布隆过滤器 & BlockCache & 顺序写操作(按timestap判断是否为最新有效数据) 进行优化

增删改方面:

只允许增加数据虽然也是只允许增加数据, 但是通过timestap字段, 可以实现增删改的功能

是否为数据库:

Hive本质上并不是数据库, 而是将MySQL表的元数据 和 HDFS文件进行映射, 形成了逻辑上的数据库Hbase是列式数据库

数据分析方面:

Hive擅长做数据分析

Hbase不擅长做数据分析

相同点:都依赖于HDFS进行存数据, 可以用SQL语句去查数据

Hive集成Hbase:

目的: 建立Hive表关联Hbase表,插入数据到Hive表的同时能够影响Hbase表

注意: 不能将数据直接load进Hive(这只会校验存储格式, 合法的法直接剪切, 让Hbase感知不到)

步骤: 创建表&关联 --> 创建临时表 --> load进临时表 --> insert into 原表 select 字段 from 临时表

在hive-site.xml里配置ZooKeeper

    
        hive.ZooKeeper.quorum
        hadoop102,hadoop103,hadoop104
    
    
        hive.ZooKeeper.client.port
        2181
    

建表时通过描述语句进行关联:

CREATE TABLE hive_hbase_emp_table(
empno int,
ename string,
job string,
)
-- 描述语句
STORED BY 'org.apache.hadoop.hive.hbase.HbaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":id, info:ename, info:job")
TBLPROPERTIES ("hbase.table.name" = "hbase_emp_table");
Phoenix:

是Hbase的SQL皮肤

坑: 注意大小写, 在引号内部才能保持原样, 否则就任务是大写

(一级)索引是对RowKey的索引

二级索引是对非RowKey字段的索引, 先找到这个普通字段数据对应的主键, 再通过主键去查找实际数据

全局 & 本地: (优缺点没搞懂)

    全局二级索引(默认), 适用于读多写少, 索引 和 数据 不存储在一起

    优点: 读数据时 会优先选择索引表来查询

    缺点: 写操作时 要更新的索引可能位于不同机器, 加大了网络IO 和 磁盘寻址IO 的损耗, 更占用空间

    本地二级索引, 适用于写多读少, 索引 和 数据 存放在同一个Region中(且是同一个),

    优点: 写操作时 要更新的索引位于同台机器, 减少了网络IO 和 磁盘寻址IO(实际数据在附近, 顺序寻址较快) 的额外开销, 更节省空间

    缺点: 无法提前确定数据在哪个Region上

面试题:

Hbase的批量加载 底层是靠MapReduce实现的

协处理器(CoProcessor)

分为:

    Observer: 相当于MySQL的触发器, 监听到一个表变化后 便自动地去同步操作另一个表 (如 偶像表 和 粉丝表 需要同步变化)Endpoint: 类似于MySQL地存储过程, 一般用于分布式聚合计算

建立二级索引, 需要同步索引表, 靠的就是Observer协处理器

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/758789.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号