大厂Hbase八股文面试题及参考答案(百度米哈游完美世界多家面经汇总)

介绍下 HBase?HBase 优缺点有哪些?

HBase 是一个分布式、面向列的 NoSQL 数据库,基于 Hadoop 的 HDFS 存储系统设计,适合处理海量数据的实时读写需求。它模仿 Google 的 Bigtable 模型,通过强一致性和水平扩展能力支持高并发场景。

核心特点

  • 列式存储:数据按列族(Column Family)组织,适合稀疏数据场景。
  • 强一致性:基于 HDFS 的多副本机制,保证数据可靠性。
  • 自动分片:数据按 Region 自动分片,支持动态扩展。
  • 版本控制:每个单元格(Cell)支持多版本数据存储。

优点

  1. 高扩展性:通过增加 RegionServer 节点轻松扩展集群容量。
  2. 高吞吐与低延迟:LSM 树结构优化写入,BlockCache 提升读取性能。
  3. 灵活数据模型:无需预定义表结构,支持动态列和稀疏数据。
  4. 与 Hadoop 生态无缝集成:可直接使用 MapReduce 或 Spark 进行数据分析。

缺点

  1. 不支持复杂查询:缺乏 SQL 支持,需通过 Scan 或 Filter 实现简单查询。
  2. 单点故障风险:HMaster 负责元数据管理,若未配置高可用可能成为瓶颈。
  3. 内存消耗高:MemStore 和 BlockCache 依赖内存,需合理配置资源。
  4. 无事务支持:仅支持行级原子性,跨行操作需自行处理一致性。

说下 HBase 原理?介绍下 HBase 架构?

HBase 的核心原理基于 LSM 树(Log-Structured Merge Tree),通过将随机写入转换为顺序写入提升性能。数据首先写入内存(MemStore),达到阈值后刷写到磁盘(HFile),后台定期合并小文件以减少读取开销。

架构组成

  • HMaster:负责元数据管理(如表结构、Region 分配)。处理 Region 的负载均衡与故障转移。注意:生产环境需配置多个 HMaster 以避免单点故障。
  • RegionServer:管理多个 Region,处理客户端读写请求。包含 **MemStore(写缓存)**和 BlockCache(读缓存)。
  • ZooKeeper:协调集群状态,监控 RegionServer 存活。存储 HBase 的元数据(如 HMaster 地址)。
  • HDFS:持久化存储 HFile 和预写日志(WAL)。

数据组织

  • 表按行键(Row Key)水平划分为多个 Region,每个 Region 包含连续的行区间。
  • 列族(Column Family)是物理存储单元,不同列族的数据独立存储。

HBase 读写数据流程是怎样的?HBase 的读写缓存是怎样的?在删除 HBase 中的一个数据的时候,它什么时候真正进行删除?

写入流程

  1. 客户端通过 ZooKeeper 定位目标 Region 所在的 RegionServer。
  2. 数据先写入 WAL(Write-Ahead Log),确保故障恢复能力。
  3. 写入 MemStore,内存达到阈值后异步刷写到 HDFS 生成 HFile。

读取流程

  1. 客户端从 ZooKeeper 和 Meta 表获取 Region 位置。
  2. BlockCache → MemStore → HFile 的顺序查找数据,合并结果返回。

读写缓存机制

  • BlockCache:缓存频繁访问的 HFile 数据块(如 Bloom Filter),采用 LRU 策略淘汰。
  • MemStore:写缓存,按列族隔离,刷写后生成新的 HFile。

数据删除逻辑

  • 删除操作会插入一个 墓碑标记(Tombstone),而非立即物理删除数据。
  • 墓碑标记在以下两种场景生效: Minor Compaction:合并 HFile 时跳过标记的数据。Major Compaction:彻底清理标记数据并释放空间。

HBase 中的二级索引是怎样的?

HBase 原生不支持二级索引,但可通过以下方案实现类似功能:

1. 协处理器(Coprocessor)

  • Observer:在数据写入时同步更新索引表。
  • Endpoint:自定义聚合逻辑,但需维护索引一致性。
  • 优点:实时性强,索引与数据同步更新。
  • 缺点:增加写入延迟,索引表可能成为瓶颈。

2. 外部索引表

  • 手动创建独立表存储索引数据(如行键与索引列的映射)。
  • 优点:灵活性高,支持复杂查询。
  • 缺点:需应用层维护一致性,双写可能引入数据不一致。

3. Phoenix

  • 基于 HBase 的 SQL 层,内置全局二级索引(Global Index)和本地索引(Local Index)。
  • 全局索引:独立表存储索引,适合读多写少场景。
  • 本地索引:与数据表共址,写性能更优。

4. Elasticsearch 集成

  • 通过工具(如 Lily)将 HBase 数据同步到 Elasticsearch,利用其全文检索能力。

HBase 的 RegionServer 宕机以后怎么恢复?

恢复流程

  1. 故障检测:ZooKeeper 通过心跳机制检测 RegionServer 宕机,通知 HMaster。
  2. Region 重新分配:HMaster 将宕机节点上的 Region 标记为未分配,并重新分配到其他活跃 RegionServer。
  3. WAL 回放:从 HDFS 读取宕机节点的 WAL 日志,按时间顺序重放未持久化的操作(MemStore 中的数据)。回放完成后,新 RegionServer 对外提供服务。

关键机制

  • WAL 持久化:所有写入操作先记录到 HDFS,确保故障后数据不丢失。
  • Region 副本(可选):HBase 2.0+ 支持 Region 多副本,缩短故障恢复时间。

影响与优化

  • 恢复时间:取决于 WAL 日志大小和网络带宽。
  • 预写日志分割:HMaster 将 WAL 按 Region 切分,并行回放以加速恢复。
  • 避免数据倾斜:合理设计行键,防止单个 RegionServer 负载过重。

HBase 的一个 region 由哪些东西组成?

在 HBase 中,Region 是数据存储和管理的核心单元,每个 Region 对应表中连续的一段行键范围(例如从 row1row100)。其组成结构如下:

  1. Store:每个 Region 按列族(Column Family)划分为多个 Store。例如,若表有 info 和 data 两个列族,则 Region 会包含两个 Store。Store 是物理存储的最小单位,负责管理内存和磁盘数据。
  2. MemStore:每个 Store 对应一个 MemStore(写缓存),用于暂存写入数据。数据写入时先进入 MemStore,排序后刷写到磁盘形成 HFile。
  3. HFile:存储在 HDFS 上的数据文件,采用 LSM 树结构,包含多级索引(如 Bloom Filter 和 Block Index)以加速查询。每个 Store 可能有多个 HFile,后台通过合并(Compaction)优化文件数量和大小。
  4. WAL(预写日志):虽然 WAL 由 RegionServer 全局管理,但每个 Region 的写入操作会记录到 WAL,用于故障恢复。
  5. Region 元数据:包括行键范围、所属表、列族配置等信息,存储在 HBase 的 Meta 表中。

核心作用

  • 水平扩展:Region 分裂(Split)机制允许数据分布到多台机器。
  • 读写隔离:MemStore 处理写入,HFile 处理读取,通过合并平衡性能。

HBase 高可用怎么实现?

HBase 的高可用性通过以下机制保障:

1. HMaster 高可用

  • 部署多个 HMaster 节点,通过 ZooKeeper 选举机制确保主备切换。
  • 主 HMaster 负责元数据管理,备节点监听状态并在主节点宕机时接管。

2. RegionServer 容错

  • ZooKeeper 心跳检测:实时监控 RegionServer 存活状态,宕机时触发 HMaster 重新分配 Region。
  • WAL 回放:RegionServer 故障后,HMaster 从 HDFS 读取其 WAL 日志,在其他节点重放未持久化的数据。

3. 数据持久化

  • HDFS 多副本:默认 3 副本存储 HFile 和 WAL,防止数据丢失。
  • WAL 同步写入:数据先写入 WAL 再进入 MemStore,确保故障时可恢复。

4. Region 副本(HBase 2.0+)

  • 支持为单个 Region 配置多个副本,分布在不同 RegionServer 上。
  • 主副本处理读写,备副本同步数据,主副本宕机时备副本快速接管。

优化建议

  • 避免单点瓶颈:配置至少 3 个 ZooKeeper 节点和 2 个 HMaster。
  • 合理设置超时参数:如 zookeeper.session.timeout 控制故障检测灵敏度。

为什么 HBase 适合写多读少业务?列式数据库的适用场景和优势是什么?列式存储的特点有哪些?

HBase 写多读少的优势

  • LSM 树优化写入:数据先写入内存(MemStore),批量刷盘减少磁盘随机 I/O。
  • 异步合并:后台 Compaction 将小文件合并为大文件,降低读取时的寻址开销。
  • 高吞吐:顺序写入 HDFS 和 WAL,适合日志、时序数据等写入密集型场景。

