译者序
在经历了二十余年互联网和移动互联网的发展之后,我们已经生活在一个大数据日益盛行的时代。数据早已不再是一台计算机、服务器可以存储下的,而需要成百上千台机器才能完成存储工作。数据规模也已经从以前的MB、GB级别,跨越到了TB、PB级别。并行化和分布式编程技能对开发人员的日常工作变得越来越重要,越来越多的开发人员正面临着因数据集太大而导致的问题。无论是社交、电商、短视频等如今日益流行的领域,还是人们的日常生活,都已经让我们越来越认识到大数据的价值。
在大数据的生态发展过程中,涌现了大量的新技术和框架,包括我们较为熟悉的Hadoop、Hive、Spark等,以及在大数据基础上再次发展起来的AI技术。应该说,这10年的技术发展浪潮都起源于我们可以开始处理以前无法想象的数据量。但是,无论新技术如何发展,底层的核心思想依然没有发生变化,那就是map和reduce的编程范式。如今以Hadoop为基石建立起来的大数据体系,正是map和reduce编程范式的体现。本书并没有介绍太多花哨的技术和框架,反而花费了大量篇幅讲解底层的map和reduce思想,再一步步拓展到如何用Python实现单机程序,如何用Hadoop、Spark等框架实现分布式计算,以及如何在云上的计算集群中处理更大规模的数据。这样的思路让人有“拨开迷雾,返璞归真”之感。
本书适合有一定Python编程基础,且希望掌握大型数据集处理能力的开发人员和数据科学家阅读。
感谢家人、朋友、同事一直以来对我的鼓励和支持。本译著难免会存在一些纰漏,恳请读者谅解并指出。
前言
我是在 2018 年夏天想到写这本书的。当时我和一些才华横溢的开发人员一起工作,他们在职业生涯的大部分时间里都没有学习过如何编写可伸缩的代码。我意识到,很多 “大数据”的技术,或者我们在本书中称为 “大数据集”问题的技术,都是专门为那些想要解决这些问题的人准备的。因为企业中存在很多这样的问题,而且在这种规模下产生数据的机制已经相对成熟,所以关于这个主题的书籍往往是用作为工具的企业语言(比如 Java 语言)编写的。
这本书有一些不同。我注意到越来越多的大数据集问题正在通过分布式的方式处理。这里的分布式不是指分布式计算——当然也不是指员工会分散在各地来完成这些工作。个人开发者或者小型开发团队,通常在快速的原型环境中,或者使用快速开发语言(比如 Python)来处理大数据集。
我希望这本书能够将可伸缩和分布式编程技术带给更广泛的开发人员。我们生活在一个大数据日益盛行的时代。并行化和分布式编程技能对开发人员的日常工作变得越来越重要。越来越多的程序员正面临由于数据集太大而导致的问题。我希望通过这本书,开发人员能够掌握解决这些大数据问题的工具,并将重点放在那些让他们首先对编程感兴趣的问题上。
谁应该阅读本书
本书的目标是向读者传授一种可伸缩的编程风格。为了做到这一点,我们将涉及一些你可能不熟悉的编程或技术书籍。其他书籍可能只会介绍某一个函数库,而本书则会涉及许多函数库——既有内置的模块,比如 functools 和 itertools,也有第三方库,比如 toolz、pathos 和 mrjob。其他的书籍可能只会涉及某一项技术,而这本书会涉及很多技术,包括 Hadoop、Spark 和 Amazon Web Services (AWS)。我们选择覆盖更广泛的技术是为了承认这样一个事实 :为了让代码具有可伸缩性,你需要能够适应新的情况。然而,在所有这些技术中,我会强调 Python 中一种 “map和reduce”的编程风格。
你会发现,在不断变化的环境中,这种代码风格能够保持始终如一,这也是我最初采用它的原因。你可以使用它来快速调整代码以适应新的情况。最终,本书的目的是教你如何通过映射和归约的风格来扩展代码。在这个过程中,我还打算教你使用一些大数据的工具,比如 Spark、Hadoop 和 AWS。
这本书是为开发人员或者数据科学家所编写的,因为他们知道自己正面临数据量太大的问题。如果你知道如何解决自己的问题,但却不能足够快地处理大规模的数据,那么本书就是为你准备的。如果你对Hadoop和Spark感兴趣,本书会很适合你。
如果你正在寻找一些关于如何将在云端处理大数据的方法,那么本书可能会帮到你。
本书是如何组织的:路线图
在第 1 章中,我将介绍 map 和 reduce 的编程风格,以及我将在本书中讨论的内容。我将讨论并行编程的好处、分布式计算的基础知识、用于并行和分布式计算的工具以及云计算。我还为在本书中所涉及的材料提供了一个概念模型。
在第 2 章中,我将介绍 map 和 reduce 风格中的 map 部分,并讨论如何并行化一个问题,以便更快地解决它。我将介绍 Python 的对象持久化过程,即 Python 如何在并行化期间共享数据,以及我们将通过一个示例来演示如何使用并行化来加速Web 抓取。
在第 3 章中,我们将使用 map 函数来执行复杂的数据转换。在本章中,我将教你如何将小的功能拼接到一起,形成函数管道或者函数链,从而产生巨大的效果。我还将演示如何并行化这些函数链,以便在大数据集上更快地解决问题。
在第 4 章中,我将介绍惰性(laziness)的概念,以及如何利用惰性来加速大数据工作流的处理速度。我将展示如何用惰性函数在本地来处理大数据集问题,如何创建自己的惰性函数,以及如何最佳地结合使用惰性和非惰性的编程方式。我们将使用这些惰性方法来解决一个模拟问题。
在第 5 章中,我将讨论如何使用 reduce 函数进行累加转换。我还会教你如何使用匿名或者 lambda 函数。在本章中,我们将使用 reduce 函数来计算大数据集的汇总统计信息。
在第 6 章中,我将介绍使用 map 和 reduce 的高级并行化技术。你将学习 Python中用于并行化的高级函数,以及如何、何时寻求问题的并行解决方案。在本章中,你还将学习如何实现并行的 reduce 工作流。
在第 7 章,我将介绍分布式计算的基础以及 Hadoop 和 Spark 等技术。你将使用 Hadoop 和 Spark 来编写一个入门程序,并了解每种框架的优点。我们还将讨论Hadoop 优于 Spark 和 Spark 优于 Hadoop 的情况。
在第 8 章中,我将介绍如何使用 Hadoop 在分布式集群上流式运行 map 和 reduce 风格的代码。我还将介绍一个用 Python 来编写 Hadoop 作业的 mrjob 库。我们将介绍如何在 Hadoop 的多个作业步骤之间移动复杂的数据类型。我们将通过分析 Web 流量数据和网球比赛日志的示例来巩固对这些原则的理解。
在第 9 章中,我们将深入讨论如何使用 Spark 来让 Python 代码分布式化。我将介绍 Spark 的 RDD 数据结构,以及如何使用 RDD 的方法来实现 map 和 reduce 的编程风格。我们还将对第 8 章中的网球比赛日志数据实现经典的 PageRank 算法。
在第 10 章中,我们将讨论 Spark 最流行的应用之一:并行机器学习。在本章中,我们将介绍机器学习的一些基础知识。我们将通过实现决策树和决策森林来实践这些原则,从而预测一堆蘑菇是否有毒。
在第 11 章中,我将介绍云计算的基础知识和云存储的本质。我们将通过使用Web GUI 和基于 Python 的 AWS API 包装库——boto3,将数据加载到 Amazon S3,从而将我们的学习付诸实践。
在第 12 章中,我们将使用 Amazon ElasticMapReduce 在云中运行分布式的Hadoop 和 Spark 作业。你将了解如何使用 mrjob 从控制台和基于 AWS 浏览器的GUI 来搭建一个弹性的 Hadoop 集群。一旦你掌握了本章的知识内容,就可以处理任何大小的数据集。