云计算技术-25fa-zb学习通作业

云计算技术 2025年秋季学期 的学习通作业答案。

本文连载于云计算技术-25fa-zb学习通作业| HeZzz

🙇‍♂️🙇‍♂️🙇‍♂️时间仓促,有不足之处烦请及时告知。邮箱hez2z@foxmail.com 或者在 速通之家 群里 @9¾

云计算概述

阐述云计算的7个特点

  1. 超大规模
  2. 虚拟化
  3. 高可靠
  4. 通用性
  5. 高可伸缩性
  6. 按需服务
  7. 极其廉价

对比分析云计算与其他计算模式(如网格计算、效用计算)的区别

从某种程度来看,网格要做的很多事情也是云计算要做的事情,但网格计算却不能算是云计算。
首先,网格计算主要针对科学计算和仿真,而云计算则是通用的。
其次,网格不考虑交互式终端用户,而云计算要考虑。

效用计算是随着主机的发展而出现的。考虑到主机的购买成本高昂,一些用户只能租用,而不是购买。千是有人提出了效用计算的概念,目标是把服务器及存储系统打包给用户使用,按照用户实际使用的资源晁对用户进行计费。这种模式类似于水、电、气和电话等服务的提供方式,使用户能够像把灯泡插入灯头一样来使用计鍔机资源。这种模式使用户无须为使用服务去拥有资源的所有权,而是去租资源。效用计算是云计算的前身。

云计算可以很简要地概括为 IaaS、PaaS、SaaS,也就是基础设施即服务、平台服务、软件服务。其中基础设施即服务可称为效用计算(Utility Computing),平台即服务可称为弹性计算(Elastic Computing),软件即服务可称为随需应用(On-demand Applications)。

即云计算是由网格计算、效用计算以及其他计算模式发展而来的。

计算系统是如何演变成今天的云计算的?

概括来说,云计算是各种虚拟化、效用计算、服务计算、网格计算、自动计算等概念的混合演进并集大成之结果。它从主机计算开始、历经小型机计算、客户机—服务器计算、分布式计算、网格计算、效用计算进化而来,它既是技术上的突破(技术上的集大成),也是商业模式上的飞跃(用多少付多少,没有浪费)。对于用户来说,云计算屏蔽了 IT 的所有细节,用户无须对云端所提供服务的技术基础设施有任何了解或任何控制,甚至根本不用知道提供服务的系统配置和地理位置及需求,只需“打开开关”(接上网络),坐享其成即可。

由此可见,云计算描述的是一种新的补给、消费、交付 IT 服务的模式,该模式基于互联网协议且不可避免地涉及动态可伸缩且常常是虚拟化了的资源的配置。在某种程度上说,云计算是人们追求对远程计算资源的易访问性的一个副产品。

开源技术是如何促进云计算发展的?

开源技术在云计算的发展中起到了至关重要的作用,主要体现在以下几个方面:

  1. 促进创新:开源技术允许开发者自由地访问和修改源代码,促进了创新和协作。开发者可以基于现有的开源项目进行改进和创新,推动云计算技术的发展。
  2. 提升研发能力:开源技术为云计算提供了丰富的工具和框架,帮助开发者更高效地构建和部署云计算应用。例如,开源的容器化技术(如 Docker 和 Kubernetes)极大地简化了应用的部署和管理。
  3. 定制化开发:开源技术允许用户根据自身需求定制云计算解决方案,满足不同业务场景的需求。这种灵活性使得云计算能够更好地适应各种行业和应用。
  4. 吸引优秀开发者:开源社区吸引了大量优秀的开发者参与到云计算技术的研发中,推动了技术的不断进步和完善。
  5. 成本降低:优秀的开源工具和框架的使用,降低了云计算的研发和运营成本,使得更多企业能够负担得起云计算服务。