列式数据库的适用场景

  • OLAP 分析:需扫描大量行但少量列的聚合查询(如 SUM、AVG)。
  • 稀疏数据:列独立存储,适合字段稀疏或动态增减的场景。
  • 高压缩率:同列数据类型一致,压缩效率更高(如 Run-Length 编码)。

列式存储的核心特点

按列存储

每列数据连续存储,减少读取无关列的数据量。

高效压缩

同列数据重复率高,压缩比显著优于行式存储。

延迟物化

仅读取查询涉及的列,减少 I/O 和内存占用。

向量化处理

批量处理同列数据,充分利用 CPU 缓存和 SIMD 指令。

对比行式存储

  • 写入性能:行式存储更适合频繁插入整行数据的场景(如 OLTP)。
  • 读取性能:列式存储在分析型查询中表现更优。

HBase 的 rowkey 设计原则是什么?HBase 的 rowkey 为什么不能超过一定长度?为什么要唯一?rowkey 太长会影响 Hfile 的存储吗?HBase 的 RowKey 设置讲究的原因是什么?

RowKey 设计原则

  1. 唯一性:RowKey 是数据的唯一标识,重复会导致数据覆盖。
  2. 长度控制:建议 10~100 字节,过长会降低 MemStore 和 HFile 索引效率。
  3. 散列分布:避免连续值(如时间戳)导致热点问题,可采用加盐哈希(如 MD5(username)[0:4] + username)。
  4. 查询友好:将常用查询条件前置(如 userid_actiontime)。

RowKey 长度限制的影响

  • 内存开销:每个 RowKey 会存储在 MemStore 和 BlockCache 中,过长会挤占内存空间。
  • HFile 索引膨胀:HFile 的 Bloom Filter 和 Block Index 需记录 RowKey 前缀,长度增加会降低索引效率。
  • 网络传输:RegionServer 需在 RPC 中传递 RowKey,过大会增加序列化开销。

RowKey 必须唯一的原因

  • HBase 中相同 RowKey 的多次写入会视为更新操作,旧版本数据可能被覆盖(取决于版本数配置)。

设计 RowKey 的深层考量

  • 负载均衡:良好的 RowKey 设计可避免 RegionServer 热点,例如将随机前缀(如 hash(userid) % 100)加入 RowKey。
  • 查询性能:RowKey 是唯一全局有序索引,设计需匹配业务查询模式(如范围扫描或精确查询)。

HBase 的大合并、小合并是什么?大合并是如何做的?为什么要大合并?

小合并(Minor Compaction)

  • 触发条件:单个 Store 的 HFile 数量达到阈值(如 hbase.hstore.compactionThreshold=3)。
  • 操作过程:将相邻的多个小 HFile 合并为一个更大的 HFile,减少读取时的文件寻址次数。
  • 特点:仅合并文件,不处理删除标记或过期数据,I/O 开销较低。

大合并(Major Compaction)

  • 触发条件:周期性触发(默认 7 天)或手动执行。
  • 操作过程: 将一个 Store 的所有 HFile 合并为一个新 HFile。清理墓碑标记(Tombstone) 和过期版本数据,释放磁盘空间。更新 HFile 的元数据和索引。
  • 特点:I/O 和计算密集型操作,可能影响集群性能,需避开业务高峰期。

大合并的必要性

  1. 空间回收:物理删除标记数据,避免存储浪费。
  2. 查询优化:减少读取时需要扫描的文件数量,提升性能。
  3. 数据一致性:确保多版本数据和删除操作最终生效。

优化建议

  • 自动合并策略:根据业务负载调整合并周期和触发条件。
  • 分时调度:在低峰期触发 Major Compaction。
  • 关闭自动 Major Compaction:在写入密集场景中手动控制合并时机。

HBase 和关系型数据库(传统数据库)的区别(优点)有哪些?

HBase 与传统关系型数据库(如 MySQL、Oracle)在设计目标适用场景上存在显著差异,核心区别如下:

1. 数据模型差异

  • HBase:基于列族存储,数据按行键(RowKey)和列族组织,支持动态列和稀疏数据。
  • 关系型数据库:基于行存储,数据按预定义的表结构和固定列存储,适合结构化数据。

2. 扩展性与性能

  • HBase: 水平扩展:通过增加 RegionServer 节点轻松扩展至 PB 级数据。高写入吞吐:LSM 树结构优化写入,适合日志、时序数据等写多读少场景。
  • 关系型数据库: 垂直扩展:通常通过升级硬件(如 CPU、内存)提升性能,扩展成本高。强事务支持:支持 ACID 事务,适合需要复杂事务的业务(如银行系统)。

3. 查询能力

  • HBase: 仅支持单行事务和基于 RowKey 的范围扫描(Scan)。无原生 SQL 支持,需通过 API 或 Phoenix 等工具实现类 SQL 查询。
  • 关系型数据库: 支持复杂查询(如 JOIN、子查询)、聚合函数和二级索引。提供标准 SQL 接口,开发门槛低。

4. 一致性模型

  • HBase:强一致性(基于 HDFS 多副本和 WAL)。
  • 关系型数据库:强一致性(通过锁和事务机制)。

5. 适用场景对比

数据规模

海量数据(TB/PB 级)

中小规模(GB/TB 级)

读写模式

写多读少,高吞吐写入

读写均衡,低延迟事务

灵活性

动态列,无需预定义模式

固定表结构,需预先设计

HBase 数据结构是怎样的?为什么 HBase 随机查询很快?

HBase 数据结构

  • 逻辑视图:数据按行键(RowKey) 全局有序排列,每行包含多个列族(Column Family)。列族下包含多个列限定符(Qualifier),每个单元格(Cell)可存储多个版本的数据。
  • 物理存储:数据按 Region 分片存储,每个 Region 包含多个 Store(对应一个列族)。Store 由 MemStore(内存) 和 HFile(磁盘) 组成,写入数据先进入 MemStore,刷盘后生成 HFile。

随机查询快的原因

  1. RowKey 有序性:数据按 RowKey 排序存储,通过 Region 分区和 HFile 索引快速定位目标数据块。
  2. 多级缓存机制:BlockCache:缓存频繁访问的 HFile 数据块(如 Bloom Filter),减少磁盘 I/O。MemStore:最新写入数据可直接从内存读取,无需访问磁盘。
  3. Bloom Filter:快速判断某 RowKey 是否存在于 HFile 中,避免无效的磁盘扫描。
  4. LSM 树优化:通过 Compaction 合并小文件,减少读取时需要访问的 HFile 数量。

HBase 的 LSM 结构是怎样的?HBase 的 Get 和 Scan 的区别和联系是什么?

LSM 结构解析

  • 写入流程:数据先写入 MemStore(内存),同时记录到 WAL(预写日志)。MemStore 达到阈值后,数据刷写到 HDFS 生成 HFile(有序键值存储)。后台 Compaction 合并 HFile,减少文件数量并清理过期数据。
  • 读取流程:依次检查 BlockCache → MemStore → HFile,合并结果返回客户端。

Get 与 Scan 的对比

查询类型

单行精确查询

多行范围扫描

性能

毫秒级延迟(利用索引和缓存)

依赖扫描范围,可能涉及多个 Region

使用场景

基于 RowKey 的实时查询

数据分析、全表扫描

资源消耗

低(单行数据)

高(大量 I/O 和网络传输)

联系

  • 两者均基于 RowKey 的有序性实现高效查询。
  • Scan 可视为多次 Get 的批量操作,但需注意设置合理的 cachingbatch 参数以减少开销。

HBase 数据的存储结构(底层存储结构)是怎样的?HBase 数据 compact 流程是怎样的?

底层存储结构

  • HFile:实际存储在 HDFS 上的文件,结构如下: Data Block:存储键值对,默认大小 64KB。Meta Block:存储 Bloom Filter 等元数据。Trailer:记录索引和元数据的偏移量。采用 KeyValue 格式,每个条目包含 RowKey、列族、列限定符、时间戳和值。
  • WAL(预写日志):记录所有写入操作,用于故障恢复,存储在 HDFS 上。

Compaction 流程

  1. 触发条件:Minor Compaction:合并相邻的多个小 HFile 为大文件。Major Compaction:合并所有 HFile 并清理删除数据。
  2. 执行步骤:从 HDFS 读取待合并的 HFile,按 RowKey 排序后合并为新文件。更新元数据,删除旧文件。
  3. 核心作用:减少文件数量,提升读取效率。清理过期版本和墓碑标记,释放存储空间。

