在这里插入图片描述

【作者主页】Francek Chen
【专栏介绍】 ⌈ ⌈ 大数据技术原理与应用 ⌋ ⌋ 专栏系统介绍大数据的相关知识,分为大数据基础篇、大数据存储与管理篇、大数据处理与分析篇、大数据应用篇。内容包含大数据概述、大数据处理架构Hadoop、分布式文件系统HDFS、分布式数据库HBase、NoSQL数据库、云数据库、MapReduce、Hadoop再探讨、数据仓库Hive、Spark、流计算、Flink、图计算、数据可视化,以及大数据在互联网领域、生物医学领域的应用和大数据的其他应用。
【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/BigData_principle_application


本文首先简要介绍分布式并行编程,然后介绍分布式并行编程模型 MapReduce 以及它的核心函数 Map 和 Reduce。

一、分布式并行编程

在过去的很长一段时间里,CPU 的性能都遵循“摩尔定律”,大约每隔 18 个月性能翻一番。这意味着不需要对程序做任何改变,仅通过使用更高级的 CPU,程序就可以“享受”性能提升。但是,大规模集成电路的制作工艺已经达到一个极限,从 2005 年开始摩尔定律逐渐失效。人们想要提高程序的运行性能,就不能再把希望过多地寄托在性能更高的 CPU 身上。于是,人们开始借助于分布式并行编程来提高程序的性能。分布式程序运行在大规模计算机集群上,集群中包括大量廉价服务器,可以并行执行大规模数据处理任务,从而获得海量的计算能力。

分布式并行编程与传统的程序开发方式有很大的区别。传统的程序都以单指令、单数据流的方式顺序执行,虽然这种方式比较符合人类的思维习惯,但是这种程序的性能受到单台机器性能的限制,可扩展性较差。分布式并行程序可以运行在由大量计算机构成的集群上,从而可以充分利用集群的并行处理能力,同时通过向集群中增加新的计算节点,可以很容易地实现集群计算能力的扩充。

谷歌最先提出分布式并行编程模型 MapReduce,Hadoop MapReduce 是它的开源实现。谷歌的 MapReduce 运行在分布式文件系统 GFS 上。与谷歌类似,Hadoop MapReduce 运行在分布式文件系统 HDFS 上。相对而言,Hadoop MapReduce 要比 Google 的 MapReduce 的使用门槛低很多,程序员即使没有任何分布式程序开发经验,也可以很轻松地开发出分布式程序并部署到计算机集群中。

二、MapReduce 模型简介

谷歌在 2003—2006 年连续发表了 3 篇很有影响力的文章,分别阐述了 GFS、MapReduce 和 BigTable 的核心思想。其中,MapReduce 是谷歌的核心计算模型。MapReduce 将复杂的、运行于大规模集群上的并行计算过程高度地抽象为两个函数:Map 和 Reduce,这两个函数及其核心思想都源自函数式编程语言。

在 MapReduce 中,一个存储在分布式文件系统中的大规模数据集会被切分成许多独立的小数据集,这些小数据集可以被多个 Map 任务并行处理。MapReduce 框架会为每个 Map 任务输入一个小数据集(分片),Map 任务生成的结果会继续作为 Reduce 任务的输入,最终由 Reduce 任务输出最后结果,并写入分布式文件系统。特别需要注意的是,适合用 MapReduce 来处理的数据集需要满足一个前提条件:待处理的数据集可以分解成许多小的数据集,而且每一个小数据集都可以完全并行地进行处理。

MapReduce 设计的一个理念就是“计算向数据靠拢”,而不是“数据向计算靠拢”。因为移动数据需要大量的网络传输开销,尤其是在大规模数据环境下,这种开销尤为惊人,所以,移动计算要比移动数据更加经济。本着这个理念,在一个集群中,只要有可能,MapReduce 框架就会将 Map 程序就近地在 HDFS 数据所在的节点运行,即将计算节点和存储节点放在一起运行,从而减少节点间的数据移动开销。

