@@ -87,7 +87,7 @@ cat /var/log/nginx/access.log | #1
87
87
915 /css/typography.css
88
88
```
89
89
90
- 如果你不熟悉 Unix 工具,上面的命令行可能看起来有点吃力,但是它非常强大。它能在几秒钟内处理几 GB 的日志文件,并且你可以根据需要轻松修改命令。例如,如果要从报告中省略 CSS 文件,可以将 awk 参数更改为 ` '$7 !~ /\.css$/ {print $7}' ` , 如果想统计最多的客户端 IP 地址,可以把 awk 参数改为 ` '{print $1}' ` 等等。
90
+ 如果你不熟悉 Unix 工具,上面的命令行可能看起来有点吃力,但是它非常强大。它能在几秒钟内处理几 GB 的日志文件,并且你可以根据需要轻松修改命令。例如,如果要从报告中省略 CSS 文件,可以将 awk 参数更改为 ` '$7 !~ /\.css$/ {print $7}' ` , 如果想统计最多的客户端 IP 地址,可以把 awk 参数改为 ` '{print $1}' ` , 等等。
91
91
92
92
我们不会在这里详细探索 Unix 工具,但是它非常值得学习。令人惊讶的是,使用 awk、sed、grep、sort、uniq 和 xargs 的组合,可以在几分钟内完成许多数据分析,并且它们的性能相当的好【8】。
93
93
@@ -148,7 +148,7 @@ Unix 管道的发明者道格・麦克罗伊(Doug McIlroy)在 1964 年首先
148
148
149
149
如果你希望一个程序的输出成为另一个程序的输入,那意味着这些程序必须使用相同的数据格式 —— 换句话说,一个兼容的接口。如果你希望能够将任何程序的输出连接到任何程序的输入,那意味着所有程序必须使用相同的 I/O 接口。
150
150
151
- 在 Unix 中,这种接口是一个 ** 文件** (file,更准确地说,是一个文件描述符)。一个文件只是一串有序的字节序列。因为这是一个非常简单的接口,所以可以使用相同的接口来表示许多不同的东西:文件系统上的真实文件,到另一个进程(Unix 套接字,stdin,stdout)的通信通道,设备驱动程序(比如 ` /dev/audio ` 或 ` /dev/lp0 ` ),表示 TCP 连接的套接字等等 。很容易将这些设计视为理所当然的,但实际上能让这些差异巨大的东西共享一个统一的接口是非常厉害的,这使得它们可以很容易地连接在一起 [ ^ ii ] 。
151
+ 在 Unix 中,这种接口是一个 ** 文件** (file,更准确地说,是一个文件描述符)。一个文件只是一串有序的字节序列。因为这是一个非常简单的接口,所以可以使用相同的接口来表示许多不同的东西:文件系统上的真实文件,到另一个进程(Unix 套接字,stdin,stdout)的通信通道,设备驱动程序(比如 ` /dev/audio ` 或 ` /dev/lp0 ` ),表示 TCP 连接的套接字,等等 。很容易将这些设计视为理所当然的,但实际上能让这些差异巨大的东西共享一个统一的接口是非常厉害的,这使得它们可以很容易地连接在一起 [ ^ ii ] 。
152
152
153
153
[ ^ ii ] : 统一接口的另一个例子是 URL 和 HTTP,这是 Web 的基石。 一个 URL 标识一个网站上的一个特定的东西(资源),你可以链接到任何其他网站的任何网址。 具有网络浏览器的用户因此可以通过跟随链接在网站之间无缝跳转,即使服务器可能由完全不相关的组织维护。 这个原则现在似乎非常明显,但它却是网络取能取得今天成就的关键。 之前的系统并不是那么统一:例如,在公告板系统(BBS)时代,每个系统都有自己的电话号码和波特率配置。 从一个 BBS 到另一个 BBS 的引用必须以电话号码和调制解调器设置的形式;用户将不得不挂断,拨打其他 BBS,然后手动找到他们正在寻找的信息。 直接链接到另一个 BBS 内的一些内容当时是不可能的。
154
154
@@ -199,7 +199,7 @@ MapReduce 有点像 Unix 工具,但分布在数千台机器上。像 Unix 工
199
199
200
200
虽然 Unix 工具使用 ` stdin ` 和 ` stdout ` 作为输入和输出,但 MapReduce 作业在分布式文件系统上读写文件。在 Hadoop 的 MapReduce 实现中,该文件系统被称为 ** HDFS(Hadoop 分布式文件系统)** ,一个 Google 文件系统(GFS)的开源实现【19】。
201
201
202
- 除 HDFS 外,还有各种其他分布式文件系统,如 GlusterFS 和 Quantcast File System(QFS)【20】。诸如 Amazon S3, Azure Blob 存储和 OpenStack Swift【21】等对象存储服务在很多方面都是相似的 [ ^ iv ] 。在本章中,我们将主要使用 HDFS 作为示例,但是这些原则适用于任何分布式文件系统。
202
+ 除 HDFS 外,还有各种其他分布式文件系统,如 GlusterFS 和 Quantcast File System(QFS)【20】。诸如 Amazon S3、 Azure Blob 存储和 OpenStack Swift【21】等对象存储服务在很多方面都是相似的 [ ^ iv ] 。在本章中,我们将主要使用 HDFS 作为示例,但是这些原则适用于任何分布式文件系统。
203
203
204
204
[ ^ iv ] : 一个不同之处在于,对于 HDFS,可以将计算任务安排在存储特定文件副本的计算机上运行,而对象存储通常将存储和计算分开。如果网络带宽是一个瓶颈,从本地磁盘读取有性能优势。但是请注意,如果使用纠删码(Erasure Coding),则会丢失局部性,因为来自多台机器的数据必须进行合并以重建原始文件【20】。
205
205
@@ -414,7 +414,7 @@ Reduce 侧方法的优点是不需要对输入数据做任何假设:无论其
414
414
415
415
Google 最初使用 MapReduce 是为其搜索引擎建立索引,其实现为由 5 到 10 个 MapReduce 作业组成的工作流【1】。虽然 Google 后来也不仅仅是为这个目的而使用 MapReduce 【43】,但如果从构建搜索索引的角度来看,更能帮助理解 MapReduce。 (直至今日,Hadoop MapReduce 仍然是为 Lucene/Solr 构建索引的好方法【44】)
416
416
417
- 我们在 “[ 全文搜索和模糊索引] ( ch3.md#全文搜索和模糊索引 ) ” 中简要地了解了 Lucene 这样的全文搜索索引是如何工作的:它是一个文件(关键词字典),你可以在其中高效地查找特定关键字,并找到包含该关键字的所有文档 ID 列表(文章列表)。这是一种非常简化的看法 —— 实际上,搜索索引需要各种额外数据,以便根据相关性对搜索结果进行排名, 纠正拼写错误, 解析同义词等等 —— 但这个原则是成立的。
417
+ 我们在 “[ 全文搜索和模糊索引] ( ch3.md#全文搜索和模糊索引 ) ” 中简要地了解了 Lucene 这样的全文搜索索引是如何工作的:它是一个文件(关键词字典),你可以在其中高效地查找特定关键字,并找到包含该关键字的所有文档 ID 列表(文章列表)。这是一种非常简化的看法 —— 实际上,搜索索引需要各种额外数据,以便根据相关性对搜索结果进行排名、 纠正拼写错误、 解析同义词等等 —— 但这个原则是成立的。
418
418
419
419
如果需要对一组固定文档执行全文搜索,则批处理是一种构建索引的高效方法:Mapper 根据需要对文档集合进行分区,每个 Reducer 构建该分区的索引,并将索引文件写入分布式文件系统。构建这样的文档分区索引(请参阅 “[ 分区与次级索引] ( ch6.md#分区与次级索引 ) ”)并行处理效果拔群。
420
420
@@ -646,7 +646,7 @@ Spark、Flink 和 Tez 避免将中间状态写入 HDFS,因此它们采取了
646
646
647
647
自 MapReduce 开始流行的这几年以来,分布式批处理的执行引擎已经很成熟了。到目前为止,基础设施已经足够强大,能够存储和处理超过 10,000 台机器集群上的数 PB 的数据。由于在这种规模下物理执行批处理的问题已经被认为或多或少解决了,所以关注点已经转向其他领域:改进编程模型,提高处理效率,扩大这些技术可以解决的问题集。
648
648
649
- 如前所述,Hive, Pig, Cascading 和 Crunch 等高级语言和 API 变得越来越流行,因为手写 MapReduce 作业实在是个苦力活。随着 Tez 的出现,这些高级语言还有一个额外好处,可以迁移到新的数据流执行引擎,而无需重写作业代码。 Spark 和 Flink 也有它们自己的高级数据流 API,通常是从 FlumeJava 中获取的灵感【34】。
649
+ 如前所述,Hive、 Pig、 Cascading 和 Crunch 等高级语言和 API 变得越来越流行,因为手写 MapReduce 作业实在是个苦力活。随着 Tez 的出现,这些高级语言还有一个额外好处,可以迁移到新的数据流执行引擎,而无需重写作业代码。Spark 和 Flink 也有它们自己的高级数据流 API,通常是从 FlumeJava 中获取的灵感【34】。
650
650
651
651
这些数据流 API 通常使用关系型构建块来表达一个计算:按某个字段连接数据集;按键对元组做分组;按某些条件过滤;并通过计数求和或其他函数来聚合元组。在内部,这些操作是使用本章前面讨论过的各种连接和分组算法来实现的。
652
652
0 commit comments