HBase 的预分区是怎样的?HBase 的热点问题有哪些?

预分区(Pre-splitting)

  • 目的:避免自动分区导致的数据倾斜(如所有数据集中在单个 Region)。
  • 实现方式: 建表时指定 Split Keys(如 create 'table', 'cf', {SPLITS => ['a', 'b', 'c']})。根据业务数据分布选择合适的分区策略(如哈希、范围划分)。

热点问题

  • 成因:RowKey 设计不当:例如使用连续时间戳作为前缀,导致写入集中在单个 Region。访问模式倾斜:高频访问同一 RowKey 或小范围数据。
  • 解决方案:加盐(Salting):在 RowKey 前添加随机前缀(如 hash(userid) % 100)。哈希化:对自然键(如用户 ID)进行哈希,确保均匀分布。反转时间戳:将时间戳高位反转(如 Long.MAX_VALUE - timestamp),避免新数据集中写入。范围分区:根据业务查询模式设计 RowKey,分散负载。

优化效果

  • 通过预分区和 RowKey 设计,可将数据均匀分布到多个 RegionServer,提升集群吞吐量。

HBase 的 memstore 冲刷条件是什么?HBase 的 MVCC 是怎样的?

MemStore 冲刷条件

MemStore 是 HBase 的写缓存,数据写入时先暂存于此,当满足以下条件时会触发刷写(Flush)到磁盘生成 HFile:

  1. 内存阈值触发:单个 MemStore 大小达到 hbase.hregion.memstore.flush.size(默认 128MB)。
  2. 全局内存限制:RegionServer 所有 MemStore 总大小超过 hbase.regionserver.global.memstore.size(默认堆内存的 40%),此时按 Region 的写入顺序强制刷写。
  3. WAL 文件数量限制:当 WAL 文件数量超过 hbase.regionserver.max.logs(默认 32),触发刷写以减少日志数量。
  4. 手动触发:通过 API 或 HBase Shell 执行 flush 命令主动刷写。

冲刷流程

  • 刷写前会先冻结当前 MemStore,生成新的 MemStore 继续接收写入。
  • 数据按 RowKey 排序后写入 HDFS 生成 HFile,并记录元数据到 HFile 的 Trailer 部分。

MVCC(多版本并发控制)

  • 写入场景:每次写入操作会分配一个递增的版本号(Timestamp),数据以多版本形式存储。
  • 读取场景:读取时根据版本号选择最新可见版本,避免脏读和写阻塞。
  • 实现机制: 写操作:新数据直接追加到 MemStore,旧版本标记为过期但不会立即删除。读操作:扫描 MemStore 和 HFile,过滤掉被后续操作覆盖的旧版本数据。
  • 优势: 读写并发时无需加锁,提升吞吐量。通过 Compaction 清理过期版本,保证存储效率。

既然 HBase 底层数据是存储在 HDFS 上,为什么不直接使用 HDFS,而还要用 HBase?

HDFS 和 HBase 的定位不同,前者是分布式文件系统,后者是分布式数据库,两者的核心差异如下:

HDFS 的局限性

  1. 仅支持批量读写:HDFS 适合顺序访问大文件,无法高效处理随机读写。
  2. 无结构化数据管理:缺少数据索引、版本控制、事务等数据库特性。
  3. 高延迟:读取数据需遍历整个文件,不适合实时查询。

HBase 的核心价值

  1. 随机读写优化:通过 MemStore 和 LSM 树将随机写转换为顺序写,利用 BlockCache 加速读。
  2. 结构化数据模型:支持行键、列族、多版本等特性,提供灵活的数据组织方式。
  3. 高可用与自动扩展:Region 自动分裂和故障转移机制,无需人工干预数据分布。
  4. 实时查询能力:基于 RowKey 的 Get 和 Scan 操作可实现毫秒级响应。

类比场景

  • HDFS 类似“仓库”,适合存储原始日志或备份文件。
  • HBase 类似“货架”,提供分类、索引和快速存取能力。

HBase 和 Phoenix 的区别是什么?HBase 支持 SQL 操作吗?

HBase 的 SQL 支持

  • 原生不支持 SQL:HBase 仅提供 Put、Get、Scan 等 API,需通过代码或工具实现复杂查询。
  • Phoenix 的角色: 作为 HBase 的SQL 中间件,提供 JDBC 接口和类 SQL 语法(如 SELECT、JOIN)。将 SQL 查询转换为 HBase 的 Scan 和 Filter 操作,并优化执行计划。