云计算按照部署方式和服务类型分别分成哪几类?

  1. 按照部署方式分类
    • 公有云
    • 私有云
    • 社区云
    • 混合云
    • 行业云
    • 其他云类型
  2. 按照服务类型分类
    • 基础设施即服务(Infrastructure as a Service, IaaS)
      在这个层面,服务提供商提供的基本单元就是服务器。
    • 平台即服务(Platform as a Service, PaaS)
      在这个层面,服务提供商提供的是经过封装的IT能力,或者是一些逻辑的资源,例如数据库、文件系统和应用运行环境等。主要面向软件开发者。
    • 软件即服务(Software as a Service, SaaS)
      在这个层面,提供的基本单元是应用软件。这类服务既有面向普通用户的,诸如 Google Calendar 和 Gmail,有直接面向企业团体的,用于帮助处理工资单流程、人力资源管理、协作、客户关系管理和业务合作伙伴关系管理等,例如Salesforce.com 和 SugarCRM。这些 SaaS 提供的应用程序减少了客户安装与维护软件的时间及其对技能的要求,并且可以通过按使用付费的方式来减少软件许可证费用的支出。

HDFS 作业

阅读《Hadoop: The Definitive Guide》,回答以下问题

DataNode 失效

Q: 写数据的过程中,Pipeline 上的一个 DataNode 失效了,HDFS如何处理?

A:

如果 NameNode10分钟没有收到 DataNode(以下简称 “DN”) 的心跳,则任务该 DN 已经丢失,并复制其上保存的数据块到其他 DN。

  • 存储数据块(Block)
  • 启动 DN 线程时,向 NN 汇报保存的数据块信息。
  • 通过向 NN 发送心跳保持与其联系(3秒一次),包括 DN 的负载信息。
  • 如果 NN 10分钟没有收到 DN 的心跳,则任务该 DN 已经丢失,并复制其上保存的数据块到其他 DN。

数据完整性

Q: HDFS 如何保证数据的完整性(Data Integrity)?

A:

主要有以下 6 点:

  1. 安全模式:
    HDFS 刚启动时,NameNode 进入安全模式,处于安全模式的 NameNode 不能做任何的文件操作,甚至内部的副本创建也是不允许的,NameNode 此时需要和各个 DataNode 通信,获得 DataNode 存储的数据块信息,并对数据块信息进行检查,只有通过了 NameNode 的检查,一个数据块才被认为是安全的。当认为安全的数据块所占比例达到了某个阈值,NameNode才会启动。

  2. SecondaryNameNode:
    Hadoop 中使用 SecondaryNameNode 来备份 NameNode 的元数据,以便在 NameNode 失效时能从 SecondaryNameNode 恢复出 NameNode 上的元数据。SecondaryNameNode 充当NameNode 的一个副本,它本身并不处理任何请求,因为处理这些请求都是 NameNode 的责任。

    NameNode 中保存了整个文件系统的元数据,而 SecondaryNameNode 的作用就是周期性(周期长短也可配)保存 NameNode 的元数据。这些源数据中包括文件镜像数据 FSImage和编辑日志 EditLog。FSImage 相当于 HDFS 的检查点,NameNode 启动时候会读取 FSImage 的内容到内存,并将其与 EditLog 日志中的所有修改信息合并生成新的 FSImage;在 NameNode 运行过程中,所有关于 HDFS 的修改都将写入 EditLog。这样,如果 NameNode 失效,可以通过 SecondaryNameNode 中保存的 FSImage 和 EditLog 数据恢复出 NameNode 最近的状态,尽量减少损失。

  3. 心跳机制和副本重新创建:
    为了保证 NameNode 和各个 DataNode 的联系,HDFS 采用了心跳机制。位于整个 HDFS 核心的 NameNode,通过周期性的活动来检查 DataNode 的活性,像跳动的心脏一样。NameNode 周期性向各个 DataNode 发送心跳包,而收到心跳包的 DataNode 要进行回复。因为心跳包是定时发送的,所以 NameNode 就把要执行的命令也通过心跳包发送给 DataNode,而DataNode 收到心跳包,一方面回复 NameNode,另一方面就开始了用户或者应用的数据传输。

    如果侦测到 DataNode 失效,NameNode 之前保存在这个 DataNode 上的数据就变成不可用数据。如果有的副本存储在失效的 DataNode 上,则需要重新创建这个副本,放到另外可用的地方。

  4. 数据一致性:
    一般来讲,DataNode 与应用交互的大部分情况都是通过网络进行的,而网络数据传输带来的一大问题就是数据是否原样到达。为了保证数据的一致性,HDFS 采用了数据校验和(CheckSum)机制。创建文件时,HDFS 会为这个文件生成一个校验和,校验和文件和文件本身保存在同一空间中。传输数据时会将数据与校验数据和一同传输,应用收到数据后可以进行校验,如果两个校验的结果不同,则文件肯定出错了,这个数据块就变成无效的。如果判定无效,则需要从其他 DataNode 上读取副本。

  5. 租约:
    在 linux 中,为了防止多个进程向同一个文件写数据的情况,采用了文件加锁的机制。而
    在 HDFS 中,同样需要一个机制来防止同一个文件被多个人写入数据。这种机制就是租约
    (Lease),每当写入数据之前,一个客户端必须获得 NameNode 发放的一个租约。NameNode
    保证同一个文件只发放一个允许写的租约。那么就可以有效防止多人写入的情况。

  6. 回滚:
    HDFS 安装或升级时,会将当前的版本信息保存起来,如果升级一段时间内运行正常,可
    以认为这次升级没有问题,重新保存版本信息,否则,根据保存的旧版本信息,将 HDFS 恢
    复至之前的版本。

