1. HBase
1.1 概念
HBase是构建在Hadoop HDFS之上的分布式NoSQL数据库,采用列式存储模型,支持海量数据的实时读写和随机访问。适用于高吞吐、低延迟的场景,如实时日志处理、在线交易等。
RowKey(行键)
定义:表中每行数据的唯一标识,类似于关系数据库的主键。
特点:数据按 RowKey 的字典序全局排序。
所有查询必须基于 RowKey 或范围扫描(Scan)。
示例:user_123_order_1001
(用户ID + 订单ID)。
Region(区域)
定义:HBase 表的水平分片,每个 Region 存储一段连续的 RowKey 范围。
特点:一个表初始只有一个 Region,随着数据增长自动分裂(如达到 10GB 阈值)。
每个 Region 由一个 RegionServer 管理。
示例:Region 1 存储 [A-M]
的 RowKey,Region 2 存储 [N-Z]
Column Family(列族)
定义:列的逻辑分组,每个列族对应独立的物理存储单元(HFile)。
特点:列族需预先定义,但列(Qualifier)可动态添加。
同一列族的数据存储在一起,优化读取效率。
示例:定义 OrderInfo
和 ProductDetails
两个列族。
1.2 组件
HMaster
角色:集群的管理者,负责元数据操作和协调。
职责:管理表的创建、删除、修改(如列族定义)。
分配 Region 到 RegionServer,并在节点故障时重新分配。
监控所有 RegionServer 的状态(通过 ZooKeeper)。
注意:HMaster 本身不直接处理读写请求,因此 HBase 的高可用性依赖多 HMaster 实例。
RegionServer
角色:数据存储和读写请求的实际处理者。
职责:管理多个 Region(每个 Region 对应表的一部分数据)。
处理客户端的读写请求(如 Put、Get、Scan)。
管理 MemStore(内存缓存)和 HFile(磁盘文件)。
定期执行数据刷写(Flush)和合并(Compaction)。
ZooKeeper
角色:分布式协调服务,维护集群状态和元数据。
职责:管理 HMaster 的选举(避免单点故障)。
监控 RegionServer 的存活状态(通过心跳机制)。
存储 HBase 的元数据(如 hbase:meta 表的位置)。
HDFS
角色:HBase 的底层存储系统。
职责:持久化存储 HFile 数据(每个 HFile 对应一个列族)。
通过多副本机制保障数据可靠性。
1.3 计算流程
写入流程
读取流程
1.4 列族存储与行键的协同关系
物理分离,逻辑聚合:每个列族对应独立的 HFile 文件,但同一行键下的不同列族数据通过行键关联。
假设表结构如下:
RowKey | 列族:Info | 列族:Order |
---|---|---|
user_123 | name: Alice | order_2023: 手机 |
user_456 | name: Bob | order_2023: 电脑 |
列族 Info
和 Order
的数据存储在不同的 HFile 中。
当查询 user_123
的 Info.name
和 Order.order_2023
时,HBase 会通过行键 user_123
定位到对应的 Region,再分别从 Info
和 Order
的 HFile 中读取数据。
1.5 行键设计的核心原则
将高频查询条件作为前缀
示例:若按用户查询为主,行键设计为 用户ID_时间戳。
若按时间范围查询为主,行键设计为 反转时间戳_用户ID(避免热点)。
避免热点问题
错误设计:单调递增的行键(如 timestamp),导致新数据集中写入单个 Region。
改进方案:添加哈希前缀(如 MD5(userID)[0:4]_userID)。
反转时间戳(如 Long.MAX_VALUE - timestamp)。
控制行键长度
行键会冗余存储在每个单元格(Cell)中,过长会浪费存储和内存。
场景1:高效读取(合理行键设计)
需求:查询用户 user_123 的姓名(列族 Info,列 name)。
行键设计:用户ID(如 user_123)。
流程:通过行键 user_123 直接定位到对应的 Region。
在该 Region 的 Info 列族 HFile 中读取 name 列的值。
耗时:毫秒级。
场景2:低效读取(无行键条件)
需求:查询所有用户的 name 列。
问题:未指定行键,需全表扫描。
流程:扫描所有 Region。
遍历每个 Region 的 Info 列族 HFile。
耗时:分钟级到小时级。
1.6 HBase适合实时的原因
写得快:LSM 树(Log-Structured Merge Tree)架构
写入优化:数据先写入内存(MemStore),再异步刷写到磁盘(HFile),避免传统数据库的直接磁盘随机写入。
内存写入速度极快(微秒级),适合高吞吐的实时写入(如每秒百万级写入)。
合并机制:定期将多个小 HFile 合并为大文件(Compaction),平衡读写性能,避免碎片化导致的读取延迟。
写方面,与HIVE对比
数据库 | 写入机制 | 速度特点 |
---|---|---|
HBase | - 数据先写入内存(MemStore),异步刷写到磁盘(HFile)。- 基于LSM树优化写入。 | 高速写入:支持高吞吐(每秒百万级写入),延迟在毫秒级,适合实时写入场景。 |
Hive | - 数据写入本质是向HDFS追加文件(如TextFile、ORC、Parquet)。- 需要格式转换。 | 低速写入:涉及文件格式转换和分布式写入,延迟在分钟级,适合批量加载。 |
读得快:基于 RowKey 的快速随机访问
行键索引:所有数据按 RowKey 全局排序,配合 Bloom Filter 快速判断数据是否存在,减少磁盘扫描。
直接定位 Region:通过 RowKey 快速定位数据所在的 Region,避免全表扫描(例如 Get 操作时间复杂度接近 O(1))。
读方面,与HIVE对比
数据库 | 写入机制 | 速度特点 |
---|---|---|
HBase | - 通过RowKey直接定位Region,利用MemStore和Block Cache加速读取。- 支持随机读。 | 低延迟读取:单行查询为毫秒级,范围扫描(Scan)性能取决于数据量和RowKey设计。 |
Hive | - 通过MapReduce/Tez/Spark执行全表扫描或复杂查询。- 需解析文件格式(如ORC)。 | 高延迟读取:复杂查询通常需要分钟到小时级,适合离线批处理分析。 |
2. ClickHouse
2.1 概念
ClickHouse 是一款开源的列式联机分析处理(OLAP)数据库,专为大规模数据分析和高速查询设计。
2.2 特点
列式存储与数据压缩
列式存储:数据按列存储,相同数据类型连续存放,大幅提升压缩率(如数值列压缩率可达90%以上)。
高效压缩算法:支持LZ4、ZSTD等算法,减少磁盘I/O和存储成本。
向量化查询执行引擎
利用CPU SIMD指令(单指令多数据),一次处理多行数据,提升批量计算效率。
例如:计算1亿行数据的SUM,传统逐行处理需1亿次操作,向量化引擎可能仅需数百万次操作。
分布式架构与并行计算
分片(Sharding):数据水平拆分到多台节点,支持横向扩展。
副本(Replication):通过ZooKeeper实现多副本容灾(最终一致性)。
分布式查询:查询自动路由到相关分片,结果聚合后返回。
实时数据插入与批量导入
高吞吐写入:支持每秒百万级数据插入(适合日志、事件流)。
批量导入:通过INSERT SELECT
、文件导入(如Parquet)快速加载数据。
2.3 横向对比
维度 | ClickHouse | HBase | Hive |
---|---|---|---|
存储模型 | 列式存储(针对分析优化) | 列族存储(半结构化数据) | 行式/列式(依赖文件格式,如ORC) |
查询延迟 | 毫秒到秒级(OLAP场景) | 毫秒级(单行查询) | 分钟到小时级(批处理) |
写入吞吐 | 高吞吐批量写入(适合日志流) | 高吞吐实时写入(适合事务日志) | 低吞吐批量加载(ETL流程) |
数据更新 | 支持批量更新(异步合并) | 支持单行实时更新 | 仅支持覆盖或分区更新 |
典型场景 | 实时分析、宽表聚合、时序数据 | 实时读写、在线查询 | 离线数据仓库、复杂ETL |
SQL支持 | 完整SQL语法(兼容ANSI SQL) | 无原生SQL,需API或Phoenix扩展 | 类SQL(HiveQL),支持复杂查询 |
与 HBase 和 Hive 的协作模式:
HBase:作为实时数据接入层,处理高并发写入和单行查询。
ClickHouse:作为实时分析层,承载复杂聚合和即席查询。
Hive:作为离线数据仓库,处理历史数据批量计算。