Hadoop 框架是用 Java 实现的,但是 MapReduce 应用程序不一定要用 Java 来写。

三、Map 和 Reduce 函数

MapReduce 模型的核心是 Map 和 Reduce 函数,二者都是由应用程序开发者负责具体实现的。MapReduce 编程之所以比较容易,是因为程序员只需要关注如何实现 Map 和 Reduce 函数,而不需要处理并行编程中的其他各种复杂问题,如分布式存储、工作调度、负载均衡、容错处理、网络通信等,这些问题都会由 MapReduce 框架负责处理。

Map 和 Reduce 函数都是以<key,value>作为输入,按一定的映射规则将其转换成另一个或一批<key,value>进行输出(见表1)。

表1 Map和Reduce函数
函数 输入 输出 说明
Map < k 1 k_1 k1, v 1 v_1 v1> List(< k 2 k_2 k2, v 2 v_2 v2>) (1)将小数据集进一步解析成一批<key,value>对,输入Map函数中进行处理(2)每一个输入的< k 1 k_1 k1, v 1 v_1 v1>会输出一批< k 2 k_2 k2, v 2 v_2 v2>,< k 2 k_2 k2, v 2 v_2 v2>是计算的中间结果
Reduce < k 2 k_2 k2,List( v 2 v_2 v2)> < k 3 k_3 k3, v 3 v_3 v3> 输入的中间结果< k 2 k_2 k2,List( v 2 v_2 v2)>中的List( v 2 v_2 v2)表示一批属于同一个 k 2 k_2 k2的value

Map 函数的输入来自分布式文件系统的文件块,这些文件块的格式是任意的,可以是文档格式,也可以是二进制格式。文件块是一系列元素的集合,这些元素也是任意类型的,同一个元素不能跨文件块存储。Map 函数将输入的元素转换成<key,value>形式的键值对,键和值的类型也是任意的,其中,键没有唯一性,不能作为输出的身份标识,即使是同一输入元素,也可通过一个 Map 任务生成具有相同键的多个<key,value>。

Reduce 函数的任务就是将输入的一系列具有相同键的键值对以某种方式组合起来,输出处理后的键值对,输出结果会合并成一个文件。用户可以指定 Reduce 任务的个数(如 n n n个),并通知实现系统。然后主控进程通常会选择一个 Hash 函数,Map 任务输出的每个键都会经过 Hash 函数计算,并根据哈希结果将该键值对输入相应的 Reduce 任务来处理。例如处理键为 k k k的 Reduce 任务的输入形式为< k k k,< v 1 v_1 v1, v 2 v_2 v2,…, v n v_n vn>>,输出为< k k k, V V V>。

下面给出一个简单实例。比如我们想编写一个 MapReduce 程序来统计一个文本文件中每个单词出现的次数,对于表1中的 Map 函数的输入< k 1 k_1 k1, v 1 v_1 v1>,其具体数据就是<某一行文本在文件中的偏移位置,该行文本的内容>。用户可以自己编写 Map 函数处理过程,读取文件中某一行文本后解析出每个单词,生成一批中间结果<单词,出现次数>,然后把这些中间结果作为 Reduce 函数的输入。Reduce 函数的具体处理过程也是由用户自己编写的,用户可以将相同单词的出现次数进行累加,得到每个单词出现的总次数。

小结

本文介绍了分布式并行编程的背景与意义。随着摩尔定律失效,传统单机性能提升受限,分布式并行编程借助大规模计算机集群成为提高计算能力的关键。MapReduce 作为谷歌提出的核心计算模型,将复杂并行过程抽象为 Map 和 Reduce 两个函数,极大地降低了分布式程序开发门槛。其核心理念是“计算向数据靠拢”,减少数据传输开销。Map 函数将输入数据解析为中间键值对,Reduce 函数对相同键的值进行聚合处理。程序员只需实现这两个函数,底层复杂问题由框架自动处理。MapReduce 为海量数据处理提供了高效、易扩展的解决方案。

欢迎 点赞👍 | 收藏⭐ | 评论✍ | 关注🤗

在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