SequenceFile 实现多个小文件存储

DFS针对大数据文件来设计,处理小文件效率低。阅读『File-Based Data Structures』中关于『Hadoop’s SequenceFile』的介绍。编写代码,使用『 SequenceFile 』实现多个小文件的存储。要求如下:

1、开发环境:Intellj IDEA + MAVEN,JDK 1.8, Hadoop 2.9.2

2、写文件:输入:100张图片的文件夹,输出:包含所有图片的SequenceFile格式文件

3、读文件:输入:包含所有图片的SequenceFile格式文件,输出:所有图片。

分布式计算作业

什么是ACID原则?

ACID 是数据库事务正常执行的四个原则,分别指原子性、一致性、独立性及持久性。

  1. A (Atomicity) — 原子性
    原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做。事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。例如银行转账,从 A 账户转 100 元至 B 账户,分为两个步骤:先从 A 账户取 100 元;再存入 100 元至 B 账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了 100 元。

  2. C (Consistency) — 一致性
    一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。例如现有完整性约束 a + b = 10,如果一个事务改变了 a,那么必须得改变 b,使得事务结束后依然满足 a + b = 10,否则事务失败。

  3. I (Isolation) — 独立性
    所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。例如交易是从 A 账户转 100 元至 B 账户,在这个交易还未完成的情况下,如果此时 B 查询自己的账户,是看不到新增加的 100 元的。

  4. D (Durability) — 持久性
    持久性是指一旦事务提交后,它所做的修改将会永久保存在数据库上,即使出现宕机也不会丢失。这些原则解决了数据的一致性、系统的可靠性等关键问题,为关系数据库技术的成熟以及在不同领域的大规模应用创造了必要的条件。数据库 ACID 原则在单台服务器就能完成任务的时代,很容易实现,但是现在面对如此庞大的访问量和数据量,单台服务器已经不可能适应了,而 ACID 在集群环境几乎不可能达到人们的预期,要保证 ACID,效率就会大幅度下降,而且为了达到这么高的要求,系统很难扩展,因此就出现了 CAP 理论和 BASE 理论。

CAP

Q:CAP 定理中的几个关键因素为什么不能同时保证?不同的组合有什么样的应用场景?

A:

一个分布式系统最多只能同时满足一致性 (Consistency) 、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。

  1. 为什么不能同时保证三个因素?

    CAP 定理指出分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)这三项中的两项。这个限制源于分布式系统的本质矛盾。

    在分布式系统中,网络分区是不可避免的现实问题。当网络发生故障导致节点之间无法通信时,系统面临一个根本性的选择困境:如果要保证一致性,就必须拒绝某些请求或等待网络恢复,这会牺牲可用性;如果要保证可用性,允许各个分区独立提供服务,那么不同分区的数据就会出现不一致。这就像一个跷跷板,当你试图保持一端稳定时,另一端必然会受到影响。

    具体来说,假设一个系统有两个节点 A 和 B,它们之间发生了网络分区。此时如果客户端向节点 A 写入数据,要保证一致性就需要同步到节点 B,但网络已经断开无法同步。这时系统要么拒绝写入请求(牺牲可用性保证一致性),要么允许写入但接受数据不一致(牺牲一致性保证可用性)。而在现代互联网环境下,网络分区是常态而非异常,所以分区容错性通常是必须保证的,这就意味着必须在一致性和可用性之间做出权衡。

  2. 不同组合的应用场景

    CA 组合(一致性+可用性) 适用于不需要分区容错的单机或局域网环境。传统的关系型数据库如 MySQL、PostgreSQL 在单机部署时就是典型的 CA 系统,它们通过 ACID 事务保证强一致性和高可用性。这类系统适合对数据一致性要求极高且网络环境稳定可控的场景,比如银行核心账务系统、证券交易系统等。但在分布式环境下,CA 组合实际上是不现实的,因为网络分区无法完全避免。

    CP 组合(一致性+分区容错) 优先保证数据的强一致性,可以容忍短暂的服务不可用。分布式数据库如 HBase、MongoDB(在某些配置下)、Redis Cluster 以及分布式协调服务 ZooKeeper、etcd 都属于这一类。这些系统在发生网络分区时会停止对少数派分区的服务,只有多数派节点可达时才能提供服务,从而保证数据的强一致性。这种模式适合对数据准确性要求极高的场景,比如配置中心、分布式锁、元数据存储等。虽然可能会出现短暂的服务中断,但能确保读取到的数据一定是最新的正确数据。

    AP 组合(可用性+分区容错) 则优先保证系统的持续可用,接受最终一致性。像 Cassandra、DynamoDB、Couchbase 等 NoSQL 数据库,以及很多互联网应用都采用这种模式。在网络分区发生时,系统的各个分区仍然可以独立对外提供服务,只是不同分区之间的数据可能暂时不一致,但会通过后台同步机制最终达到一致。这种模式特别适合互联网场景,比如社交网络的点赞、评论功能,电商网站的商品浏览、购物车等。用户可以随时访问系统,虽然偶尔可能看到稍微过时的数据,但不影响整体使用体验,这种轻微的不一致性是可以接受的。

实际应用中,很多系统会采用混合策略,针对不同的业务模块选择不同的 CAP 组合。比如电商系统中,订单支付模块采用 CP 保证数据准确性,而商品推荐、评价展示等模块则采用 AP 保证用户体验。这种灵活的架构设计能够在保证核心业务数据准确的同时,提供良好的用户体验和系统可扩展性。

举一个简单的例子就是 Nacos 和 ZooKeeper 的区别:

Nacos 作为一个服务发现和配置管理平台,更加注重系统的可用性和分区容错性,因此它更倾向于 AP 模型。在网络分区发生时,Nacos 允许各个分区继续提供服务,确保服务的持续可用,虽然这可能会导致某些数据在短时间内不一致,但通过后台同步机制最终达到一致。

而 ZooKeeper 作为一个分布式协调服务,更加注重数据的一致性和分区容错性,因此它更倾向于 CP 模型。在网络分区发生时,ZooKeeper 会停止对少数派分区的服务,只有多数派节点可达时才能提供服务,从而保证数据的强一致性。

当然 Nacos 也可以配置成 CP 模型,但默认情况下它更偏向于 AP 模型。

分布式存储

Q: 各类分布式存储的区别与联系是什么?

A:

根据数据类型,可以将其分为非结构化数据、结构化数据、半结构化数据三类。

