mirror of
https://github.com/Vonng/ddia.git
synced 2026-06-24 02:16:53 +08:00
优化:个别词语 以及语序
修复:重复的段落; 加粗后不能对markdown正确解析(例如加粗中包含了括号,那么在加粗结束后增加一个空格)
This commit is contained in:
parent
d64b849fed
commit
64df024d24
2 changed files with 49 additions and 58 deletions
23
ch11.md
23
ch11.md
|
|
@ -33,22 +33,13 @@
|
||||||
|
|
||||||
事件可能被编码为文本字符串或JSON,或者某种二进制编码,如[第4章](ch4.md)所述。这种编码允许你存储一个事件,例如将其附加到一个文件,将其插入关系表,或将其写入文档数据库。它还允许你通过网络将事件发送到另一个节点以进行处理。
|
事件可能被编码为文本字符串或JSON,或者某种二进制编码,如[第4章](ch4.md)所述。这种编码允许你存储一个事件,例如将其附加到一个文件,将其插入关系表,或将其写入文档数据库。它还允许你通过网络将事件发送到另一个节点以进行处理。
|
||||||
|
|
||||||
在批处理领域,作业的输入和输出是文件(也许在分布式文件系统上)。什么是类似的流媒体?
|
在批处理中,文件被写入一次,然后可能被多个作业读取。类似地,在流处理术语中,一个事件由**生产者(producer)**(也称为**发布者(publisher)**或**发送者(sender)**)生成一次,然后可能由多个**消费者(consumer)**(**订阅者(subscribers)**或**接收者(recipients)**)进行处理【3】。在文件系统中,文件名标识一组相关记录;在流式系统中,相关的事件通常被聚合为一个**主题(topic)**或**流(stream)**。
|
||||||
|
|
||||||
当输入是一个文件(一个字节序列)时,第一个处理步骤通常是将其解析为一系列记录。在流处理的上下文中,记录通常被称为事件,但它本质上是一样的:一个小的,自包含的,不可变的对象,包含某个时间点发生的事情的细节。一个事件通常包含一个时间戳,指示何时根据时钟来发生(参见“[单调钟与时钟](ch8.md#单调钟与时钟)”)。
|
原则上讲,文件或数据库就足以连接生产者和消费者:生产者将其生成的每个事件写入数据存储,且每个消费者定期轮询数据存储,检查自上次运行以来新出现的事件。这实际上正是批处理在每天结束时处理当天数据时所做的事情。
|
||||||
|
|
||||||
例如,发生的事情可能是用户采取的行动,例如查看页面或进行购买。它也可能来源于机器,例如来自温度传感器的周期性测量或者CPU利用率度量。在“[使用Unix工具进行批处理](ch10.md#使用Unix工具进行批处理)”的示例中,Web服务器日志的每一行都是一个事件。
|
|
||||||
|
|
||||||
事件可能被编码为文本字符串或JSON,或者以某种二进制形式编码,如[第4章](ch4.md)所述。这种编码允许你存储一个事件,例如将其追加写入一个文件,将其插入关系型表,或将其写入文档数据库。它还允许你通过网络将事件发送到其他节点以进行处理。
|
|
||||||
|
|
||||||
在批处理中,文件被写入一次,然后可能被多个作业读取。类似地,在流处理术语中,一个事件由**生产者(producer)**(也称为**发布者(publisher)**或**发送者(sender)**)生成一次,然后可能由多个**消费者(consumer)**(**订阅者(subscribers)**或**接收者(recipients)**)进行处理【3】。在文件系统中,文件名标识一组相关记录;在流媒体系统中,相关的事件通常被聚合为一个**主题(topic)**或**流(stream)**。
|
|
||||||
|
|
||||||
原则上将,文件或数据库就足以连接生产者和消费者:生产者将其生成的每个事件写入数据存储,且每个消费者定期轮询数据存储,检查自上次运行以来新出现的事件。这实际上正是批处理在每天结束时处理当天数据时所做的事情。
|
|
||||||
|
|
||||||
但当我们想要进行低延迟的连续处理时,如果数据存储不是为这种用途专门设计的,那么轮询开销就会很大。轮询的越频繁,能返回新事件的请求比例就越低,而额外开销也就越高。相比之下,最好能在新事件出现时直接通知消费者。
|
但当我们想要进行低延迟的连续处理时,如果数据存储不是为这种用途专门设计的,那么轮询开销就会很大。轮询的越频繁,能返回新事件的请求比例就越低,而额外开销也就越高。相比之下,最好能在新事件出现时直接通知消费者。
|
||||||
|
|
||||||
数据库在传统上对这种通知机制支持的并不好,关系型数据库通常有**触发器(trigger)**,它们可以对变化作出反应(如,插入表中的一行),但它们的功能非常有限,而且在数据库设计中算是一种事后反思【4,5】。相应的是,已经有为传递事件通知这一目开发的专用工具已经被开发出来。
|
数据库在传统上对这种通知机制支持的并不好,关系型数据库通常有**触发器(trigger)**,它们可以对变化作出反应(如,插入表中的一行),但是它们的功能非常有限,并且在数据库设计中有些后顾之忧【4,5】。相应的是,已经开发了专门的工具来提供事件通知。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 消息系统
|
### 消息系统
|
||||||
|
|
@ -365,7 +356,7 @@ $$
|
||||||
|
|
||||||
如果你持久存储了变更日志,那么重现状态就非常简单。如果你认为事件日志是你的记录系统,而所有的衍生状态都从它派生而来,那么系统中的数据流动就容易理解的多。正如帕特·赫兰(Pat Helland)所说的【52】:
|
如果你持久存储了变更日志,那么重现状态就非常简单。如果你认为事件日志是你的记录系统,而所有的衍生状态都从它派生而来,那么系统中的数据流动就容易理解的多。正如帕特·赫兰(Pat Helland)所说的【52】:
|
||||||
|
|
||||||
> 事务日志记录了数据库的所有变更。高速追加下入是更改日志的唯一方法。从这个角度来看,数据库的内容其实是日志中记录最新值的缓存。日志才是真相,数据库是日志子集的缓存,这一缓存子集恰好来自日志中每条记录与索引值的最新值。
|
> 事务日志记录了数据库的所有变更。高速追加是更改日志的唯一方法。从这个角度来看,数据库的内容其实是日志中记录最新值的缓存。日志才是真相,数据库是日志子集的缓存,这一缓存子集恰好来自日志中每条记录与索引值的最新值。
|
||||||
|
|
||||||
日志压缩(如“[日志压缩](#日志压缩)”中所述)是连接日志与数据库状态之间的桥梁:它只保留每条记录的最新版本,并丢弃被覆盖的版本。
|
日志压缩(如“[日志压缩](#日志压缩)”中所述)是连接日志与数据库状态之间的桥梁:它只保留每条记录的最新版本,并丢弃被覆盖的版本。
|
||||||
|
|
||||||
|
|
@ -512,7 +503,7 @@ $$
|
||||||
|
|
||||||
而且,消息延迟还可能导致无法预测消息顺序。例如,假设用户首先发出一个Web请求(由Web服务器A处理),然后发出第二个请求(由服务器B处理)。 A和B发出描述它们所处理请求的事件,但是B的事件在A的事件发生之前到达消息代理。现在,流处理器将首先看到B事件,然后看到A事件,即使它们实际上是以相反的顺序发生的。
|
而且,消息延迟还可能导致无法预测消息顺序。例如,假设用户首先发出一个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提出这个比喻。
|
[^ii]: 感谢Flink社区的Kostas Kloudas提出这个比喻。
|
||||||
|
|
||||||
|
|
@ -561,7 +552,7 @@ $$
|
||||||
|
|
||||||
***跳动窗口(Hopping Window)***
|
***跳动窗口(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)***
|
***滑动窗口(Sliding Window)***
|
||||||
|
|
||||||
|
|
@ -569,7 +560,7 @@ $$
|
||||||
|
|
||||||
***会话窗口(Session window)***
|
***会话窗口(Session window)***
|
||||||
|
|
||||||
与其他窗口类型不同,会话窗口没有固定的持续时间,而定义为:将同一用户出现时间相近的所有事件分组在一起,而当用户一段时间没有活动时(例如,如果30分钟内没有事件)窗口结束。会话切分是网站分析的常见需求(参阅“[GROUP BY](ch10.md#GROUP BY)”)。
|
与其他窗口类型不同,会话窗口没有固定的持续时间,而定义为:将同一用户出现时间相近的所有事件分组在一起,而当用户一段时间没有活动时(例如,如果30分钟内没有事件)窗口结束。会话切分是网站分析的常见需求(参阅“[GROUP BY](ch10.md#GROUP\ BY)”)。
|
||||||
|
|
||||||
### 流式连接
|
### 流式连接
|
||||||
|
|
||||||
|
|
|
||||||
6
ch12.md
6
ch12.md
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
[TOC]
|
[TOC]
|
||||||
|
|
||||||
到目前为止,本书主要描述的是**实然**问题:现在事情**是**什么样的。在这最后一章中,我们将放眼未来,讨论**应然**的问题:事情**应该**是什么样子的。我将提出一些想法与方法,我相信它们能从根本上改进我们设计与构建应用的方式。
|
到目前为止,本书主要描述的是**现状**。在这最后一章中,我们将放眼**未来**,讨论应该是怎么样的:我将提出一些想法与方法,我相信它们能从根本上改进我们设计与构建应用的方式。
|
||||||
|
|
||||||
对未来的看法与推测当然具有很大的主观性。所以在撰写本章时,当提及我个人的观点时会使用第一人称。您完全可以不同意这些观点并提出自己的看法,但我希望本章中的概念,至少能成为富有成效讨论的出发点,并澄清一些经常被混淆的概念。
|
对未来的看法与推测当然具有很大的主观性。所以在撰写本章时,当提及我个人的观点时会使用第一人称。您完全可以不同意这些观点并提出自己的看法,但我希望本章中的概念,至少能成为富有成效的讨论出发点,并澄清一些经常被混淆的概念。
|
||||||
|
|
||||||
[第1章](ch1.md)概述了本书的目标:探索如何创建**可靠**,**可扩展**和**可维护**的应用与系统。这一主题贯穿了所有的章节:例如,我们讨论了许多有助于提高可靠性的容错算法,有助于提高可扩展性的分区,以及有助于提高可维护性的演化与抽象机制。在本章中,我们将把所有这些想法结合在一起,并在它们的基础上展望未来。我们的目标是,发现如何设计出比现有应用更好的应用 —— 健壮,正确,可演化,且最终对人类有益。
|
[第1章](ch1.md)概述了本书的目标:探索如何创建**可靠**,**可扩展**和**可维护**的应用与系统。这一主题贯穿了所有的章节:例如,我们讨论了许多有助于提高可靠性的容错算法,有助于提高可扩展性的分区,以及有助于提高可维护性的演化与抽象机制。在本章中,我们将把所有这些想法结合在一起,并在它们的基础上展望未来。我们的目标是,发现如何设计出比现有应用更好的应用 —— 健壮,正确,可演化,且最终对人类有益。
|
||||||
|
|
||||||
|
|
@ -850,7 +850,7 @@ COMMIT;
|
||||||
|
|
||||||
俗话说,“知识就是力量”。更进一步,“在避免自己被审视的同时审视他人,是权力最重要的形式之一”【105】。这就是极权政府想要监控的原因:这让它们有能力控制全体居民。尽管今天的科技公司并没有公开地寻求政治权力,但是它们积累的数据与知识却给它们带来了很多权力,其中大部分是在公共监督之外偷偷进行的【106】。
|
俗话说,“知识就是力量”。更进一步,“在避免自己被审视的同时审视他人,是权力最重要的形式之一”【105】。这就是极权政府想要监控的原因:这让它们有能力控制全体居民。尽管今天的科技公司并没有公开地寻求政治权力,但是它们积累的数据与知识却给它们带来了很多权力,其中大部分是在公共监督之外偷偷进行的【106】。
|
||||||
|
|
||||||
#### 记着工业革命
|
#### 回顾工业革命
|
||||||
|
|
||||||
数据是信息时代的决定性特征。互联网,数据存储,处理和软件驱动的自动化正在对全球经济和人类社会产生重大影响。我们的日常生活与社会组织在过去十年中发生了变化,而且在未来的十年中可能会继续发生根本性的变化,所以我们会想到与工业革命对比【87,96】。
|
数据是信息时代的决定性特征。互联网,数据存储,处理和软件驱动的自动化正在对全球经济和人类社会产生重大影响。我们的日常生活与社会组织在过去十年中发生了变化,而且在未来的十年中可能会继续发生根本性的变化,所以我们会想到与工业革命对比【87,96】。
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue