> 技术文档 > 大数据计算资源基础知识,以及5个核心技术讲解(hadoop、mapreduce、hive、spark、flink)_hadoop spark hive

大数据计算资源基础知识,以及5个核心技术讲解(hadoop、mapreduce、hive、spark、flink)_hadoop spark hive


数据计算资源基础知识

大数据处理基本背景

大数据处理面临的主要挑战是数据量太大,无法在单台机器上高效处理。因此,需要分布式系统将数据和计算任务分散到多台机器上协同完成。根据处理方式和应用场景的不同,发展出了不同类型的计算资源。

批处理计算资源

背景:最早的大数据处理方式,主要处理已经存储好的大量历史数据。

  • MapReduce

    • 背景:由Google在2004年提出的分布式计算模型,Hadoop是其开源实现
    • 工作原理:将数据处理拆分为\"映射(Map)\"和\"归约(Reduce)\"两个阶段,可以在大量普通计算机上并行处理
    • 适用场景:如每日的销售报表、网站访问日志分析等不需要实时结果的场景
  • Hive

    • 背景:由Facebook开发,为了让不懂编程的数据分析师也能处理大数据
    • 工作原理:提供类SQL语言(HQL)接口,底层转换为MapReduce任务执行
    • 适用场景:数据仓库建设、复杂数据查询、报表生成
  • Spark Batch

    • 背景:为克服MapReduce的局限性而开发,最初由UC Berkeley开发
    • 工作原理:采用内存计算,避免中间结果写入磁盘,大幅提高处理速度
    • 适用场景:需要多次迭代的复杂计算,如机器学习算法训练

流处理计算资源

背景:随着实时性需求的增加,开始出现处理实时数据流的技术。

  • Flink

    • 背景:起源于欧洲的研究项目,后成为Apache顶级项目
    • 工作原理:设计为真正的流处理引擎,以事件为单位处理数据
    • 适用场景:银行交易欺诈实时检测、网站实时用户行为分析
  • Spark Streaming

    • 背景:Spark生态的一部分,为满足实时计算需求而设计
    • 工作原理:将数据流分割成小批次,利用Spark批处理能力处理
    • 适用场景:社交媒体情感分析、物联网数据实时处理
  • Storm

    • 背景:最早由Twitter开发和使用的流处理系统
    • 工作原理:通过\"拓扑\"定义处理流程,保证毫秒级响应
    • 适用场景:实时计数、系统异常监控告警

交互式查询资源

背景:为满足数据分析师对大数据的快速查询需求而产生。

  • Presto/Trino

    • 背景:最初由Facebook开发,为了解决Hive查询速度慢的问题
    • 工作原理:采用内存处理查询,不依赖MapReduce,支持多数据源
    • 适用场景:业务人员即席查询、跨数据源的数据分析
  • Impala

    • 背景:由Cloudera开发,受Google Dremel启发
    • 工作原理:采用MPP(大规模并行处理)架构,直接访问HDFS数据
    • 适用场景:交互式BI工具、数据探索分析
  • Kylin

    • 背景:最初由eBay开发,用于加速OLAP分析
    • 工作原理:预先计算并存储多维数据立方体,实现超快查询
    • 适用场景:销售数据多维分析、用户行为分析报表

机器学习/AI计算资源

背景:随着人工智能的发展,需要专门的框架处理机器学习任务。

  • Spark MLlib

    • 背景:Spark生态的机器学习库,统一在Spark平台上开发
    • 工作原理:利用Spark分布式计算能力,实现常见机器学习算法
    • 适用场景:客户分群、产品推荐、风险评估
  • TensorFlow/PyTorch

    • 背景:分别由Google和Facebook开发的深度学习框架
    • 工作原理:通过计算图或动态图定义模型,支持GPU加速
    • 适用场景:图像识别、语音转文字、自然语言处理、智能客服

弹性计算资源

背景:为优化资源利用率、降低成本而产生的资源调度系统。

  • K8s集群

    • 背景:由Google开源的容器编排平台,现已成为云原生标准
    • 工作原理:管理容器化应用的部署、扩展和运行
    • 适用场景:微服务架构应用、DevOps持续集成部署
  • Yarn集群

    • 背景:Hadoop 2.0引入的资源管理器,解决Hadoop 1.0的资源利用问题
    • 工作原理:负责集群资源分配和作业调度
    • 适用场景:在同一集群上运行多种计算框架(MapReduce、Spark等)

大数据核心技术详解

Hadoop

核心概念

Hadoop是一个开源的分布式计算框架,设计用来处理无法在单台机器上高效处理的大数据。

两大核心组件

  1. HDFS (存储)

    • 分布式文件系统,将大文件分块存储在多台机器上
    • 一个中心管理器(NameNode)和多个存储节点(DataNode)
    • 自动多副本机制确保数据安全
  2. MapReduce (计算)

    • 分布式计算模型,分为Map和Reduce两个阶段
    • Map:将任务分解为小块并行处理
    • Reduce:汇总处理结果

工作原理简图

[大数据] → [HDFS分块存储] → [MapReduce计算]  |  |  [多台服务器] [并行处理]  |  | [自动容错] [结果汇总] → [最终结果]

Hadoop优势

  • 可扩展性:从几台到上千台服务器
  • 容错性:自动处理节点故障
  • 成本效益:可使用普通硬件
  • 生态系统丰富:Hive、HBase、Spark等工具集成

适用场景

  • 日志处理分析
  • 数据仓库建设
  • 搜索引擎索引构建
  • 机器学习数据准备

理解Hadoop就是理解\"分而治之\"的思想——将大问题拆分为小问题并行解决。

MapReduce

核心概念

  • 一种分布式计算模型,由Google在2004年提出
  • 设计用于在大型计算机集群上并行处理海量数据

两大核心阶段

  1. Map阶段

    • 将输入数据分片,每片由一个Mapper处理
    • 每个Mapper输出键值对
    • 例如:文本分割成的形式
  2. Reduce阶段

    • 接收具有相同Key的所有Value
    • 合并计算后输出最终结果
    • 例如:统计

工作原理简图

[输入数据分片] → [Map处理] → [Shuffle] → [Reduce处理] → [结果] |  | | | [多台服务器] [转化为K-V] [分组] [聚合计算]

适用场景

  • 日志分析
  • 搜索索引
  • 数据转换
  • 简单统计计算

编程模型示例

// WordCount示例// WordCount示例 - MapReduce框架下统计文本中单词出现频率的标准实现/* ===== MapReduce工作流程 ===== * 1. 输入分片: HDFS将输入文件分成固定大小的块(通常128MB) * 2. Map阶段: 每个分片由一个Map任务处理,产生中间键值对 * 3. Shuffle阶段: 系统自动对Map输出进行排序、分区、合并,相同key的值被发送到同一个Reducer * 4. Reduce阶段: 对每个key的所有值进行处理,产生最终结果 * 5. 输出: 将Reduce结果写入HDFS */public class WordCount { // Mapper类实现 - MapReduce第一阶段 // Mapper public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> { // 静态常量值1,在所有map调用间共享,避免重复创建对象 private final static IntWritable one = new IntWritable(1); // 可重用的Text对象,避免垃圾回收压力 private Text word = new Text(); // map方法 - 此方法会被框架对每条输入记录调用一次 // 每个map任务会处理一个输入分片(split)的多条记录 //context是一个非常重要的对象,它代表了map或reduce任务的执行h环境,是Mapper/Reducer与MapReduce框架之间的桥梁 public void map(Object key, Text value, Context context) throws IOException, InterruptedException {// 在MapReduce中,map(20, Text(\"Hello Hadoop\"), context) 中的\"20\"是输入键(key),代表该文本行在原始输入文件中的字节偏移量(byte offset)。// 详细解释:// 当MapReduce处理文本文件时,它会:// 将文件分割成行// 对每一行调用一次map方法// 第一个参数是这一行在文件中的起始位置(偏移量)// 例如:// map(0, Text(\"Hello World\"), context) - 第一行从文件的第0个字节开始// map(20, Text(\"Hello Hadoop\"), context) - 第二行从文件的第20个字节开始(假设第一行加上换行符共20字节)// 在实际的map函数实现中:// 这个偏移量很少被直接使用,大多数WordCount实现中会忽略它// 它的主要作用是提供数据来源的位置信息,在某些应用中可能有用// 对于WordCount,我们只关心文本内容(map方法的第二个参数)// 这就是为什么Mapper类通常定义为Mapper,而不是Mapper,因为通常不关心这个偏移量的具体类型,只把它视为一个Object。 /* Map阶段核心逻辑: * 1. 接收键值对, * 2. 处理并输出中间结果 * 3. MapReduce框架会收集所有Mapper输出 */ StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); // 输出键值对到Context,将触发Partitioner将数据发送到对应的Reducer context.write(word, one); } // Map任务结束后,框架自动进行Shuffle阶段: // - Partitioning: 决定数据发送到哪个Reducer // - Sorting: 按键排序 // - Combining: 可选的本地合并(类似于迷你Reduce) // - Grouping: 将相同key的值分组// IntWritable(1) 中的\"1\"表示单词出现了一次。// 在WordCount算法中,我们的目标是统计每个单词在文本中出现的总次数。处理过程是:// Map阶段:每发现一个单词,就输出(单词, 1)的键值对// 这个\"1\"就是表示\"该单词在当前位置出现了1次\"// 例如处理\"Hello World Hello\"会输出三对:(Hello, 1), (World, 1), (Hello, 1)// Reduce阶段:将同一单词的所有计数值(1)累加// 例如:(Hello, [1,1]) 累加后变成 (Hello, 2) } } // Reducer类实现 - MapReduce第三阶段 // Reducer public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> { private IntWritable result = new IntWritable(); // reduce方法 - 框架为每个唯一的key调用一次此方法 public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { /* Reduce阶段核心逻辑: * 1. 接收来自Shuffle阶段的 * 2. 聚合计算得到 * 3. 输出最终结果 */ int sum = 0; // 遍历该key的所有值(被框架分组后的) for (IntWritable val : values) { sum += val.get(); } result.set(sum); // 输出最终结果到HDFS context.write(key, result); } } /* 完整作业配置(通常在main方法中): * Job job = Job.getInstance(conf, \"word count\"); * job.setJarByClass(WordCount.class); * job.setMapperClass(TokenizerMapper.class); * job.setCombinerClass(IntSumReducer.class); // 优化: 使用Combiner减少网络传输 * job.setReducerClass(IntSumReducer.class); * job.setOutputKeyClass(Text.class); * job.setOutputValueClass(IntWritable.class); * FileInputFormat.addInputPath(job, new Path(args[0])); * FileOutputFormat.setOutputPath(job, new Path(args[1])); * System.exit(job.waitForCompletion(true) ? 0 : 1); */}

优缺点

  • 优点

    • 高度容错性
    • 适合大规模数据处理
    • 编程模型简单
  • 缺点

    • 性能较慢(磁盘IO频繁)
    • 不适合迭代计算和实时处理
    • 编程复杂度高

Hive

  • 核心概念

    • 构建在Hadoop上的数据仓库工具
    • 提供类SQL接口(HiveQL)处理结构化数据
    • 自动将SQL转换为MapReduce作业执行

    主要组件

    1. 元数据存储

      • 保存表结构、分区等信息
      • 通常存储在关系数据库中
    2. 查询处理器

      • 解析HiveQL语句
      • 生成执行计划
      • 优化查询
    3. 执行引擎

      • MapReduce (传统)
      • Tez/Spark (优化)

    工作原理简图

    [HiveQL查询] → [解析和优化] → [转换为MapReduce] → [执行] → [结果] |  | |  | [类SQL语法] [生成计划] [物理执行] [返回数据]

    适用场景

    • 数据仓库
    • 报表生成
    • 离线数据分析
    • 结构化数据查询

HiveQL示例

-- HiveQL示例 - 将SQL语句转换为MapReduce作业执行/* ===== Hive查询执行流程 ===== * 1. 解析: HiveQL被解析成抽象语法树(AST) * 2. 语义分析: 验证表、列是否存在,类型检查 * 3. 逻辑计划生成: 转换为操作符树 * 4. 优化: 应用各种规则优化查询计划 * 5. 物理计划生成: 转换为MapReduce/Tez/Spark作业 * 6. 执行: 在集群上运行生成的作业 */-- 创建表 - 定义数据结构和存储格式CREATE TABLE page_views ( user_id STRING, -- 用户ID timestamp INT, -- 访问时间戳 page_url STRING, -- 页面URL referrer_url STRING -- 来源URL)-- 定义存储格式 - 这会影响Hive如何读取数据ROW FORMAT DELIMITED -- 行格式为分隔符文本FIELDS TERMINATED BY \'\\t\'; -- 字段间用制表符分隔/* 表创建过程: * 1. 元数据存储: 表定义存入Metastore(通常是MySQL等关系数据库) * 2. 不会移动或处理实际数据,只创建元数据 */-- 分析查询 - 此SQL将被转换为MapReduce作业SELECT user_id, -- 输出字段1 COUNT(DISTINCT page_url) AS page_count -- 聚合计算FROM page_views -- 输入表WHERE timestamp > 1420070400  -- 过滤条件GROUP BY user_id -- 分组字段HAVING page_count > 10; -- 分组后过滤/* 查询转换为MapReduce过程: * 1. Map阶段: * - 读取表数据并应用WHERE过滤(timestamp > 1420070400) * - 提取需要的字段(user_id, page_url) * - 输出键值对 * * 2. Shuffle: * - 按user_id分区和排序 * - 相同user_id的所有page_url分组在一起 * * 3. Reduce阶段: * - 计算每个user_id下不同page_url的数量 * - 应用HAVING过滤(page_count > 10) * - 输出最终结果 * * 注: 复杂查询可能会转换为多个MapReduce作业串联执行 */