结构化存储的历史非常古老,典型的场景就是事务处理系统或者关系型数据库(RDBMS)。
传统的结构化存储都是从单机做起的,例如大家耳熟能详的 MySQL。MySQL 的成长史就是
互联网的成长史。除了 MySQL 之外,PostgreSQL 也是近年来势头非常强劲的一个 RDBMS。
传统的结构化存储系统强调以下内容。

  1. 结构化的数据(例如关系表);
  2. 强一致性(例如银行系统,电商系统等场景);
  3. 随机访问(索引、增删查改、SQL)

与结构化存储不同的是,非结构化存储强调的是高可扩展性,典型的系统就是分布式文件系统。分布式文件系统也是一个很老的研究话题,例如 20 世纪 70 年代的 Xerox Alto,80 年代的 NFS、AFS,90 年代的 xFS 等。然而,这些早期的分布式文件系统只是起到了网络磁的作用,其最大的问题就是不支持容错和错误恢复。而 Google 在 2003 年 SOSP 会议上推
出的 GFS(Google File System)则走出了里程碑的一步,其开源实现对应为 HDFS。

半结构化存储的提出是为了解决结非结构化存储系统随机访问性能差的问题。我们通常会听到一些流行的名词,例如 NoSQL、Key-Value Store,包括对象存储等。这些都属于半结构化存储研究的领域,其中以 NoSQL 的发展势头最为强劲。NoSQL 系统既有分布式文件系所具有的可扩展性,又有结构化存储系统的随机访问能力(例如随机操作),系统在设计时通常选择简单键值(K-V)进行存储,抛弃了传统 RDBMS 里复杂 SQL 查询及 ACID 事务。

分布式计算

Q: 各类分布式计算的区别与联系是什么?

可以先对分布式计算系统做以下分类:

  1. 传统基于消息的系统
    这类系统里比较有代表性的就是 MPI (Message Passing Interface)。目前比较流行的两个 MPI 实现是 MPICH2 和 OpenMPI。MPI 这个框架非常灵活,对程序的结构几乎没有太多约束,以至于人们有时把 MPI 称为一组接口 API,而不是系统框架。MPI 除了提供消息传递接口之外,其框架还实现了资源管理和分配,以及调度的功能。除此之外,MPI 在高性能计算里也被广泛使用,通常可以和这样的高速网络无缝结合 InfiniBand 实现。

  2. MapReduce 家族系统
    这一类系统又称作 Dataflow 系统,其中以 Hadoop MapReduce 和 Spark 为代表。其实在学术界有很多类似的系统,例如 Dryad、Twister 等。这一类系统的特点是将计算抽象成高层操作,例如 Map、Reduce、Filter 这样的函数式算子,将算子组合成有向无环图(DAG),然后由后端的调度引擎进行并行化调度。其中,MapReduce 系统属于比较简单的 DAG,只有 Map 和 Reduce 两层节点。MapReduce 这样的系统之所以可以扩展到超大规模的集群上运行,就是因为其完备的容错机制。在 Hadoop 社区还有很多基于 MapReduce 框架的衍生产品,例如 Hive(用于并行数据库 OLAP)、Pig(交互式数据操作)等。

    MapReduce 家族的编程风格和 MPI 截然相反。MapReduce 对程序的结构有严格的约束,即计算过程必须能在两个函数中描述:Map 和 Reduce;输入和输出数据都必须是一个个的记录;任务之间不能通信,整个计算过程中唯一的通信机会是 Map 阶段和 Reduce 阶段之间的 shuffling 阶段,这是在框架控制下的,而不是应用代码控制的。因为有了严格的控制,系统框架在任何时候出错都可以从上一个状态恢复。Spark 的 RDD 则是利用 Lineage 机制,可以让数据在内存中完成转换。

    由于良好的扩展性,许多人将机器学习方法的并行化任务放在了这些平台之上。比较有名的库有基于 Hadoop 的 Mahout,以及基于 Spark 的 MLlib。

  3. 图计算系统
    图计算系统是分布式计算的另一个分支,这些系统都是把计算过程抽象成图,然后在不同节点分布式执行,例如 PageRank 这样的任务,很适合用图计算系统来表示。

    大数据图是无法使用单台机器进行处理的,如果对大图数据进行并行处理,对于每一个顶点之间都是连通的图来讲,难以分割成若干完全独立的子图进行独立的并行处理。即使可以分割,也会面临并行机器的协同处理,以及将最后的处理结果进行合并等一系列问题。这需要图数据处理系统选取合适的图分割以及图计算模型来迎接挑战并解决问题。

    最早成名的图计算系统当属 Google 的 Pregel,该系统采用 BSP 模型,计算以节点为中心。随后又有一系列图计算框架推出。除了同步(BSP)图计算系统之外,异步图计算系统里的佼佼者当属 GraphLab,该系统提出了 GAS 的编程模型。2015 年这个项目已经改名为 Dato,专门推广基于图的大规模机器学习系统。其他典型的图数据处理系统还包括 Neo4j 系统和微软的 Trinity 系统等。

  4. 基于状态的系统
    这一类系统主要包括2010年在OSDI会议上推出的Piccolo,以及后来2012年在NIPS会议上Google推出的开源机器学习系统DistBelief,再到后来被机器学习领域广泛应用的参数服务器(Parameter Server)架构。本节重点介绍参数服务器这一架构。

    MPI由于不支持容错所以很难扩展至大规模集群之中,而MapReduce系统也无法支持大模型机器学习应用,并且节点同步效率较低。用图抽象来做机器学习任务,很多问题都不能很好地求解,例如深度学习中的多层结构。而参数服务器这种以状态为中心的模型则把机器学习的模型存储参数上升为主要组件,并且采用异步机制提升处理能力。参数服务器的概念最早来自亚历克斯·斯莫拉(Alex Smola)在2010年提出的并行LDA架构。它通过采用分布式的Memcached作为存放参数的存储器,这样就提供了有效的机制作用于不同节点同步模型参数。Google的杰夫·狄恩(Jeff Dean)在2012年进一步提出了第一代Google Brain大规模神经网络的解决方案 DistBelief。随后,CMU的 Eric Xing 以及百度的李沐都提出了更通用的参数服务器架构。

  5. 实时流处理系统
    实时流处理系统是为高效实时地处理流式数据而提供服务的,更关注数据处理的实时性,能够快速地为决策提供支持。流处理是从复杂事件处理(CEP)发展而来的,流处理模式包括两种:连续查询处理模式、可扩展数据流计算模式。

    连续查询处理模式是一个数据流管理系统(DBMS)的必需功能,通常以SQL查询语句描述,数据流被按照时间模式切割成数据窗口,DBMS在连续流动的数据窗口中执行用户提交的SQL并返回结果。比较著名的系统包括STREAM、StreamBase、Aurora、Telegraph等。

    可扩展数据流计算模式与此不同,其设计初衷是模仿MapReduce计算框架的思路,即在对处理时效性有高要求的计算场景下,提供一个完善的计算框架并暴露给用户少量的编程接口,使得用户能够集中精力处理应用逻辑。至于系统性能、低延迟、数据不丢失以及容错等问题,则由计算框架来负责,这样能够大大提高应用开发的生产力。早期代表有Yahoo的S4,现在流计算的典型框架包括Twitter的Storm、LinkedIn的Samza及Spark Streaming。

MapReduce

质因数

某个 MapReduce 程序的输入是 <$key,value$>集合,其中 $value$ 是整数,$key$ 的取值对 Map 函数没有影响。

Map 函数的功能是将输入的整数 value 转换为 <$p,value$> 列表输出,其中 $p$ 是 $value$ 的质因数。如,Map( <$key,12$> )的输出为{$(2,12),(3,12)$}。

Reduce 函数 提供汇总功能,Reduce( <$p$,$value_1,value_2,⋯,value_k$> ) 的输出为 <$p,value_1+value_2+⋯+value_k$>。

