概述
HDFS全称Hadoop Distributed File System,这名字一听就和hadoop分不开,甚至是hadoop的一部分。hdfs是一个分布式文件系统,在磁盘上面,非常底层,将海量数据分割成块并分散存储在集群的多个节点上,提供高容错性和扩展性。
pom
<!-- hadoop客户端(包括hdfs、yarn、mapReduce等模块) -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-clinet</artifactId>
<version>3.3.6</version>
</dependency>
java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class HDFSExample {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://namenode:8020"); // HDFS地址
FileSystem fs = FileSystem.get(conf);
// 上传本地文件到HDFS
fs.copyFromLocalFile(new Path("/local/file.txt"), new Path("/hdfs/path/file.txt"));
fs.close();
}
}
Yarn和MapReduce
提到hdfs,就不能不提yarn和mapReduce,因为三者是组成hadoop的核心组件。hdfs负责存储数据,当数据需要被处理时,yarn负责调度分配资源,mapReduce则执行具体的计算任务。
YARN(Yet Another Resource Negotiator)
负责资源管理与任务调度。它解耦了资源管理和计算框架,使得Hadoop可以运行多种计算模型(如MapReduce、Spark、Flink等),而不仅限于MapReduce。
MapReduce
是Hadoop早期的分布式计算框架,通过将任务拆分为Map(映射)和Reduce(归约)两个阶段处理数据。但自YARN出现后,MapReduce逐渐成为可选的计算引擎之一,而非唯一选择。
HDFS + YARN + 多种计算框架
Spark与Flink
spark
spark是一个分布式计算框架,比mapReduce更快,因为spark使用内存计算。
spark可以独立运行,也可以与hadoop集成:Spark通常读取HDFS的数据进行计算,结果也可能存回HDFS;资源管理方面,Spark可以部署在YARN上。
那spark不用hdfs呢?能不运行再yarn上面吗?
spark支持多种数据源:本地文件text、csv;关系型数据库mysql;NoSQL数据库hbase;云存储服务S3、oss;流数据源kafka;spark还可以集成hive元数据,读取hive表的数据。
spark也支持多种资源管理:standalone模式,自带轻量级资源管理器,小集群;yarn:通过--master yarn提交任务,支持资源动态分配。
现在嘛,当然是K8s,云原生架构的首选:容器化部署、弹性伸缩。spark的Driver和Executor作为Pod运行。spark任务以Pod形式运行,由K8s调度器分配资源,支持动态Executor调整。通过k8s://协议提交任务。
shell
spark-submit --master k8s://https://<k8s-apiserver> ...
spark集群在k8s上的部署架构:saprk任务运行,比如用shell脚本直接操作hdfs创建st表(外部表)等,一个作业可能用到多个个pod。
flink
flink也是分布式计算框架,这不是巧了嘛。flink支持流处理和批处理。也是可以独立运行,或者与hadoop集成:使用YARN进行资源管理,存储可能用HDFS。
但是同样的,现在也和hadoop没啥关系了。
同样,现在肯定是在k8s上运行了。越来越多的企业将 Flink 部署在 Kubernetes 上,尤其是在混合云或多云架构中。k8s支持原生部署(如通过 Flink Operator)或 Application 模式。
Application 模式:推荐的生产模式,作业与资源绑定,支持动态扩缩容(Flink 1.11+ 特性)。
flink on k8s:
shell
kubectl apply -f filnk-deployment.yaml
flink集群在k8s上的部署架构:flink作业运行,比如流处理,把kafka中的流数据读取出来写入hdfs,也是一个作业甚至能运行在一两百个节点上。
一点对比
flink on k8s和spark on hive:
Iceberg
iceberg是存储层的一部分,用于大型表格式管理?支持ACID事务。iceberg可能依赖hdfs作为底层存储,但是跟yarn、mapreduce就没啥关系了。
除了hdfs,iceberg可以依赖很多底层存储,只要存储系统实现Hadoop的FileSystem接口或兼容S3 API,Iceberg即可使用:
对象存储:Amazon S3、阿里云OSS、Google Cloud Storage等。
分布式文件系统:HDFS、Ceph、Alluxio。
云原生存储:Azure Blob Storage、MinIO。
一点对比
iceberg on hdfs和mysql on 磁盘文件:
一点集成
Iceberg本身是表格式规范,必须通过计算引擎(如Hive、Spark、Flink)才能操作数据。只有自己是个死的,集成了别人,自己身上这些零件才能动起来。
Hive
hive是一个数据仓库工具,可以将结构化的数据文件(hdfs?iceberg?)映射为数据库表,并提供SQL查询功能。hive底层通常用hdfs做存储(就不够灵活了),引擎早期用mapreduce,现在也支持spark(hive on spark?)。
数仓表
hive既然是一个数仓工具,首先就和表离不开关系,常见的数仓分层表大家也都知道:ODS(操作数据存储)、DWD(数据仓库明细)、DWS(数据仓库汇总)、ADS(应用数据服务)。
或者:原始日志 → ODS(贴源层) → DWD(清洗后明细)→ DWS(轻度汇总)→ ADS(应用层报表)
传统的hadoop数仓中者四层表差不多都是hive表,ADS当然可以是redis、ES这些业务好用的了。在这四层表里,还有外部表和内部表的区分。
内部表:由Hive全权管理表的元数据和数据。删除表时,元数据和数据会被同时删除。存储位置默认在Hive的仓库目录(如/user/hive/warehouse)。适合临时数据或Hive独立管理的场景?
sql
CREATE TABLE managed_table (...);
外部表 :仅管理表的元数据,数据存储在用户指定的外部路径(如HDFS自定义路径)。删除表时,只删除元数据,不删除数据。适合与其他工具(如Spark、Flink)共享数据,或需要长期保留数据的场景。
sql
CREATE EXTERNAL TABLE external_table (...) LOCATION '/path/to/data';
上面的四层表里面,只有ODS表是外部表
- ODS层(贴源层/原始数据层) 外部表 ODS层存储从业务系统、日志文件等外部数据源直接导入的原始数据。通常使用外部表,因为: 数据文件可能由外部系统生成或维护(如日志采集工具),需避免误删原始数据。 数据可能被多个团队共享(如数据湖),外部表能确保元数据与数据文件解耦。
- DWD层(明细层/数据仓库明细层) 内部表 DWD层存储经过清洗、转换、规范化后的明细数据,通常使用内部表,因为: 数据完全由数仓内部ETL流程生成,生命周期由数仓管理。 方便优化存储格式(如ORC/Parquet)和分区策略,提升查询性能。
- DWS层(汇总层/多维明细层) 内部表 DWS层存储按主题或维度聚合的汇总数据,通常为内部表,因为: 数据由数仓内部计算生成,生命周期与业务需求强相关。 需要灵活调整存储结构(如分区、分桶)以支持高效查询。
- ADS层(应用层/数据集市层) 内部表 ADS层存储面向报表、分析或API服务的最终结果数据,通常为内部表,因为: 数据完全由数仓内部加工生成,无需依赖外部文件。 需要严格管理存储空间和性能优化。
hive的能力
hive更核心的价值在于将结构化数据映射到分布式存储(如 HDFS),使用户可以用SQL语法处理大规模数据。
核心能力:
数据查询与分析:支持复杂 SQL 查询(聚合、连接、窗口函数等)。
ETL 处理:可通过 HiveQL 实现数据清洗、转换和加载。
元数据管理:通过 Metastore 统一管理表结构和存储位置,方便跨工具(如 Spark、Presto)集成。
执行引擎演变:
早期:HiveQL 会被翻译成 MapReduce 任务,适合离线批处理,但延迟高。
优化后:引入 Tez 和 Spark 作为执行引擎,提升计算效率(如 DAG 优化、内存计算)。
局限性:仍以批处理为主,不适合实时场景(需对比 Flink、Kafka Streams)。
与 SQL 的关系:
HiveQL 兼容 SQL 标准,但扩展了自定义函数(UDF)、分区/分桶优化等特性,支持更复杂的大数据场景。
hive小结
Hive 的设计初衷是降低大数据处理的门槛,通过 SQL 抽象隐藏底层复杂性。虽然它与 Hadoop 生态紧密相关,但仍在持续演进(如 LLAP 实时查询、Iceberg 表格式支持)。
所以学完hdfs来学hive是比较合适的。
几个SQL的比较
- 传统 SQL(MySQL/Oracle等) 定位:面向事务处理(OLTP),强一致性和实时读写。 原理: 存储引擎:基于 B+ 树或 LSM 树,数据存储在本地磁盘或 SSD。 执行引擎:基于火山模型(Volcano Model),逐行处理数据。 事务:支持 ACID,通过锁或 MVCC 实现。 特点: 低延迟响应(毫秒级),适合高频简单查询。 数据规模较小(通常 TB 级以下)。
- Hive SQL 定位:基于 Hadoop 的离线数据仓库(OLAP),适合大规模批量数据处理。 原理: 存储:数据存储在 HDFS 或对象存储(如 S3),列式存储(ORC/Parquet)。 执行引擎:将 SQL 转换为 MapReduce 任务(默认)或 Tez/Spark 任务。 元数据:依赖独立元数据库(如 MySQL)管理表结构。 特点: 高延迟(分钟到小时级),无事务支持。 适合 TB/PB 级历史数据分析,语法兼容传统 SQL(HiveQL)。
- Spark SQL 定位:基于内存计算的混合引擎(批处理 + 微批流处理)。 原理: 执行引擎: 将 SQL 转换为 RDD/DAG 执行,利用内存缓存加速计算。 使用 Catalyst 优化器进行逻辑优化(如谓词下推、列裁剪)。 Tungsten 引擎优化序列化和内存管理。 数据源:支持 HDFS、Hive、JSON、Parquet 等。 流处理:通过 Structured Streaming 实现微批次流计算。 特点: 比 Hive 快 10~100 倍(内存计算),适合迭代算法(如机器学习)。 兼容 Hive 语法,支持 DataFrame API 和 SQL。
- Flink SQL 定位:面向流处理的实时计算引擎(True Streaming)。 原理: 执行引擎: 将 SQL 转换为 DataStream 程序,基于事件驱动的流水线模型。 使用 Calcite 优化器优化逻辑计划,支持增量计算。 状态管理:内置状态后端(State Backend),支持精确一次语义(Exactly-Once)。 时间语义:支持事件时间(Event Time)、处理时间(Processing Time)。 特点: 低延迟(毫秒级),适合实时风控、监控等场景。 统一批处理和流处理(批是流的特例)。
HDFS详解
组成
hdfs的文件块大小是128M。太小会增加一开始的寻址时间,太大磁盘传输时间又太长。
命令
首先,你得有一台跳板机,机器上面有hdfs-client(当然如果是公司的跳板机,肯定会加一些权限类的东西)。
然后,与直接使用linux命令不同的是,需要在命令前加上hdfs dfs。hdfs dfs是直接操作HDFS的命令行工具,例如上传/下载文件、创建/删除目录、查看文件列表、修改权限等。
而且hdfs dfs是专属于HDFS的命令行工具,不能操作其他的存储系统如S3,其他的可能还得用老的命令工具如hadoop fs。
常见的命令:
执行一下看下,可以看出某个路径下的文件或目录,所有用户都有读写和执行的权限,- 表示这是一个目录,flume是目录的所有者,hive是目录所属的组,0 表示目录的大小(目录大小通常都是0),后面有4个日期区分的子目录。
写/读数据流程
写 读
NameNode/SecondNameNode
要搞清楚什么是追加数据,什么是checkponit,什么是临时磁盘文件,什么是小文件。
核心概念:
执行流程:
为什么要设计成这样?设计的巨佬们是怎么考虑的?
做大数据,当然首要考虑的就是数据的完整性、一致性!!!同时,对于一个服务来说,服务的可靠性和性能永远是两个要考虑的点,这两者是有点对立的,好的工程师应该要把它们统一起来。
类似的设计:
HDFS 的元数据管理通过 fsimage(快照) + edits(增量日志) + checkpoint(合并机制) 实现高效恢复与数据安全。类似设计广泛用于分布式系统,核心思想是 "批量快照 + 增量日志",平衡性能与可靠性。
数据完整性
不仅仅要在流程中保障完整性,还有很多设计开发的细节来保障完整性。
校验和机制(Checksum Verification);副本冗余策略(Replication);心跳检测与块报告;客户端验证机制;容错恢复机制;磁盘故障处理;NameNode高可用。