mirror of
https://github.com/Vonng/ddia.git
synced 2024-12-06 15:20:12 +08:00
part-iii in progress
This commit is contained in:
parent
f757453b3f
commit
eaa392f5fb
@ -106,9 +106,9 @@
|
||||
| 第八章:分布式系统中的问题 | 初翻 | |
|
||||
| 第九章:一致性与共识 | 初翻 | |
|
||||
| 第三部分:衍生数据 | 精翻 | |
|
||||
| 第十章:批处理 | 草翻 | |
|
||||
| 第十章:批处理 | 草翻 | Vonng |
|
||||
| 第十一章:流处理 | 草翻 | |
|
||||
| 第十二章:数据系统的未来 | 草翻 | |
|
||||
| 第十二章:数据系统的未来 | 初翻 40% | Vonng |
|
||||
| 术语表 | - | |
|
||||
| 后记 | 初翻 | |
|
||||
|
||||
@ -124,12 +124,15 @@ All contribution will give proper credit. 贡献者需要同意[法律声明](#
|
||||
|
||||
1. [序言初翻修正](https://github.com/Vonng/ddia/commit/afb5edab55c62ed23474149f229677e3b42dfc2c) by [@seagullbird](https://github.com/Vonng/ddia/commits?author=seagullbird)
|
||||
2. [第一章语法标点校正](https://github.com/Vonng/ddia/commit/973b12cd8f8fcdf4852f1eb1649ddd9d187e3644) by [@nevertiree](https://github.com/Vonng/ddia/commits?author=nevertiree)
|
||||
3. [第六章部分校正](https://github.com/Vonng/ddia/commit/d4eb0852c0ec1e93c8aacc496c80b915bb1e6d48) by @[MuAlex](https://github.com/Vonng/ddia/commits?author=MuAlex)
|
||||
3. [第六章部分校正](https://github.com/Vonng/ddia/commit/d4eb0852c0ec1e93c8aacc496c80b915bb1e6d48) 与[第10章的翻译](https://github.com/Vonng/ddia/commit/9de8dbd1bfe6fbb03b3bf6c1a1aa2291aed2490e) by @[MuAlex](https://github.com/Vonng/ddia/commits?author=MuAlex)
|
||||
4. 第一部分前言,ch2校正 by @jiajiadebug
|
||||
5. 词汇表、后记关于野猪的部分 by @[Chowss](https://github.com/Vonng/ddia/commits?author=Chowss)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 译读者交流微信群
|
||||
|
||||
![](img/ddia-wexin.JPG)
|
||||
|
94
ch10.md
94
ch10.md
@ -10,58 +10,60 @@
|
||||
|
||||
[TOC]
|
||||
|
||||
在本书的前两部分中,我们讨论了很多关于请求和查询以及相应的响应或结果。许多现有数据系统中都采用这种数据处理方式:你发送请求指令,一段时间后(我们期望)系统会给出一个结果。数据库,缓存,搜索索引,Web服务器以及其他一些系统都以这种方式工作。
|
||||
在本书的前两部分中,我们讨论了很多关于**请求**和**查询**以及相应的**响应**或**结果**。许多现有数据系统中都采用这种数据处理方式:你发送请求指令,一段时间后(我们期望)系统会给出一个结果。数据库,缓存,搜索索引,Web服务器以及其他一些系统都以这种方式工作。
|
||||
|
||||
像这样的线上系统,无论是浏览器请求页面还是调用远程API的服务,我们通常认为请求是由用户触发的,并且正在等待响应。他们不应该等太久,所以我们非常关注系统的响应时间(参阅“[描述性能](ch1.md)”)。
|
||||
像这样的**在线(online)**系统,无论是浏览器请求页面还是调用远程API的服务,我们通常认为请求是由用户触发的,并且正在等待响应。他们不应该等太久,所以我们非常关注系统的响应时间(参阅“[描述性能](ch1.md)”)。
|
||||
|
||||
Web和越来越多的基于HTTP/REST的API使交互的请求/响应风格变得如此普遍,以至于很容易将其视为理所当然。但我们应该记住,这不是构建系统的唯一方式,其他方法也有其优点。我们来看看三种不同类型的系统:
|
||||
Web和越来越多的基于HTTP/REST的API使交互的请求/响应风格变得如此普遍,以至于很容易将其视为理所当然。但我们应该记住,这不是构建系统的唯一方式,其他方法也有其优点。我们来看看三种不同类型的系统:
|
||||
|
||||
***服务(线上系统)***
|
||||
***服务(在线系统)***
|
||||
|
||||
- 服务等待客户的请求或指令到达。每收到一个,服务会试图尽快处理它,并发回一个响应。响应时间通常是服务性能的主要衡量指标,可用性通常非常重要(如果客户端无法访问服务,用户可能会收到错误消息)。
|
||||
服务等待客户的请求或指令到达。每收到一个,服务会试图尽快处理它,并发回一个响应。响应时间通常是服务性能的主要衡量指标,可用性通常非常重要(如果客户端无法访问服务,用户可能会收到错误消息)。
|
||||
|
||||
***批处理系统(线下系统)***
|
||||
***批处理系统(离线系统)***
|
||||
|
||||
- 一个批处理系统有大量的输入数据,跑一个作业(job)来处理它,并生成一些输出数据,这往往需要一段时间(从几分钟到几天),所以通常不会有用户等待作业完成。相反,批量作业通常会定期运行(例如,每天一次)。批处理作业的主要性能衡量标准通常是吞吐量(处理特定大小的输入所需的时间)。本章中讨论的就是批处理。
|
||||
一个批处理系统有大量的输入数据,跑一个**作业(job)**来处理它,并生成一些输出数据,这往往需要一段时间(从几分钟到几天),所以通常不会有用户等待作业完成。相反,批量作业通常会定期运行(例如,每天一次)。批处理作业的主要性能衡量标准通常是吞吐量(处理特定大小的输入所需的时间)。本章中讨论的就是批处理。
|
||||
|
||||
***流处理系统(近实时系统)***
|
||||
***流处理系统(准实时系统)***
|
||||
|
||||
- 流处理介于线上和线下(批处理)之间,所以有时候被称为近实时或近线(nearline)处理。像批处理系统一样,流处理消费输入并产生输出(并不需要响应请求)。但是,流式作业在事件发生后不久就会对事件进行操作,而批处理作业则需等待固定的一组输入数据。这种差异使流处理系统比起批处理系统具有更低的延迟。由于流处理基于批处理,我们将在第11章讨论它。
|
||||
流处理介于在线和离线(批处理)之间,所以有时候被称为**准实时(near-real-time)**或**准在线(nearline)**处理。像批处理系统一样,流处理消费输入并产生输出(并不需要响应请求)。但是,流式作业在事件发生后不久就会对事件进行操作,而批处理作业则需等待固定的一组输入数据。这种差异使流处理系统比起批处理系统具有更低的延迟。由于流处理基于批处理,我们将在[第11章](ch11.md)讨论它。
|
||||
|
||||
正如我们将在本章中看到的那样,批处理是构建可靠,可扩展和可维护应用程序的重要组成部分。例如,2004年发布的批处理算法Map-Reduce(可能有点过于热门)被称为“造就Google大规模可扩展性的算法”)被称为“造就Google大规模可扩展性的算法”[2]。随后在各种开源数据系统中得到应用,包括Hadoop,CouchDB和MongoDB。
|
||||
|
||||
与多年前为数据仓库开发的并行处理系统【3,4】相比,MapReduce是一个相当低级别的编程模型,但它在现有硬件水平基础上,迈出了处理大数据重要的一步。虽然MapReduce的重要性正在下降【5】,但它仍然值得理解,因为它提供了一个清晰的画面来阐述批处理为什么以及如何有用。
|
||||
|
||||
实际上,批处理是一种非常古老的计算方式。早在可编程数字计算机诞生之前,打孔卡制表机(例如1890年美国人口普查【6】中使用的霍尔里斯机)实现了半机械化的批处理形式,从大量输入中汇总计算。 Map-Reduce与1940年代和1950年代广泛用于商业数据处理的机电IBM卡片分类机器有着惊人的相似之处[7]。正如我们所说,历史总是在不断重演。
|
||||
正如我们将在本章中看到的那样,批处理是构建可靠,可扩展和可维护应用程序的重要组成部分。例如,2004年发布的批处理算法Map-Reduce(可能被过分热情地)被称为“造就Google大规模可扩展性的算法”【2】。随后在各种开源数据系统中得到应用,包括Hadoop,CouchDB和MongoDB。
|
||||
|
||||
在本章中,我们将了解MapReduce和其他一些批处理算法和框架,并探索它们在现代数据系统中的作用。但首先我们将看看使用标准Unix工具的数据处理。即使你已经熟悉了它们,Unix的哲学也值得一读,Unix的思想和经验教训可以转移到大规模,异构的分布式数据系统中。
|
||||
与多年前为数据仓库开发的并行处理系统【3,4】相比,MapReduce是一个相当低级别的编程模型,但它使得在商用硬件上能进行的处理规模迈上一个新的台阶。虽然MapReduce的重要性正在下降【5】,但它仍然值得去理解,因为它描绘了一幅关于批处理为什么有用,以及如何实用的清晰图景。
|
||||
|
||||
实际上,批处理是一种非常古老的计算方式。早在可编程数字计算机诞生之前,打孔卡制表机(例如1890年美国人口普查【6】中使用的霍尔里斯机)实现了半机械化的批处理形式,从大量输入中汇总计算。 Map-Reduce与1940年代和1950年代广泛用于商业数据处理的机电IBM卡片分类机器有着惊人的相似之处【7】。正如我们所说,历史总是在不断重复自己。
|
||||
|
||||
在本章中,我们将了解MapReduce和其他一些批处理算法和框架,并探索它们在现代数据系统中的作用。但首先我们将看看使用标准Unix工具的数据处理。即使你已经熟悉了它们,Unix的哲学也值得一读,Unix的思想和经验教训可以迁移到大规模,异构的分布式数据系统中。
|
||||
|
||||
|
||||
|
||||
## 使用Unix工具的批处理
|
||||
|
||||
我们从一个简单的例子开始。假设您有一台Web服务器,每次处理请求时都会在日志文件中附加一行。例如,使用nginx默认访问日志格式,日志的一行可能如下所示:
|
||||
我们从一个简单的例子开始。假设您有一台Web服务器,每次处理请求时都会在日志文件中附加一行。例如,使用nginx默认访问日志格式,日志的一行可能如下所示:
|
||||
|
||||
```
|
||||
```bash
|
||||
216.58.210.78 - - [27/Feb/2015:17:55:11 +0000] "GET /css/typography.css HTTP/1.1"
|
||||
200 3377 "http://martin.kleppmann.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5)
|
||||
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"
|
||||
```
|
||||
|
||||
(实际上这只是一行,分成多行只是为了便于阅读)。这一行中有很多信息。为了理解它,你需要看看日志格式的定义,如下所示:
|
||||
(实际上这只是一行,分成多行只是为了便于阅读。)这一行中有很多信息。为了理解它,你需要了解日志格式的定义,如下所示:
|
||||
|
||||
```
|
||||
$remote_addr - $remote_user [$time_local] "$request"
|
||||
$status $body_bytes_sent "$http_referer" "$http_user_agent"
|
||||
```
|
||||
|
||||
日志的这一行表明在2015年2月27日17:55:11 UTC,服务器从客户端IP地址216.58.210.78接收到对文件`/css/typography.css`的请求。用户没有被认证,所以`$remote_user`被设置为连字符(`-` )。响应状态是200(即请求成功),响应的大小是3377字节。网页浏览器是Chrome 40,并且加载了该文件,因为在URL `http://martin.kleppmann.com/`的页面中引用。
|
||||
日志的这一行表明在2015年2月27日17:55:11 UTC,服务器从客户端IP地址`216.58.210.78`接收到对文件`/css/typography.css`的请求。用户没有被认证,所以`$remote_user`被设置为连字符(`-` )。响应状态是200(即请求成功),响应的大小是3377字节。网页浏览器是Chrome 40,URL `http://martin.kleppmann.com/` 的页面中的引用导致该文件被加载。
|
||||
|
||||
|
||||
|
||||
### 分析简单日志
|
||||
|
||||
很多工具可以利用这些日志文件产生关于你网站流量的漂亮的报告,但为了练手,让我们使用基本的Unix功能创建自己的工具。 例如,假设你想在你的网站上找到五个最受欢迎的网页。 你可以在Unix shell中这样做:[^i]
|
||||
很多工具可以利用这些日志文件产生关于你网站流量的漂亮的报告,但为了练手,让我们使用基本的Unix功能创建自己的工具。 例如,假设你想在你的网站上找到五个最受欢迎的网页。 则可以在Unix shell中这样做:[^i]
|
||||
|
||||
[^i]: 有些人认为`cat`这里并没有必要,因为输入文件可以直接作为awk的参数。 但这种写法让线性管道更为显眼。
|
||||
|
||||
@ -77,9 +79,9 @@ cat /var/log/nginx/access.log | #1
|
||||
1. 读取日志文件
|
||||
2. 将每一行按空格分割成不同的字段,每行只输出第七个字段,恰好是请求的URL。在我们的例子中是`/css/typography.css`。
|
||||
3. 按字母顺序排列请求的URL列表。如果某个URL被请求过n次,那么排序后,文件在一行中会重复出现n次该URL。
|
||||
4. uniq命令通过检查两个相邻的行是否相同来过滤掉输入中的重复行。 -c则表示输出一个计数器:对于每个不同的URL,它会报告输入中出现该URL的次数。
|
||||
5. 第二种排序按每行起始处的数字(-n)排序,这是URL的请求次数。然后逆序(-r)返回结果,大的数字在前。
|
||||
6. 最后,只输出前五行(-n 5),并丢弃其余的。该系列命令的输出如下所示:
|
||||
4. `uniq`命令通过检查两个相邻的行是否相同来过滤掉输入中的重复行。 `-c`则表示输出一个计数器:对于每个不同的URL,它会报告输入中出现该URL的次数。
|
||||
5. 第二种排序按每行起始处的数字(`-n`)排序,这是URL的请求次数。然后逆序(`-r`)返回结果,大的数字在前。
|
||||
6. 最后,只输出前五行(`-n 5`),并丢弃其余的。该系列命令的输出如下所示:
|
||||
|
||||
```
|
||||
4189 /favicon.ico
|
||||
@ -89,13 +91,13 @@ cat /var/log/nginx/access.log | #1
|
||||
915 /css/typography.css
|
||||
```
|
||||
|
||||
如果你不熟悉Unix工具,上面的命令行可能看起来有点吃力,但是它非常强大。它能在几秒钟内处理几GB的日志文件,并且您可以根据需要轻松修改命令。例如,如果要从报告中省略CSS文件,可以将awk参数更改为`'$7 !~ /\.css$/ {print $7}'`,如果想统计最多的客户端IP地址,可以把awk参数改为`'{print $1}'`等等。
|
||||
如果你不熟悉Unix工具,上面的命令行可能看起来有点吃力,但是它非常强大。它能在几秒钟内处理几GB的日志文件,并且您可以根据需要轻松修改命令。例如,如果要从报告中省略CSS文件,可以将awk参数更改为`'$7 !~ /\.css$/ {print $7}'`,如果想统计最多的客户端IP地址,可以把awk参数改为`'{print $1}'`等等。
|
||||
|
||||
我们不会在这里详细探索Unix工具,但是它非常值得学习。令人惊讶的是,使用awk,sed,grep,sort,uniq和xargs的组合,可以在几分钟内完成许多数据分析,并且它们的性能相当的好[8]。
|
||||
我们不会在这里详细探索Unix工具,但是它非常值得学习。令人惊讶的是,使用awk,sed,grep,sort,uniq和xargs的组合,可以在几分钟内完成许多数据分析,并且它们的性能相当的好【8】。
|
||||
|
||||
#### 命令链与自定义程序
|
||||
|
||||
抛开Unix命令链,你可以写一个简单的程序来做同样的事情。例如,在Ruby中,它可能看起来像这样:
|
||||
除了Unix命令链,你还可以写一个简单的程序来做同样的事情。例如在Ruby中,它可能看起来像这样:
|
||||
|
||||
```ruby
|
||||
counts = Hash.new(0) # 1
|
||||
@ -110,40 +112,42 @@ top5 = counts.map{|url, count| [count, url] }.sort.reverse[0...5] # 4
|
||||
top5.each{|count, url| puts "#{count} #{url}" } # 5
|
||||
```
|
||||
|
||||
1. `counts`是一个存储计数器次数的哈希表,初始情况下每个网址对应的计数为零。
|
||||
2. 我们读取日志的每一行,把获取第七个空格分隔的字段(这里的数组索引是6,因为Ruby的数组从0开始)对应的URL。
|
||||
3. 将日志当前行中URL的计数加一。
|
||||
4. 按计数器值(降序)对哈希表进行排序,并取前五位。
|
||||
1. `counts`是一个存储计数器的哈希表,保存了每个URL被浏览的次数,默认为0。
|
||||
2. 逐行读取日志,抽取每行第七个被空格分隔的字段为URL(这里的数组索引是6,因为Ruby的数组索引从0开始计数)
|
||||
3. 将日志当前行中URL对应的计数器值加一。
|
||||
4. 按计数器值(降序)对哈希表内容进行排序,并取前五位。
|
||||
5. 打印出前五个条目。
|
||||
|
||||
这个程序并不像Unix管道那样简练,但是它的可读性很强,对于这两种方式每个人有不同的偏好。但是,除了表面上的语法差异,两者执行流程也有很大差异,文件越大则越明显。
|
||||
这个程序并不像Unix管道那样简洁,但是它的可读性很强,喜欢哪一种属于口味的问题。但两者除了表面上的差异之外,执行流程也有很大差异,如果你在大文件上运行此分析,则会变得明显。
|
||||
|
||||
#### 排序 VS 内存中的聚合
|
||||
|
||||
Ruby脚本在内存中保存着一个URL的哈希表,其中每个URL映射到它被统计的次数。 Unix流水线没有这样一个哈希表,而是依赖于对URL列表的排序,在这个URL列表中,同一个URL的只是简单的重复出现。
|
||||
Ruby脚本在内存中保存了一个URL的哈希表,将每个URL映射到它出现的次数。 Unix管道没有这样的哈希表,而是依赖于对URL列表的排序,在这个URL列表中,同一个URL的只是简单地重复出现。
|
||||
|
||||
哪种方法更好?这取决于你有多少个不同的URL。对于大多数中小型网站,您可能可以为所有不同网址提供一个计数器(假设我们使用1GB内存)。在此例中,作业的工作集(作业需要随机访问的内存大小)仅取决于不同URL的数量:如果单个URL有一百万个日志条目,则哈希中所需的空间表仍然只有一个URL加上一个计数器的大小。如果这个工作集足够小,那么内存哈希表工作正常,甚至在性能较差的笔记本电脑上也可以。
|
||||
哪种方法更好?这取决于你有多少个不同的URL。对于大多数中小型网站,您可能可以为所有不同网址提供一个计数器(假设我们使用1GB内存)。在此例中,作业的**工作集(working set)**(作业需要随机访问的内存大小)仅取决于不同URL的数量:如果日志中只有单个URL,重复出现一百万次,则散列表所需的空间表就只有一个URL加上一个计数器的大小。当工作集足够小时,内存散列表表现良好,甚至在性能较差的笔记本电脑上也可以正常工作。
|
||||
|
||||
另一方面,如果作业的工作集大于可用内存,则排序方法的优点是可以高效地使用磁盘。这与我们在第74页的“[SSTables和LSM树]”中讨论过的原理是一样的:数据块可以在内存中排序并分段写入磁盘,然后多个有序的分段可以合并为一个更大的有序文件。归并排序具有在磁盘上运行良好的顺序访问模式。(请记住,在顺序I/O中进行优化是第3章中反复出现的主题,这里我们再次提到。)
|
||||
另一方面,如果作业的工作集大于可用内存,则排序方法的优点是可以高效地使用磁盘。这与我们在“[SSTables和LSM树](ch3.md#SSTables和LSM树)”中讨论过的原理是一样的:数据块可以在内存中排序并作为段文件写入磁盘,然后多个排序好的段可以合并为一个更大的排序文件。 归并排序具有在磁盘上运行良好的顺序访问模式。 (请记住,针对顺序I/O进行优化是[第3章](ch3.md)中反复出现的主题,相同的模式在此重现)
|
||||
|
||||
Linux GNU 核心工具(Coreutils)中的排序自动把大于可用内存的数据集在磁盘进行分割,并且通过CPU的多核并行排序【9】。这意味着之前简单的Unix命令链很容易扩展到大数据集,并且不会耗尽内存。瓶颈更可能是从磁盘读取输入文件的速度。
|
||||
GNU Coreutils(Linux)中的`sort `程序通过溢出至磁盘的方式来自动应对大于内存的数据集,并能同时使用多个CPU核进行并行排序【9】。这意味着我们之前看到的简单的Unix命令链很容易扩展到大数据集,且不会耗尽内存。瓶颈可能是从磁盘读取输入文件的速度。
|
||||
|
||||
|
||||
|
||||
### Unix哲学
|
||||
|
||||
我们可以非常容易地使用前一个例子中的命令链来分析日志文件,这并非巧合:这实际上是Unix的关键设计思想之一,而且它今天依然令人惊讶。让我们更深入地进行研究,这样我们可以从Unix中借鉴一些想法【10】。
|
||||
我们可以非常容易地使用前一个例子中的命令链来分析日志文件,这并非巧合:这实际上是Unix的关键设计思想之一,而且它今天依然令人惊讶。让我们更深入地进行研究,这样我们可以从Unix中借鉴一些想法【10】。
|
||||
|
||||
Unix管道的发明者道格·麦克罗伊(Doug McIlroy)在1964年首先做出了描述【11】:“我们需要一种像花园软管一样的连接程序的方法 - 可以把数据通过拧口传输到不同的片段中。这也是I/O的实现方式”。通过管道连接程序的想法成为了Unix的哲学的一部分,Unix哲学成为在开发人员和用户之间流行的设计准则。1978年, Unix哲学得到具体描述【12,13】:
|
||||
Unix管道的发明者道格·麦克罗伊(Doug McIlroy)在1964年首先做出了描述【11】:“我们需要一种像花园软管一样的连接程序的方法 - 可以把数据通过拧口传输到不同的片段中。这也是I/O的实现方式”。通过管道连接程序的想法成为了Unix的哲学的一部分,Unix哲学成为在开发人员和用户之间流行的设计准则。1978年, Unix哲学得到具体描述【12,13】:
|
||||
|
||||
1. 让每个程序都做好一件事。如果有新的任务,重新建立一个新的程序,而不是在原有程序上增加“功能”使其复杂化。
|
||||
2. 每个程序的输出应该成为另一个程序的输入,而不是未知程序。不要将输出与无关的信息混淆。避免使用严格的柱状或二进制输入格式。不要坚持交互式输入。
|
||||
3. 设计和构建软件,甚至是操作系统时要尽早尝试,最好在几周内完成。毫不犹犹豫扔掉笨拙的部分并重建它们。
|
||||
4. 优先使用工具而不是拙劣的帮助来减轻编程任务,即使您必须花费额外经历开发工具,并且其中一些工具可能今后再也不会用到。
|
||||
|
||||
这种方式 - 自动化,快速原型设计,迭代式迭代,对实验友好,将大型项目分解成可管理的模块 - 听起来非常像今天的敏捷和DevOps概念。令人惊奇的是这个理念四十年来变化不大。
|
||||
|
||||
排序工具是一个“做好一件事”很好的例子。它可以说比大多数编程语言的标准库(不会分割到磁盘并且不使用多线程,即使这么做有好处)中的实现更好。然而,排序工具几乎不会单独使用。它只能与其他Unix工具(如`uniq`)结合使用。
|
||||
|
||||
这种方式 —— 自动化,快速原型设计,迭代式迭代,对实验友好,将大型项目分解成可管理的模块 —— 听起来非常像今天的敏捷和DevOps概念。令人惊奇的是这个理念四十年来变化不大。
|
||||
|
||||
排序工具是一个“做好一件事”很好的例子。它可以说比大多数编程语言的标准库(不会分割到磁盘并且不使用多线程,即使这么做有好处)中的实现更好。然而,排序工具几乎不会单独使用。它只能与其他Unix工具(如`uniq`)结合使用。
|
||||
|
||||
像bash这样的Unix shell可以让我们轻松地将这些小程序组合成令人惊讶的强大数据处理作业。尽管这些程序有很多是由不同人群编写的,但它们可以灵活地组合在一起。 Unix如何实现这种可组合性?
|
||||
|
||||
@ -188,7 +192,7 @@ Unix工具如此成功的部分原因是它们使得查看正在发生的事情
|
||||
- Unix命令的输入文件通常被视为不可变的。这意味着您可以随意运行命令,尝试各种命令行选项,而不会损坏输入文件。
|
||||
|
||||
- 您可以在任何时候结束管道,将输出管道输送到`less`,然后查找它是否具有预期的数据。这种检查能力对调试非常有用。
|
||||
|
||||
|
||||
- 您可以将一个流水线阶段的输出写入文件,并将该文件用作下一阶段的输入。这使您可以重新启动后面的阶段,而无需重新运行整个管道。
|
||||
|
||||
因此,与关系数据库的查询优化器相比,即使Unix工具非常直接和简单,仍然非常有用,特别是对于调试来说。
|
||||
@ -268,17 +272,17 @@ Reducer通过一个迭代器对相同的主键进行逐步扫描(在某些情
|
||||
|
||||
#### MapReduce工作流程
|
||||
|
||||
单个MapReduce作业可以解决的问题范围有限。请参阅日志分析案例,一个MapReduce作业可以确定每个URL的页面浏览次数,但无法确定访问最多的URL,因为这需要第二轮排序。
|
||||
单个MapReduce作业可以解决的问题范围有限。请参阅日志分析案例,一个MapReduce作业可以确定每个URL的页面浏览次数,但无法确定访问最多的URL,因为这需要第二轮排序。
|
||||
|
||||
因此,将MapReduce作业链到工作流中非常常见,例如,一个作业的输出成为下一个作业的输入。 Hadoop Map-Reduce框架对工作流没有特别的支持,所以这个链接是通过目录名隐含完成的:第一个作业必须通过配置将其输出写入到HDFS中的指定目录,第二个作业必须是读取这个目录。从MapReduce框架的角度来看,他们是两个独立的工作。
|
||||
因此,将MapReduce作业链到工作流中非常常见,例如,一个作业的输出成为下一个作业的输入。 Hadoop Map-Reduce框架对工作流没有特别的支持,所以这个链接是通过目录名隐含完成的:第一个作业必须通过配置将其输出写入到HDFS中的指定目录,第二个作业必须是读取这个目录。从MapReduce框架的角度来看,他们是两个独立的工作。
|
||||
|
||||
因此,被链接的MapReduce作业和Unix命令的流水线(它直接将一个进程的输出作为输入传递给另一个进程,只使用一个小的内存缓冲区)不太一样,它更像是一个命令序列,其中每个命令的输出会写入临时文件,下一个命令从临时文件中读取。这种设计有利有弊,我们将在第419页“中间状态的具体化”中讨论。
|
||||
因此,被链接的MapReduce作业和Unix命令的流水线(它直接将一个进程的输出作为输入传递给另一个进程,只使用一个小的内存缓冲区)不太一样,它更像是一个命令序列,其中每个命令的输出会写入临时文件,下一个命令从临时文件中读取。这种设计有利有弊,我们将在第419页“中间状态的具体化”中讨论。
|
||||
|
||||
只有当作业成功完成时,批处理作业的输出才被视为有效(MapReduce丢弃失败作业产生的部分输出)。因此,工作流中的一项工作只有在先前的工作 - 即产生它所需的输入工作成功完成时才能开始。为了处理这些作业之间的依赖关系执行,基于Hadoop开发了各种工作流调度器,包括Oozie,Azkaban,Luigi,Airflow和Pinball [28]。
|
||||
只有当作业成功完成时,批处理作业的输出才被视为有效(MapReduce丢弃失败作业产生的部分输出)。因此,工作流中的一项工作只有在先前的工作 - 即产生它所需的输入工作成功完成时才能开始。为了处理这些作业之间的依赖关系执行,基于Hadoop开发了各种工作流调度器,包括Oozie,Azkaban,Luigi,Airflow和Pinball [28]。
|
||||
|
||||
这些调度程序还具有管理功能,在维护大量批处理作业时非常有用。在构建推荐系统[29]时,由50到100个MapReduce作业组成的工作流非常常见,而在大型组织中,不同的团队可能运行不同的作业来读取彼此的输出。工具支持对于管理这样复杂的数据流非常重要。
|
||||
这些调度程序还具有管理功能,在维护大量批处理作业时非常有用。在构建推荐系统[29]时,由50到100个MapReduce作业组成的工作流非常常见,而在大型组织中,不同的团队可能运行不同的作业来读取彼此的输出。工具支持对于管理这样复杂的数据流非常重要。
|
||||
|
||||
Hadoop的各种高级工具(如Pig [30],Hive [31],Cascading [32],Crunch [33]和FlumeJava [34])也设置了多个MapReduce阶段的工作流程并且将他们自动连接在一起。
|
||||
Hadoop的各种高级工具(如Pig [30],Hive [31],Cascading [32],Crunch [33]和FlumeJava [34])也设置了多个MapReduce阶段的工作流程并且将他们自动连接在一起。
|
||||
|
||||
### Reduce端连接(join)与分组(group)
|
||||
|
||||
@ -492,7 +496,7 @@ MPP数据库是单一的,紧密集成的软件,负责磁盘上的存储布
|
||||
|
||||
MapReduce使工程师能够轻松地在大型数据集上运行自己的代码。如果你有HDFS和MapReduce,那么你可以在它上面建立一个SQL查询执行引擎,事实上这正是Hive项目所做的[31]。而且对于不适合用SQL查询表示的批处理,也可以自己实现处理方式。
|
||||
|
||||
随后,人们发现MapReduce对于某些类型的处理来说太过于限制,表现得很差,基于Hadoop开发了其他各种处理模型(我们将在第419页的“Beyond MapReduce”中看到其中的一些)。仅仅两种处理模型,SQL和MapReduce是不够的,我们需要更多不同的模型!而且由于Hadoop平台的开放性,实施一整套方法是可行的,而这在整体MPP数据库的范围内是不可能的[58]。
|
||||
随后,人们发现MapReduce对于某些类型的处理来说太过于限制,表现得很差,基于Hadoop开发了其他各种处理模型(我们将在第419页的“[超越MapReduce]()”中看到其中的一些)。仅仅两种处理模型,SQL和MapReduce是不够的,我们需要更多不同的模型!而且由于Hadoop平台的开放性,实施一整套方法是可行的,而这在整体MPP数据库的范围内是不可能的【58】。
|
||||
|
||||
至关重要的是,这些不同的处理模型都可以在一个共享用途的集群上运行,所有这些机器都可以访问分布式文件系统上的相同文件。在Hadoop方法中,不需要将数据导入到几个不同的专用系统中进行不同类型的处理:系统足够灵活,可以支持同一个群集内不同的工作负载。不需要移动数据使得从数据中取值变得容易得多,并且在新的处理模型进行实验更加容易。
|
||||
|
||||
|
2
ch4.md
2
ch4.md
@ -372,7 +372,7 @@ Avro为静态类型编程语言提供了可选的代码生成功能,但是它
|
||||
|
||||
|
||||
|
||||
### 服务中的数据流:REST 与 RPC
|
||||
### 服务中的数据流:REST与RPC
|
||||
|
||||
当您需要通过网络进行通信的进程时,安排该通信的方式有几种。最常见的安排是有两个角色:客户端和服务器。服务器通过网络公开API,并且客户端可以连接到服务器以向该API发出请求。服务器公开的API被称为服务。
|
||||
|
||||
|
19
ch7.md
19
ch7.md
@ -879,9 +879,9 @@ WHERE room_id = 123 AND
|
||||
|
||||
一个相当新的算法,避免了先前方法的大部分缺点。它使用乐观的方法,允许事务执行而无需阻塞。当一个事务想要提交时,它会进行检查,如果执行不可序列化,事务就会被中止。
|
||||
|
||||
本章中的示例主要是在关系数据模型的上下文中。使用关系数据模型。但是,正如在讨论中,无论使用哪种数据模型,如“**[多对象事务的需求](#多对象事务的需求)**”中所讨论的,事务都是重要的数据库功能。
|
||||
本章中的示例主要是在关系数据模型的上下文中。使用关系数据模型。但是,正如在讨论中,无论使用哪种数据模型,如“**[多对象事务的需求](#多对象事务的需求)**”中所讨论的,事务都是重要的数据库功能。
|
||||
|
||||
本章主要是在单机数据库的上下文中,探讨了各种概念与想法。分布式数据库中的事务,则引入了一系列新的困难挑战,将在接下来的两章中讨论。
|
||||
本章主要是在单机数据库的上下文中,探讨了各种概念与想法。分布式数据库中的事务,则引入了一系列新的困难挑战,将在接下来的两章中讨论。
|
||||
|
||||
|
||||
|
||||
@ -902,16 +902,15 @@ WHERE room_id = 123 AND
|
||||
10. Philip A. Bernstein, Vassos Hadzilacos, and Nathan Goodman: [*Concurrency Control and Recovery in Database Systems*](http://research.microsoft.com/en-us/people/philbe/ccontrol.aspx). Addison-Wesley, 1987. ISBN: 978-0-201-10715-9, available online at *research.microsoft.com*.
|
||||
11. Alan Fekete, Dimitrios Liarokapis, Elizabeth O'Neil, et al.: “[Making Snapshot Isolation Serializable](https://www.cse.iitb.ac.in/infolab/Data/Courses/CS632/2009/Papers/p492-fekete.pdf),” *ACM Transactions on Database Systems*, volume 30, number 2, pages 492–528, June 2005.
|
||||
[doi:10.1145/1071610.1071615](http://dx.doi.org/10.1145/1071610.1071615)
|
||||
12. Mai Zheng, Joseph Tucek, Feng Qin, and Mark Lillibridge: “[Understanding the Robustness of SSDs Under Power Fault](https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf),” at *11th USENIX Conference on File and Storage Technologies* (FAST), February 2013.
|
||||
12. Mai Zheng, Joseph Tucek, Feng Qin, and Mark Lillibridge: “[Understanding the Robustness of SSDs Under Power Fault](https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf),” at *11th USENIX Conference on File and Storage Technologies* (FAST), February 2013.
|
||||
13. Laurie Denness: “[SSDs: A Gift and a Curse](https://laur.ie/blog/2015/06/ssds-a-gift-and-a-curse/),” *laur.ie*, June 2, 2015.
|
||||
14. Adam Surak: “[When Solid State Drives Are Not That Solid](https://blog.algolia.com/when-solid-state-drives-are-not-that-solid/),” *blog.algolia.com*, June 15, 2015.
|
||||
14. Adam Surak: “[When Solid State Drives Are Not That Solid](https://blog.algolia.com/when-solid-state-drives-are-not-that-solid/),” *blog.algolia.com*, June 15, 2015.
|
||||
15. Thanumalayan Sankaranarayana Pillai, Vijay Chidambaram, Ramnatthan Alagappan, et al.: “[All File Systems Are Not Created Equal: On the Complexity of Crafting Crash-Consistent Applications](http://research.cs.wisc.edu/wind/Publications/alice-osdi14.pdf),” at *11th USENIX Symposium on Operating Systems Design and Implementation* (OSDI),
|
||||
October 2014.
|
||||
16. Chris Siebenmann: “[Unix's File Durability Problem](https://utcc.utoronto.ca/~cks/space/blog/unix/FileSyncProblem),” *utcc.utoronto.ca*, April 14, 2016.
|
||||
17. Lakshmi N. Bairavasundaram, Garth R. Goodson, Bianca Schroeder, et al.: “[An Analysis of Data Corruption in the Storage Stack](http://research.cs.wisc.edu/adsl/Publications/corruption-fast08.pdf),” at *6th USENIX Conference on File and Storage
|
||||
Technologies* (FAST), February 2008.
|
||||
16. Chris Siebenmann: “[Unix's File Durability Problem](https://utcc.utoronto.ca/~cks/space/blog/unix/FileSyncProblem),” *utcc.utoronto.ca*, April 14, 2016.
|
||||
17. Lakshmi N. Bairavasundaram, Garth R. Goodson, Bianca Schroeder, et al.: “[An Analysis of Data Corruption in the Storage Stack](http://research.cs.wisc.edu/adsl/Publications/corruption-fast08.pdf),” at *6th USENIX Conference on File and Storage Technologies* (FAST), February 2008.
|
||||
18. Bianca Schroeder, Raghav Lagisetty, and Arif Merchant: “[Flash Reliability in Production: The Expected and the Unexpected](https://www.usenix.org/conference/fast16/technical-sessions/presentation/schroeder),” at *14th USENIX Conference on File and Storage Technologies* (FAST), February 2016.
|
||||
19. Don Allison: “[SSD Storage – Ignorance of Technology Is No Excuse](https://blog.korelogic.com/blog/2015/03/24),” *blog.korelogic.com*, March 24, 2015.
|
||||
19. Don Allison: “[SSD Storage – Ignorance of Technology Is No Excuse](https://blog.korelogic.com/blog/2015/03/24),” *blog.korelogic.com*, March 24, 2015.
|
||||
20. Dave Scherer: “[Those Are Not Transactions (Cassandra 2.0)](http://web.archive.org/web/20150526065247/http://blog.foundationdb.com/those-are-not-transactions-cassandra-2-0),” *blog.foundationdb.com*, September 6, 2013.
|
||||
21. Kyle Kingsbury: “[Call Me Maybe: Cassandra](http://aphyr.com/posts/294-call-me-maybe-cassandra/),” *aphyr.com*, September 24, 2013.
|
||||
22. “[ACID Support in Aerospike](http://www.aerospike.com/docs/architecture/assets/AerospikeACIDSupport.pdf),” Aerospike, Inc., June 2014.
|
||||
@ -935,9 +934,9 @@ WHERE room_id = 123 AND
|
||||
38. Joel Jacobson: “[Riak 2.0: Data Types](http://blog.joeljacobson.com/riak-2-0-data-types/),” *blog.joeljacobson.com*, March 23, 2014.
|
||||
39. Michael J. Cahill, Uwe Röhm, and Alan Fekete: “[Serializable Isolation for Snapshot Databases](http://www.cs.nyu.edu/courses/fall12/CSCI-GA.2434-001/p729-cahill.pdf),” at *ACM International Conference on Management of Data* (SIGMOD), June 2008. [doi:10.1145/1376616.1376690](http://dx.doi.org/10.1145/1376616.1376690)
|
||||
40. Dan R. K. Ports and Kevin Grittner: “[Serializable Snapshot Isolation in PostgreSQL](http://drkp.net/papers/ssi-vldb12.pdf),” at *38th International Conference on Very Large Databases* (VLDB), August 2012.
|
||||
41. Tony Andrews: “[Enforcing Complex Constraints in Oracle](http://tonyandrews.blogspot.co.uk/2004/10/enforcing-complex-constraints-in.html),” *tonyandrews.blogspot.co.uk*, October 15, 2004.
|
||||
41. Tony Andrews: “[Enforcing Complex Constraints in Oracle](http://tonyandrews.blogspot.co.uk/2004/10/enforcing-complex-constraints-in.html),” *tonyandrews.blogspot.co.uk*, October 15, 2004.
|
||||
42. Douglas B. Terry, Marvin M. Theimer, Karin Petersen, et al.: “[Managing Update Conflicts in Bayou, a Weakly Connected Replicated Storage System](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.141.7889&rep=rep1&type=pdf),” at *15th ACM Symposium on Operating Systems Principles* (SOSP), December 1995. [doi:10.1145/224056.224070](http://dx.doi.org/10.1145/224056.224070)
|
||||
43. Gary Fredericks: “[Postgres Serializability Bug](https://github.com/gfredericks/pg-serializability-bug),” *github.com*, September 2015.
|
||||
43. Gary Fredericks: “[Postgres Serializability Bug](https://github.com/gfredericks/pg-serializability-bug),” *github.com*, September 2015.
|
||||
44. Michael Stonebraker, Samuel Madden, Daniel J. Abadi, et al.: “[The End of an Architectural Era (It’s Time for a Complete Rewrite)](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.137.3697&rep=rep1&type=pdf),” at *33rd International Conference on Very Large Data Bases* (VLDB), September 2007.
|
||||
45. John Hugg: “[H-Store/VoltDB Architecture vs. CEP Systems and Newer Streaming Architectures](https://www.youtube.com/watch?v=hD5M4a1UVz8),” at *Data @Scale Boston*, November 2014.
|
||||
46. Robert Kallman, Hideaki Kimura, Jonathan Natkins, et al.: “[H-Store: A High-Performance, Distributed Main Memory Transaction Processing System](http://www.vldb.org/pvldb/1/1454211.pdf),” *Proceedings of the VLDB Endowment*, volume 1, number 2, pages 1496–1499, August 2008.
|
||||
|
Loading…
Reference in New Issue
Block a user