岚殿的技术博客 岚殿的技术博客
首页
Java
  • docker
  • hbase
  • 提示词工程
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

岚殿

首页
Java
  • docker
  • hbase
  • 提示词工程
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • docker

  • hbase

    • hbase-入门
    • hbase-原理
      • 存储引擎
      • 写流程
      • 读流程
        • Block Cahce
      • 合并
        • 触发时机
      • 数据切分
      • Hfile结构
      • 并发控制
      • 宕机恢复
      • 高可用
  • 技术学习
  • hbase
lan-dian
2024-04-10
目录

hbase-原理

# 存储引擎

底层存储引擎是基于LSM-Tree数据结构设计的。写入数据时会先写WAL日志,再将数据写到写缓存MemStore中,等写缓存达到一定规模后或满足其他触发条件才会flush刷写到磁盘,这样就将磁盘随机写变成了顺序写,提高了写性能。每一次刷写磁盘都会生成新的HFile文件。 随着时间推移,写入的HFile会越来越多,查询数据时就会因为要进行多次io导致性能降低,为了提升读性能,HBase会定期执行compaction操作以合并HFile。

读优化

此外,HBase在读路径上也有诸多设计,其中一个重要的点是设计了BlockCache读缓存。这样以后,读取数据时会依次从BlockCache、MemStore以及HFile中seek数据,再加上一些其他设计比如布隆过滤器、索引等,保证了HBase的高性能。

# 写流程

  1. 访问Zookeeper获取具体交互的服务器地址,并且缓存在客户端。
  2. 追加到WAL中,写在MemStore中并且排序。
    1. 会先写WAL再写内存,如果同步日志失败,那么内存也会被回滚
  3. MemStore刷盘(基本上包含了所以刷盘的可能性,非常值得学习)
    1. Region的memstore太大了会刷盘
    2. 写入的太快会阻塞写入,抛出异常,并且刷新memstore
    3. 总的RegionServer太大也会刷盘,因为都在一个JVM内存里面,所以在内存占用过高的时候,减少gc的影响,从大到小开始刷数据
    4. 定时刷新,避免如果没有数据写入就不刷新到磁盘的问题
    5. 更新次数太多,如果更新的量很小,但是更新的次数多,也不会导致内存扩张,所以在更新次数多的时候也刷盘
    6. WAL文件太大的时候也会刷新

# 读流程

  1. 访问Zookeeper获取具体交互的服务器地址,并且缓存在客户端。
  2. 分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)。

# Block Cahce

HBase缓存不像对传统缓存理解的一样读了内存如果有数据就不再读磁盘,因为它是以时间戳进行版本控制的,所以不能只读内存。 HBase读数据无论如何都会扫描HDFS磁盘,只是在 BlockCache 中存在的数据不再读取,BlockCache 只是提高了读磁盘的效率。如:磁盘中有数据A和B,BlockCache 中有数据A,则扫描磁盘时只读取B,不再读取A。 所以 HBase 是写比读快(读不仅扫磁盘,还要合并选取数据)。

# 合并

由于memstore每次刷写都会生成一个新的HFile,且同一个字段的不同版本(timestamp)和不同类型(Put/Delete)有可能会分布在不同的 HFile 中,因此查询时需要遍历所有的 HFile。 为了减少 HFile 的个数,以及清理掉过期和删除的数据,会进行 StoreFile Compaction。Compaction 分为两种,分别是 Minor Compaction 和 Major Compaction。

Minor Compaction

Minor Compaction 是指选取一些小的、相邻的 HFile 将他们合并成一个更大的 HFile。默认情况下,Minor Compaction 会删除所合并 HFile 中的 TTL 过期数据,但是不会删除手动删除(也就是 Delete 标记作用的数据)不会被删除。

Major Compaction

Major Compaction 是指将一个 Store 中所有的 HFile 合并成一个 HFile,这个过程会清理三类没有意义的数据:被删除的数据(打了 Delete 标记的数据)、TTL 过期数据、版本号超过设定版本号的数据。 另外,一般情况下,Major Compaction 时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此,生产环境下通常关闭自动触发 Major Compaction 功能,改为手动在业务低峰期触发。

# 触发时机

MemStore Flush

HBase 每次Flush 之后,都会判断是否要进行 Compaction,一旦满足 Minor Compaction 或 Major Compaction 的条件便会触发执行。

后台线程周期性检查

这里主要考虑的是一段时间内没有写入仍然需要做 Compact 检查。

手动触发

compact、major_compact

# 数据切分

默认情况下,每个 Table 起初只有一个 Region,随着数据的不断写入,Region 会自动进行拆分。刚拆分时,两个子 Region 都位于当前的 Region Server,但处于负载均衡的考虑,HMaster 有可能会将某个 Region 转移给其他的 Region Server。 数据切分会造成数据倾斜(region 大小分布不均),带来热点数据问题。所以建表时进行预分区来尽量避免这种问题。

# Hfile结构

HFile中包含了一个多层索引系统。这个多层索引是的HBase可以在不读取整个文件的情况下查找数据。这一多层索引类似于一个B+树。 文件结尾指向meta block。因为meta block是在数据写入硬盘操作的结尾写入该文件中的。文件的结尾同时还包含一些别的信息。比如 bloom filter 及时间信息。bloom filter可以帮助HBase加速数据查询的速度。因为HBase可以利用 bloom filter 跳过不包含当前查询的键的文件。时间信息则可以帮助HBase在查询时跳过读操作所期望的时间区域之外的文件。HFile的索引在HFile被打开时会被读取到内存中。这样就可以保证数据检索只需一次硬盘查询操作。

# 并发控制

写写并发

多个写入/更新同时进行会导致数据不一致的问题,HBase通过获取行锁来实现写写并发,如果获取不到,就需要不断重试等待或者自旋等待,直至其他线程释放该锁。拿到锁之后开始写入数据,写入完成之后释放行锁即可。这种行锁机制是实现写写并发控制最常用的手段,MySQL也使用了行锁来实现写写并发。

读写并发

HBase中MVCC机制实现主要分为两步: (1) 为每一个写入/更新事务分配一个Region级别自增的序列号。 (2) 为每一个读请求分配一个已完成的最大写事务序列号。

# 宕机恢复

当Region Server宕机的时候,其所管理的region在这一故障被发现并修复之前是不可访问的。ZooKeeper负责根据服务器的心跳信息来监控服务器的工作状态。当某一服务器下线之后,ZooKeeper会发送该服务器下线的通知。HMaster收到这一通知之后会进行恢复操作。 HMaster会首先将宕机的Region Server所管理的region分配给其他仍在工作的活跃的Region Server。然后HMaster会将该服务器的WAL分割并分别分配给相应的新分配的Region Server进行存储。新的Region Server会读取并顺序执行WAL中的数据操作,从而重新创建相应的MemStore。

# 高可用

HBase使用Hadoop的HDFS作为底层存储,数据被分散存储在多个RegionServer上。每个RegionServer都负责管理一部分数据,这些数据通过HBase的分区机制进行划分。同时,HBase还使用了Hadoop的复制机制,将数据复制到多个RegionServer上,以实现数据的冗余备份。当一个RegionServer出现故障时,系统可以从其他RegionServer上获取备份数据,实现高可用性。

编辑 (opens new window)
#笔记
上次更新: 2024/04/24, 11:31:27
hbase-入门

← hbase-入门

最近更新
01
设计模式
04-22
02
提示词工程
04-14
03
hbase-入门
04-10
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式