核心区别

查询语言

API 接口(Java/Python)

ANSI SQL

二级索引

需手动实现

内置全局和本地索引

事务支持

仅行级原子性

跨行事务(实验性)

性能优化

依赖 RowKey 设计

自动优化查询计划

Phoenix 的适用场景

  • 需要复杂查询(如聚合、JOIN)的业务。
  • 希望降低开发门槛,复用现有 SQL 生态。

HBase 适合读多写少还是写多读少?HBase 表设计要注意什么?Region 分配是怎样的?HBase 的 Region 切分是怎样的?

读写场景适配性

  • 写多读少:LSM 树结构优化写入吞吐,适合日志、时序数据等场景。
  • 读多场景:需通过 BlockCache、布隆过滤器和 RowKey 设计提升性能。

表设计要点

  1. RowKey 设计: 避免热点:散列或加盐处理(如 hash(userid) + timestamp)。查询友好:将常用查询条件前置(如 region_userid)。
  2. 列族数量:通常不超过 3 个,过多列族会降低 Compaction 效率。
  3. 数据版本:根据业务需求设置 VERSIONS,避免存储冗余数据。

Region 分配与切分

  • 初始分配:建表时通过预分区(Pre-splitting)手动指定 Split Keys。
  • 自动切分:当 Region 大小达到 hbase.hregion.max.filesize(默认 10GB)时,按中间 RowKey 分裂为两个子 Region。
  • 负载均衡:HMaster 监控 Region 分布,将密集节点的 Region 迁移至空闲节点。

切分影响

  • 优点:分散数据压力,提升并行处理能力。
  • 缺点:分裂期间 Region 短暂不可用,可能引发性能波动。

如何查询散列后的 rowkey?

散列 RowKey 的常见场景是为解决热点问题,例如对原始 RowKey 进行 MD5 或取模运算。查询时需按相同规则处理才能准确定位数据。

查询方法

  1. 精确查询:对查询条件应用相同的散列算法,生成散列后的 RowKey。例如:查询 userid=123,需先计算 hash(123),再执行 Get 操作。
  2. 范围查询:散列后的 RowKey 失去原始顺序,无法直接范围扫描。替代方案: 在应用层存储原始 RowKey 与散列值的映射关系,查询时转换为多个散列区间。使用 Phoenix 的全局索引或本地索引,通过 SQL 条件自动处理散列逻辑。

设计权衡

  • 写入均匀性:散列能分散负载,但增加了查询复杂度。
  • 业务适配:需根据查询模式选择散列算法(如一致性哈希可减少迁移开销)。

示例代码(非实际代码,仅逻辑描述):

# 写入时生成散列 RowKey  
hashed_key = md5(original_key).hexdigest()  
hbase.put(hashed_key, data)  

# 查询时重新计算散列值  
target_hash = md5(query_key).hexdigest()  
result = hbase.get(target_hash)  

HBase/mysql 的主从复制机制是什么?

HBase 和 MySQL 的主从复制机制设计目标不同,分别服务于分布式数据库和传统关系型数据库的需求,其实现方式和应用场景存在显著差异:

HBase 主从复制

  • 核心机制:基于 WAL(Write-Ahead Log) 的异步复制,将主集群(Master)的写入操作同步到从集群(Slave)。
  • 触发条件: 主集群的 RegionServer 将写入操作记录到 WAL。异步线程读取 WAL 并发送到从集群的 RegionServer。
  • 数据流向: 主集群 → ZooKeeper 协调 → 从集群。支持跨数据中心复制(如灾备场景)。
  • 一致性级别:最终一致性,从集群数据可能存在延迟。
  • 配置方式:通过 peer 配置指定从集群地址和复制规则。

MySQL 主从复制

  • 核心机制:基于 binlog(二进制日志) 的异步或半同步复制,主库(Master)将数据变更同步到从库(Slave)。
  • 触发条件: 主库将事务写入 binlog。从库的 I/O 线程拉取 binlog 并写入中继日志(Relay Log)。从库的 SQL 线程重放中继日志。
  • 数据流向:主库 → 从库(单向)。
  • 一致性级别: 异步复制:数据延迟较高,主库宕机可能导致数据丢失。半同步复制:主库提交事务前需至少一个从库确认,降低丢失风险。

对比总结

数据粒度

行级或列族级