说明: 质因数是一个数的约数,并且是质数。如,$12 = 2 × 2 × 3$,$2$ 和 $3$ 就是 $12$ 的质因数。

Q1: Hadoop MapReduce 提供了什么机制允许一个作业的各个任务间共享只读文件?尝试描述该机制的工作原理。

Q2: MapReduce 中 Combiner 的作用是什么?

Q3: 输入集合 <$k_1,15$>,<$k_2,21$>,<$k_3,24$>,<$k_4,30$>,<$k_5,49$>,按照以下表格的形式,填写 Map 阶段、Shuffle 阶段和 Reduce 阶段的输出。

Map 阶段 Shuffle 阶段 Reduce 阶段

A1: DistributedCache,即分布式缓存,原理是借助 HDFS 实现数据分发功能,实际上是一个磁盘(不是内存)缓存实现。

A2: Combiner 位于 Map Task 中,相当于 local Reducer。通常跟 Reducer 逻辑一样,作用是对 Map Task 数据进行局部汇总或者规约,以减少数据输出量。

A3:

Map 阶段 Shuffle 阶段 Reduce 阶段
15→(3,15),(5,15)
21→(3,21),(7,21)
24→(2,24),(3,24)
30→(2,30),(3,30),(5,30)
49→(7,49)
(2,[24,30])
(3,[15,21,24,30])
(5,[15,30])
(7,[21,49])
(2,54)
(3,90)
(5,45)
(7,70)

祖孙

某个 MapReduce 程序的输入是 $\langle key_P, value_C \rangle$ 集合,其中 $key_P$ 表示父母,$value_C$ 是儿女,输出 $\langle key_GP, value_GC \rangle$ 集合,其中 $key_GP$ 表示祖父母,$value_GC$ 是孙子或孙女。如 $(Tom, Jack)$ 表示 Tom 是 Jack 的父亲,$(Jack, Alice)$ 表示 Jack 是 Alice 的父亲,则程序输出 $(Tom, Alice)$。

Q1: 在 Hadoop 中,一个处理文本文件的 MapReduce 作业,其 Map Task 数目是如何决定的?

Q2: MapReduce 中 Partitioner 的作用是什么?

Q3: 输入集合如下表所示,按照以下表格的形式,填写 Map 阶段、Shuffle 阶段和 Reduce 阶段的输出,并简要描述各阶段的操作。

输入数据:

key_P key_C
Tom Jack
Jack Alice
Jack Jesse

Map 阶段:

输入 输出

Shuffle 阶段:

输入 输出

Reduce 阶段:

输入 输出

A1: MapTask 个数由 split 的数量决定。

A2: Partitioner 的作用是决定 Map Task 产生的数据记录交给哪个 Reduce Task 处理。默认实现是:$(key)mod R$,其中 $R$ 是 Reduce Task 个数。一般情况下,当需要按照 $key$ 的一部分(不是全部,比如 $key$ 的前三个字节)进行 partition,或者按照 $key$ 范围进行 partition 时,
需要自定义 Partitioner。

A3:

Map 阶段
输入 输出
(Tom, Jack) (Jack, 1_Tom)
(Tom, 0_Jack)
(Jack, Alice) (Alice, 1_Jack)
(Jack, 0_Alice)
(Jack, Jesse) (Jesse, 1_Jack)
(Jack, 0_Jesse)
Shuffle 阶段
输入 输出
(Jack, 1_Tom)
(Jack, 0_Alice)
(Tom, 0_Jack)
(Alice, 1_Jack)
(Jack, 0_Alice)
(Jesse, 1_Jack)
(Jack, 0_Jesse)
(Jack, [1_Tom, 0_Alice, 0_Jesse])
(Tom, [0_Jack])
(Alice, [1_Jack])
(Jesse, [1_Jack])
Reduce 阶段
输入 输出
(Jack, [1_Tom, 0_Alice, 0_Jesse])
(Tom, [0_Jack])
(Alice, [1_Jack])
(Jesse, [1_Jack])
(Tom, Alice)
(Tom, Jesse)