特点

  • 适合批处理查询分析
  • 支持复杂的ETL流程
  • 类SQL语法降低了学习门槛
  • 查询延迟较高,不适合低延迟应用

Spark

  • 核心概念

    • 快速通用的分布式计算引擎
    • 内存计算,比MapReduce快10-100倍
    • 支持批处理、流处理、机器学习等多种计算

    主要组件

    1. Spark Core

      • RDD (弹性分布式数据集)
      • 内存计算框架
      • 任务调度
    2. 生态系统

      • Spark SQL:结构化数据处理
      • Spark Streaming:实时数据处理
      • MLlib:机器学习库
      • GraphX:图计算

    工作原理简图

    [数据源] → [创建RDD] → [转换操作] → [触发动作] → [结果] |  |  | |[多种来源] [内存缓存] [惰性操作] [实际计算]

【Spark集群架构】
Driver Program (SparkContext)

↙ ↓ ↘
Executor Executor Executor
(内存) (内存) (内存)
tasks tasks tasks

- Driver程序:包含main函数和SparkContext,负责作业调度- Executor:在工作节点上执行具体任务的进程- Task:被送到Executor上执行的最小工作单元### Spark优势- **速度快**:内存计算- **易用性**:支持Java、Scala、Python、R- **统一平台**:一个框架满足多种需求- **丰富生态**:可无缝对接多种数据源### 适用场景- **日志分析**:分析网站访问日志,计算PV/UV- **推荐系统**:基于用户行为构建推荐模型- **实时监控**:处理传感器实时数据,检测异常- **ETL处理**:数据清洗、转换和加载- **机器学习**:训练预测模型,如客户流失预测### 优缺点- **优点**:- 高性能(内存计算)- 多语言支持(Java, Scala, Python, R)- 统一的多种应用场景支持- 丰富的算子和API- **缺点**:- 内存管理复杂- 调优难度大- 对内存需求高### Spark核心编程模型#### 1. RDD (弹性分布式数据集)```scala// 创建RDDval lines = sc.textFile(\"hdfs://...\")// 转换操作(Transformation)val words = lines.flatMap(_.split(\" \"))val pairs = words.map(word => (word, 1))val wordCounts = pairs.reduceByKey(_ + _)// 行动操作(Action)wordCounts.collect()

特点:

  • 分区(Partitioned):数据分布在集群多个节点
  • 不可变(Immutable):创建后不能修改
  • 弹性(Resilient):失败自动恢复
  • 延迟计算(Lazy Evaluation):转换操作不立即执行
2. DataFrame和Dataset
// DataFrame示例val df = spark.read.json(\"customer.json\")df.filter($\"age\" > 25).groupBy(\"city\").count()// Dataset示例case class Person(name: String, age: Int)val ds = spark.read.json(\"people.json\").as[Person]ds.filter(_.age > 25).show()

优势:

  • 结构化数据处理
  • 优化执行计划
  • 与SQL无缝集成

Spark与其他技术对比

【执行速度对比】MapReduce处理10TB数据: ~1小时30分钟Spark处理10TB数据: ~10分钟【迭代计算】MapReduce: 每次迭代都要读写HDFSSpark: 中间结果保留在内存中

Spark编程示例

1. WordCount实现对比
// MapReduce实现public void map(Object key, Text value, Context context) { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); }}public void reduce(Text key, Iterable<IntWritable> values, Context context) { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result);}
// Spark实现val wordCounts = sc.textFile(\"hdfs://...\") .flatMap(line => line.split(\" \")) .map(word => (word, 1)) .reduceByKey(_ + _) wordCounts.saveAsTextFile(\"hdfs://...\")
2. Spark SQL查询
// 注册临时表df.createOrReplaceTempView(\"people\")// 执行SQL查询val teenagersDF = spark.sql(\"SELECT name FROM people WHERE age BETWEEN 13 AND 19\")

Spark生态系统