事务级(行或语句)

拓扑结构

多主或多从(需手动配置)

一主多从

适用场景

跨数据中心容灾、数据分发

读写分离、负载均衡

故障恢复

依赖 WAL 重放

依赖 binlog 和中继日志

HBase 的三级索引是什么?

HBase 原生仅支持基于 RowKey 的一级索引(即主索引),但通过外部工具或自定义方案可实现二级索引三级索引。这里的“三级索引”通常指以下两种含义:

1. 多层索引结构

  • 一级索引:RowKey 索引,全局有序,直接定位数据。
  • 二级索引:基于列值构建的辅助索引(如通过协处理器实现)。
  • 三级索引:在二级索引基础上进一步聚合或分层,例如: 按时间范围划分的索引(如 日期_用户ID)。联合多列的复合索引(如 品牌_价格_销量)。

2. 基于外部组件的索引

  • Phoenix 全局索引:独立表存储索引数据,支持快速查询。
  • Elasticsearch 集成:将 HBase 数据同步到 ES,利用其倒排索引实现全文检索。
  • HBase+Solr:通过 Lily Indexer 同步数据到 Solr 构建多维索引。

三级索引的典型实现

  • 适用场景:需要同时按多个非 RowKey 字段查询(如 查询某地区价格低于 100 的商品)。
  • 挑战: 数据一致性:需保证索引与主数据同步更新。写入性能:多级索引增加写入延迟和资源消耗。

在定位到 region 的 table 获取数据时,需要打开和读取所有的 hfile 吗?

不需要。HBase 通过以下机制避免全量扫描 HFile,从而提升读取效率:

  1. Bloom Filter:快速判断目标 RowKey 是否存在于某个 HFile 中,跳过无关文件。存储在 HFile 的 Meta Block 中,内存加载后直接使用。
  2. Block Cache:缓存频繁访问的 HFile 数据块(如最近读取的 Data Block)。优先从内存读取,减少磁盘 I/O。
  3. HFile 索引结构:多级索引:包括文件级索引(Trailer 中的 Data Index)和 Block 内的行键索引。通过二分查找或跳跃表定位目标 Data Block。
  4. Compaction 优化:定期合并小文件,减少需要扫描的 HFile 数量。Major Compaction 后,单个列族通常仅保留一个 HFile。

读取流程精简版

  • 从 BlockCache 和 MemStore 查找最新数据。
  • 对 HFile 按时间戳倒序扫描,找到第一个匹配的单元格后终止(版本控制)。

在 HBase 读写流程中,Hlog 的作用是什么?

HLog(预写日志) 是 HBase 实现数据持久化故障恢复的核心组件,其作用贯穿整个读写生命周期:

写入流程中的 HLog

  1. 写入顺序:数据先写入 HLog,再写入 MemStore。
  2. 持久化保证:即使 RegionServer 宕机,未刷盘的数据仍可通过 HLog 恢复。
  3. 日志结构:按时间顺序记录所有 Put、Delete 等操作,存储在 HDFS 上。

故障恢复流程

  1. 检测宕机:ZooKeeper 发现 RegionServer 失联,通知 HMaster。
  2. 重放 HLog: HMaster 从 HDFS 读取宕机节点的 HLog。按 Region 拆分日志,分发到新分配的 RegionServer 回放。
  3. 数据一致性:回放完成后,MemStore 数据与故障前一致。

HLog 的管理

  • 滚动更新:当 HLog 文件大小超过阈值(默认 128MB)或时间到期(默认 1 小时),创建新文件。
  • 失效清理:MemStore 刷盘后,对应的 HLog 可被安全删除。

性能影响

  • 优势:保障数据可靠性,避免写入丢失。
  • 代价:追加写入 HLog 增加少量延迟(可通过异步写入优化)。

17年+码农经历了很多次面试,多次作为面试官面试别人,多次大数据面试和面试别人,深知哪些面试题是会被经常问到。 在多家企业从0到1开发过离线数仓实时数仓等多个大型项目,详细介绍项目架构等企业内部秘不外传的资料,介绍踩过的坑和开发干货,分享多个拿来即用的大数据ETL工具,让小白用户快速入门并精通,指导如何入职后快速上手。 计划更新内容100篇以上,包括一些企业内部秘不外宣的干货,欢迎订阅!

全部评论

相关推荐

评论
1
3
分享

创作者周榜

更多
牛客网
牛客企业服务