Merge pull request #36 from wwek/master

1.修复多个链接错误 2.名词优化修订 3.错误修订
This commit is contained in:
Feng Ruohang 2019-11-26 14:35:59 +08:00 committed by GitHub
commit 73003f49a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 61 additions and 70 deletions

View File

@ -13,7 +13,7 @@
* [第七章:事务](ch7.md)
* [第八章:分布式系统的麻烦](ch8.md)
* [第九章:一致性与共识](ch9.md)
* [第三部分:生数据](part-iii.md)
* [第三部分:生数据](part-iii.md)
* [第十章:批处理](ch10.md)
* [第十一章:流处理](ch11.md)
* [第十二章:数据系统的未来](ch12.md)

View File

@ -909,4 +909,4 @@ top5.each{|count, url| puts "#{count} #{url}" } # 5
| 上一章 | 目录 | 下一章 |
| --------------------------------- | ------------------------------- | ------------------------ |
| [第三部分:派生数据](part-iii.md) | [设计数据密集型应用](README.md) | [第十章:流处理](ch7.md) |
| [第三部分:派生数据](part-iii.md) | [设计数据密集型应用](README.md) | [第十一章:流处理](ch11.md) |

25
ch11.md
View File

@ -33,22 +33,13 @@
事件可能被编码为文本字符串或JSON或者某种二进制编码如[第4章](ch4.md)所述。这种编码允许你存储一个事件,例如将其附加到一个文件,将其插入关系表,或将其写入文档数据库。它还允许你通过网络将事件发送到另一个节点以进行处理。
在批处理领域,作业的输入和输出是文件(也许在分布式文件系统上)。什么是类似的流媒体?
当输入是一个文件(一个字节序列)时,第一个处理步骤通常是将其解析为一系列记录。在流处理的上下文中,记录通常被称为事件,但它本质上是一样的:一个小的,自包含的,不可变的对象,包含某个时间点发生的事情的细节。一个事件通常包含一个时间戳,指示何时根据时钟来发生(参见“[单调钟与时钟](ch8.md#单调钟与时钟)”)。
例如发生的事情可能是用户采取的行动例如查看页面或进行购买。它也可能来源于机器例如来自温度传感器的周期性测量或者CPU利用率度量。在“[使用Unix工具进行批处理](ch10.md#使用Unix工具进行批处理)”的示例中Web服务器日志的每一行都是一个事件。
事件可能被编码为文本字符串或JSON或者以某种二进制形式编码如[第4章](ch4.md)所述。这种编码允许你存储一个事件,例如将其追加写入一个文件,将其插入关系型表,或将其写入文档数据库。它还允许你通过网络将事件发送到其他节点以进行处理。
在批处理中,文件被写入一次,然后可能被多个作业读取。类似地,在流处理术语中,一个事件由**生产者producer**(也称为**发布者publisher**或**发送者sender**)生成一次,然后可能由多个**消费者consumer****订阅者subscribers**或**接收者recipients**进行处理【3】。在文件系统中文件名标识一组相关记录在流媒体系统中相关的事件通常被聚合为一个**主题topic**或**流stream**。
在批处理中,文件被写入一次,然后可能被多个作业读取。类似地,在流处理术语中,一个事件由 **生产者producer** (也称为 **发布者publisher****发送者sender** )生成一次,然后可能由多个 **消费者consumer** **订阅者subscribers****接收者recipients** 进行处理【3】。在文件系统中文件名标识一组相关记录在流式系统中相关的事件通常被聚合为一个 **主题topic****流stream**
原则上讲,文件或数据库就足以连接生产者和消费者:生产者将其生成的每个事件写入数据存储,且每个消费者定期轮询数据存储,检查自上次运行以来新出现的事件。这实际上正是批处理在每天结束时处理当天数据时所做的事情。
但当我们想要进行低延迟的连续处理时,如果数据存储不是为这种用途专门设计的,那么轮询开销就会很大。轮询的越频繁,能返回新事件的请求比例就越低,而额外开销也就越高。相比之下,最好能在新事件出现时直接通知消费者。
数据库在传统上对这种通知机制支持的并不好,关系型数据库通常有**触发器trigger**它们可以对变化作出反应插入表中的一行但它们的功能非常有限而且在数据库设计中算是一种事后反思【4,5】。相应的是已经有为传递事件通知这一目开发的专用工具已经被开发出来。
数据库在传统上对这种通知机制支持的并不好,关系型数据库通常有 **触发器trigger** 它们可以对变化作出反应插入表中的一行但是它们的功能非常有限并且在数据库设计中有些后顾之忧【4,5】。相应的是已经开发了专门的工具来提供事件通知。
### 消息系统
@ -262,7 +253,7 @@
#### 变更数据捕获的实现
我们可以将日志消费者叫做**衍生数据系统**,正如在第三部分的[介绍](part-iii.md)中所讨论的:存储在搜索索引和数据仓库中的数据,只是**记录系统**数据的额外视图。变更数据捕获是一种机制,可确保对记录系统所做的所有更改都反映在派生数据系统中,以便派生系统具有数据的准确副本。
我们可以将日志消费者叫做**衍生数据系统**,正如在第三部分的[介绍](part-iii.md)中所讨论的:存储在搜索索引和数据仓库中的数据,只是**记录系统**数据的额外视图。变更数据捕获是一种机制,可确保对记录系统所做的所有更改都反映在衍生数据系统中,以便衍生系统具有数据的准确副本。
从本质上说,变更数据捕获使得一个数据库成为领导者(被捕获变化的数据库),并将其他组件变为追随者。基于日志的消息代理非常适合从源数据库传输变更事件,因为它保留了消息的顺序(避免了[图11-2](img/fig11-2.png)的重新排序问题)。
@ -365,7 +356,7 @@ $$
如果你持久存储了变更日志那么重现状态就非常简单。如果你认为事件日志是你的记录系统而所有的衍生状态都从它派生而来那么系统中的数据流动就容易理解的多。正如帕特·赫兰Pat Helland所说的【52】
> 事务日志记录了数据库的所有变更。高速追加下入是更改日志的唯一方法。从这个角度来看,数据库的内容其实是日志中记录最新值的缓存。日志才是真相,数据库是日志子集的缓存,这一缓存子集恰好来自日志中每条记录与索引值的最新值。
> 事务日志记录了数据库的所有变更。高速追加是更改日志的唯一方法。从这个角度来看,数据库的内容其实是日志中记录最新值的缓存。日志才是真相,数据库是日志子集的缓存,这一缓存子集恰好来自日志中每条记录与索引值的最新值。
日志压缩(如“[日志压缩](#日志压缩)”中所述)是连接日志与数据库状态之间的桥梁:它只保留每条记录的最新版本,并丢弃被覆盖的版本。
@ -512,7 +503,7 @@ $$
而且消息延迟还可能导致无法预测消息顺序。例如假设用户首先发出一个Web请求由Web服务器A处理然后发出第二个请求由服务器B处理。 A和B发出描述它们所处理请求的事件但是B的事件在A的事件发生之前到达消息代理。现在流处理器将首先看到B事件然后看到A事件即使它们实际上是以相反的顺序发生的。
有一个类比也许能帮助理解“星球大战”电影第四集于1977年发行第五集于1980年第六集于1983年紧随其后的是1999年的第一集2002年的第二集和2005年的三集以及2015年的第七集【80】[^ii]。如果你按照按照它们上映的顺序观看电影,你处理电影的顺序与它们叙事的顺序就是不一致的。 (集数编号就像事件时间戳,而你观看电影的日期就是处理时间)作为人类,我们能够应对这种不连续性,但是流处理算法需要专门写,以适应这种时机与顺序的问题。
有一个类比也许能帮助理解“星球大战”电影第四集于1977年发行第五集于1980年第六集于1983年紧随其后的是1999年的第一集2002年的第二集和2005年的三集以及2015年的第七集【80】[^ii]。如果你按照按照它们上映的顺序观看电影,你处理电影的顺序与它们叙事的顺序就是不一致的。 (集数编号就像事件时间戳,而你观看电影的日期就是处理时间)作为人类,我们能够应对这种不连续性,但是流处理算法需要专门写,以适应这种时机与顺序的问题。
[^ii]: 感谢Flink社区的Kostas Kloudas提出这个比喻。
@ -561,7 +552,7 @@ $$
***跳动窗口Hopping Window***
跳动窗口也有着固定的长度但允许窗口重叠以提供一些平滑。例如一个带有1分钟跳跃步长的5分钟窗口将包含`10:03:00`至`10:07:59`之间的事件,而下一个窗口将覆盖`10:04:00`至`10:08`之间的事件 59等等。通过首先计算1分钟的滚动窗口然后在几个相邻窗口上进行聚合可以实现这种跳动窗口。
跳动窗口也有着固定的长度但允许窗口重叠以提供一些平滑。例如一个带有1分钟跳跃步长的5分钟窗口将包含`10:03:00`至`10:07:59`之间的事件,而下一个窗口将覆盖`10:04:00`至`10:08:59`之间的事件等等。通过首先计算1分钟的滚动窗口然后在几个相邻窗口上进行聚合可以实现这种跳动窗口。
***滑动窗口Sliding Window***
@ -569,7 +560,7 @@ $$
***会话窗口Session window***
与其他窗口类型不同会话窗口没有固定的持续时间而定义为将同一用户出现时间相近的所有事件分组在一起而当用户一段时间没有活动时例如如果30分钟内没有事件窗口结束。会话切分是网站分析的常见需求参阅“[GROUP BY](ch10.md#GROUP BY)”)。
与其他窗口类型不同会话窗口没有固定的持续时间而定义为将同一用户出现时间相近的所有事件分组在一起而当用户一段时间没有活动时例如如果30分钟内没有事件窗口结束。会话切分是网站分析的常见需求参阅“[GROUP BY](ch10.md#GROUP\ BY)”)。
### 流式连接
@ -940,4 +931,4 @@ GROUP BY follows.follower_id
| 上一章 | 目录 | 下一章 |
| ------------------------- | ------------------------------- | ---------------------------------- |
| [第十章:批处理](ch10.md) | [设计数据密集型应用](README.md) | [第十二章:数据系统的未来](ch7.md) |
| [第十章:批处理](ch10.md) | [设计数据密集型应用](README.md) | [第十二章:数据系统的未来](ch12.md) |

View File

@ -10,9 +10,9 @@
[TOC]
到目前为止,本书主要描述的是**实然**问题:现在事情**是**什么样的。在这最后一章中,我们将放眼未来,讨论**应然**的问题:事情**应该**是什么样子的。我将提出一些想法与方法,我相信它们能从根本上改进我们设计与构建应用的方式。
到目前为止,本书主要描述的是**现状**。在这最后一章中,我们将放眼**未来**,讨论应该是怎么样的:我将提出一些想法与方法,我相信它们能从根本上改进我们设计与构建应用的方式。
对未来的看法与推测当然具有很大的主观性。所以在撰写本章时,当提及我个人的观点时会使用第一人称。您完全可以不同意这些观点并提出自己的看法,但我希望本章中的概念,至少能成为富有成效讨论出发点,并澄清一些经常被混淆的概念。
对未来的看法与推测当然具有很大的主观性。所以在撰写本章时,当提及我个人的观点时会使用第一人称。您完全可以不同意这些观点并提出自己的看法,但我希望本章中的概念,至少能成为富有成效讨论出发点,并澄清一些经常被混淆的概念。
[第1章](ch1.md)概述了本书的目标:探索如何创建**可靠****可扩展**和**可维护**的应用与系统。这一主题贯穿了所有的章节:例如,我们讨论了许多有助于提高可靠性的容错算法,有助于提高可扩展性的分区,以及有助于提高可维护性的演化与抽象机制。在本章中,我们将把所有这些想法结合在一起,并在它们的基础上展望未来。我们的目标是,发现如何设计出比现有应用更好的应用 —— 健壮,正确,可演化,且最终对人类有益。
@ -850,7 +850,7 @@ COMMIT;
俗话说“知识就是力量”。更进一步“在避免自己被审视的同时审视他人是权力最重要的形式之一”【105】。这就是极权政府想要监控的原因这让它们有能力控制全体居民。尽管今天的科技公司并没有公开地寻求政治权力但是它们积累的数据与知识却给它们带来了很多权力其中大部分是在公共监督之外偷偷进行的【106】。
#### 记着工业革命
#### 回顾工业革命
数据是信息时代的决定性特征。互联网数据存储处理和软件驱动的自动化正在对全球经济和人类社会产生重大影响。我们的日常生活与社会组织在过去十年中发生了变化而且在未来的十年中可能会继续发生根本性的变化所以我们会想到与工业革命对比【87,96】。

2
ch2.md
View File

@ -144,7 +144,7 @@ JSON表示比[图2-1](img/fig2-1.png)中的多表模式具有更好的**局部
[^ii]: 关于关系模型的文献区分了几种不同的规范形式,但这些区别几乎没有实际意义。一个经验法则是,如果重复存储了可以存储在一个地方的值,则模式就不是**规范化normalized**的。
> 数据库管理员和开发人员喜欢争论规范化和非规范化,让我们暂时保留判断吧。在本书的[第三部分](part-iii.md),我们将回到这个话题,探讨系统的方法用以处理缓存,非规范化和生数据。
> 数据库管理员和开发人员喜欢争论规范化和非规范化,让我们暂时保留判断吧。在本书的[第三部分](part-iii.md),我们将回到这个话题,探讨系统的方法用以处理缓存,非规范化和生数据。
不幸的是对这些数据进行规范化需要多对一的关系许多人生活在一个特定的地区许多人在一个特定的行业工作这与文档模型不太吻合。在关系数据库中通过ID来引用其他表中的行是正常的因为连接很容易。在文档数据库中一对多树结构没有必要用连接对连接的支持通常很弱[^iii]。

2
ch7.md
View File

@ -955,4 +955,4 @@ WHERE room_id = 123 AND
| 上一章 | 目录 | 下一章 |
| ---------------------- | ------------------------------- | ---------------------------------- |
| [第六章:分区](ch6.md) | [设计数据密集型应用](README.md) | [第八章:分布式系统的麻烦](ch7.md) |
| [第六章:分区](ch6.md) | [设计数据密集型应用](README.md) | [第八章:分布式系统的麻烦](ch8.md) |

4
ch9.md
View File

@ -283,7 +283,7 @@
> ### CAP定理没有帮助
>
> CAP有时以这种面目出现一致性可用性和分区容三者只能择其二。不幸的是这种说法很有误导性【32】因为网络分区是一种错误所以它并不是一个选项不管你喜不喜欢它都会发生【38】。
> CAP有时以这种面目出现一致性可用性和分区容错性三者只能择其二。不幸的是这种说法很有误导性【32】因为网络分区是一种错误所以它并不是一个选项不管你喜不喜欢它都会发生【38】。
>
> 在网络正常工作的时候系统可以提供一致性线性一致性和整体可用性。发生网络故障时你必须在线性一致性和整体可用性之间做出选择。因此一个更好的表达CAP的方法可以是一致的或者在分区时可用【39】。一个更可靠的网络需要减少这个选择但是在某些时候选择是不可避免的。
>
@ -1201,5 +1201,5 @@
| 上一章 | 目录 | 下一章 |
| ---------------------------------- | ------------------------------- | --------------------------------- |
| [第八章:分布式系统的麻烦](ch8.md) | [设计数据密集型应用](README.md) | [第三部分:生数据](part-iii.md) |
| [第八章:分布式系统的麻烦](ch8.md) | [设计数据密集型应用](README.md) | [第三部分:生数据](part-iii.md) |

View File

@ -88,9 +88,9 @@
### 生数据derived data
### 生数据derived data
一种数据集,根据其他数据通过可重复运行的流程创建。必要时,你可以运行该流程再次创建派生数据。派生数据通常用于提高特定数据的读取速度。常见的派生数据有索引、缓存和物化视图。参见第三部分的介绍。
一种数据集,根据其他数据通过可重复运行的流程创建。必要时,你可以运行该流程再次创建衍生数据。衍生数据通常用于提高特定数据的读取速度。常见的衍生数据有索引、缓存和物化视图。参见第三部分的介绍。
@ -338,7 +338,7 @@
### 记录系统system of record
一个保存主要权威版本数据的系统,也被称为真相的来源。首先在这里写入数据变更,其他数据集可以从记录系统生。 参见第三部分的介绍。
一个保存主要权威版本数据的系统,也被称为真相的来源。首先在这里写入数据变更,其他数据集可以从记录系统生。 参见第三部分的介绍。

View File

@ -24,7 +24,7 @@
大多数数据库,存储引擎和查询语言,本质上既不是记录系统也不是衍生系统。数据库只是一个工具:如何使用它取决于你自己。**记录系统和衍生数据系统之间的区别不在于工具,而在于应用程序中的使用方式。**
通过梳理数据的衍生关系,可以清楚地理解一个令人困惑的系统架构。这将贯穿本书的这一部分。
通过梳理数据的衍生关系,可以清楚地理解一个令人困惑的系统架构。这将贯穿本书的这一部分。
## 章节概述