1. 主要组件
  • Spark Core:基础计算引擎
  • Spark SQL:SQL和结构化数据处理
  • Spark Streaming:实时数据处理
  • MLlib:机器学习库
  • GraphX:图计算引擎
2. 数据源支持
  • 文件格式:Text, CSV, JSON, Parquet, ORC, Avro等
  • 数据库:HDFS, HBase, MySQL, MongoDB等
  • 消息队列:Kafka, Flume等

Flink

基本概念

  • 真正的流处理框架,由欧洲研究项目发展而来
  • 同时支持批处理和流处理
  • 以\"无界数据流\"为核心设计理念

架构特点

  • JobManager:协调任务分配和检查点
  • TaskManager:执行任务的工作节点
  • 事件时间处理:支持按数据生成时间而非处理时间处理
  • 状态管理:支持强一致性的有状态计算

处理模型

  • 数据流:所有数据都被视为流
  • 窗口操作:可以在流上定义时间窗口
  • 检查点机制:保证故障恢复时的一致性

代码示例

// Flink流式WordCount - 实时统计数据流中的词频/* ===== Flink流处理模型 ===== * 1. 数据源(Source): 从外部系统读取数据流 * 2. 转换(Transformation): 对数据流进行处理 * 3. 接收器(Sink): 将结果写入外部系统 * 4. 执行: 惰性评估,构建执行图后整体优化执行 * 5. 状态管理: 维护计算状态并支持容错 */// 创建源(Source) - 从TCP套接字读取文本流// socketTextStream包含4个参数: 主机名、端口、分隔符、最大尝试次数DataStream<String> text = env.socketTextStream(\"localhost\", 9999);// 定义转换操作链DataStream<Tuple2<String, Integer>> counts = text // 转换1: flatMap - 将每行文本分割成单词并输出(单词,1)的二元组 .flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() { /* 流处理特点: * - 一次处理一个事件(此处是一行文本) * - 立即产生输出,不等待批次完成 */ @Override public void flatMap(String value, Collector<Tuple2<String, Integer>> out) { // 对每个输入字符串应用分词 for (String word : value.split(\"\\\\s\")) { // 收集器输出(类似于生产者-消费者模式) out.collect(new Tuple2<>(word, 1)); } } }) // 转换2: keyBy - 按单词分组,创建KeyedStream // keyBy与Spark的groupByKey类似,但Flink会维护状态而不是收集所有数据 .keyBy(0) // 按元组第一个字段(单词)分组 // 转换3: sum - 对分组后的流计算滚动总和 // 这涉及有状态计算: // - 为每个key维护一个状态 // - 每当新事件到来,更新对应key的状态 // - 自动处理状态持久化和恢复 .sum(1); // 累加元组第二个字段(计数)/* 流式处理区别于批处理: * 1. 无界数据: 流是无限的,不像批处理有明确的开始和结束 * 2. 实时处理: 数据到达即处理,延迟通常为毫秒级 * 3. 状态管理: 需要维护计算状态(如每个单词当前的计数) * 4. 容错机制: 通过检查点(Checkpoint)保证精确一次处理语义 */// 定义接收器(Sink) - 将结果输出到控制台// 在生产环境中,通常会输出到Kafka、数据库等外部系统counts.print(); // print()是一个内置的Sink/* 执行流程: * 1. 以上代码只是构建了执行图,没有实际执行 * 2. 调用env.execute()后,Flink才会: * - 优化执行计划 * - 分配任务到TaskManager * - 建立数据流通道 * - 开始连续处理数据流 */

优缺点

  • 优点

    • 低延迟、高吞吐
    • 精确一次(exactly-once)语义保证
    • 强大的时间处理能力
    • 有状态计算支持
  • 缺点

    • 生态系统相对较新
    • 学习曲线较陡
    • 调优和运维复杂度高

各技术之间的关系

  • Hadoop是基础平台,提供分布式存储(HDFS)和资源管理(YARN)
  • MapReduce是Hadoop上的原生计算模型
  • Hive构建在Hadoop之上,提供数据仓库功能和SQL接口
  • Spark最初也是构建在Hadoop上,但提供了比MapReduce更高效的计算模型
  • Flink是独立的流处理框架,但通常也与Hadoop生态集成

实际应用选择

  • 需要简单批处理:Hadoop MapReduce
  • 需要类SQL分析:Hive
  • 需要混合批处理和机器学习:Spark
  • 需要低延迟流处理:Flink
  • 完整方案通常组合使用多种技术