Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed redundant section numbering, replaced some watermarked images, and changed the citation format for images. #24

Merged
merged 4 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ subtrees:
entries:
- file: ch-big-data-intro/index
entries:
- file: ch-big-data-intro/bigdata
- file: ch-big-data-intro/sec-bigdata
- file: ch-big-data-intro/batch-stream
- file: ch-big-data-intro/technologies
- file: ch-big-data-intro/evolution
Expand Down Expand Up @@ -40,9 +40,9 @@ subtrees:
- file: ch-time-window/exercise-stock
- file: ch-state-checkpoint/index
entries:
- file: ch-state-checkpoint/state
- file: ch-state-checkpoint/checkpoint
- file: ch-state-checkpoint/savepoint
- file: ch-state-checkpoint/state
- file: ch-state-checkpoint/exercise-state
- file: ch-flink-connectors/index
entries:
Expand Down
8 changes: 4 additions & 4 deletions doc/ch-big-data-intro/batch-stream.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

## 数据与数据流

在大数据的 5 个 “V” 中我们已经提到,数据量大且产生速度快。从时间维度来讲,数据源源不断地产生,形成一个无界的数据流(Unbounded Data Stream)。如 {numref}`data-and-data-stream` 所示,单条数据被称为事件(Event),事件按照时序排列会形成一个数据流。例如,我们每时每刻的运动数据都会累积到手机传感器上,金融交易随时随地都在发生,物联网(Internet of Things,IoT)传感器会持续监控并生成数据。
在大数据的 5 个 “V” 中我们已经提到,数据量大且产生速度快。从时间维度来讲,数据源源不断地产生,形成一个无界的数据流(Unbounded Data Stream)。如 {numref}`fig-data-and-data-stream` 所示,单条数据被称为事件(Event),事件按照时序排列会形成一个数据流。例如,我们每时每刻的运动数据都会累积到手机传感器上,金融交易随时随地都在发生,物联网(Internet of Things,IoT)传感器会持续监控并生成数据。

```{figure} ./img/data-and-data-stream.png
---
width: 60%
name: data-and-data-stream
name: fig-data-and-data-stream
---
数据和数据流
```
Expand Down Expand Up @@ -39,12 +39,12 @@ name: data-and-data-stream

### 生产者 - 消费者模型

处理流数据一般使用 “生产者 - 消费者”(Producer-Consumer)模型来解决问题。如 {numref}`producer-consumer` 所示,生产者生成数据,将数据发送到一个缓存区域(Buffer),消费者从缓存区域中消费数据。这里我们暂且不关心生产者如何生产数据,以及数据如何缓存,我们只关心如何实现消费者。
处理流数据一般使用 “生产者 - 消费者”(Producer-Consumer)模型来解决问题。如 {numref}`fig-producer-consumer` 所示,生产者生成数据,将数据发送到一个缓存区域(Buffer),消费者从缓存区域中消费数据。这里我们暂且不关心生产者如何生产数据,以及数据如何缓存,我们只关心如何实现消费者。

```{figure} ./img/producer-consumer.png
---
width: 60%
name: producer-consumer
name: fig-producer-consumer
---
生产者 - 消费者模型
```
Expand Down
8 changes: 4 additions & 4 deletions doc/ch-big-data-intro/evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

## Lambda 架构

当以 Storm 为代表的第一代流处理框架成熟后,一些互联网公司为了兼顾数据的实时性和准确性,采用 {numref}`lambda-architecture` 所示的 Lambda 架构来处理数据并提供在线服务。Lambda 架构主要分为 3 部分:批处理层、流处理层和在线服务层。其中数据流来自 Kafka 这样的消息队列。
当以 Storm 为代表的第一代流处理框架成熟后,一些互联网公司为了兼顾数据的实时性和准确性,采用 {numref}`fig-lambda-architecture` 所示的 Lambda 架构来处理数据并提供在线服务。Lambda 架构主要分为 3 部分:批处理层、流处理层和在线服务层。其中数据流来自 Kafka 这样的消息队列。

```{figure} ./img/lambda.png
---
width: 60%
name: lambda-architecture
name: fig-lambda-architecture
---
Lambda 架构
```
Expand Down Expand Up @@ -43,12 +43,12 @@ Lambda 架构

## Kappa 架构

Kafka 的创始人杰•克雷普斯认为在很多场景下,维护一套 Lambda 架构的大数据处理平台耗时耗力,于是提出在某些场景下,没有必要维护一个批处理层,直接使用一个流处理层即可满足需求,即 {numref}`kappa-architecture` 所示的 Kappa 架构。
Kafka 的创始人杰•克雷普斯认为在很多场景下,维护一套 Lambda 架构的大数据处理平台耗时耗力,于是提出在某些场景下,没有必要维护一个批处理层,直接使用一个流处理层即可满足需求,即 {numref}`fig-kappa-architecture` 所示的 Kappa 架构。

```{figure} ./img/kappa.png
---
width: 60%
name: kappa-architecture
name: fig-kappa-architecture
---
Kappa 架构
```
Expand Down
2 changes: 1 addition & 1 deletion doc/ch-big-data-intro/exercise-stream-with-kafka.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

### 消息队列的功能

消息队列一般使用{numref}`producer-consumer` 所示的 “生产者 - 消费者” 模型来解决问题:生产者生成数据,将数据发送到一个缓存区域,消费者从缓存区域中消费数据。消息队列可以解决以下问题:
消息队列一般使用{numref}`fig-producer-consumer` 所示的 “生产者 - 消费者” 模型来解决问题:生产者生成数据,将数据发送到一个缓存区域,消费者从缓存区域中消费数据。消息队列可以解决以下问题:

- 系统解耦:很多企业内部有众多系统,一个 App 也包含众多模块,如果将所有的系统和模块都放在一起作为一个庞大的系统来开发,未来则会很难维护和扩展。如果将各个模块独立出来,模块之间通过消息队列来通信,未来可以轻松扩展每个独立模块。另外,假设没有消息队列,M 个生产者和 N 个消费者通信,会产生 M×N 个数据管道,消息队列将这个复杂度降到了 M+N。
- 异步处理:同步是指如果模块 A 向模块 B 发送消息,必须等待返回结果后才能执行接下来的业务逻辑。异步是消息发送方模块 A 无须等待返回结果即可继续执行,只需要向消息队列中发送消息,至于谁去处理这些消息、消息等待多长时间才能被处理等一系列问题,都由消费者负责。异步处理更像是发布通知,发送方不用关心谁去接收通知、如何对通知做出响应等问题。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
(bigdata)=
(sec-bigdata)=
# 什么是大数据

## 大数据的 5 个 “V”

大数据,顾名思义,就是拥有庞大体量的数据。关于什么是大数据、如何定义大数据、如何使用大数据等一系列问题,拥有不同领域背景的读者的理解各不相同。通常,业界将大数据的特点归纳为 {numref}`5v` 所示的 5 个 “V”。
大数据,顾名思义,就是拥有庞大体量的数据。关于什么是大数据、如何定义大数据、如何使用大数据等一系列问题,拥有不同领域背景的读者的理解各不相同。通常,业界将大数据的特点归纳为 {numref}`fig-5V` 所示的 5 个 “V”。

```{figure} ./img/5V.png
---
width: 60%
name: 5v
name: fig-5V
---
大数据的 5 个 "V"
```
Expand All @@ -31,12 +31,12 @@ name: 5v

计算机诞生之后,一般是在单台计算机上处理数据。大数据时代到来后,一些传统的数据处理方法无法满足大数据的处理需求。将一组计算机组织到一起形成一个集群,利用集群的力量来处理大数据的工程实践逐渐成为主流。这种使用集群进行计算的方式被称为分布式计算,当前几乎所有的大数据系统都在使用集群进行分布式计算。

分布式计算的概念听起来很高深,其背后的思想却十分朴素,即分而治之,又称为分治法(Divide and Conquer)。如图 {numref}`divide-conquer` 所示,分治法是指将一个原始问题分解为多个子问题,多个子问题分别在多台计算机上求解,借助必要的数据交换和合并策略,将子结果汇总即可求出最终结果的方法。具体而言,不同的分布式系统使用的算法和策略根据所要解决的问题各有不同,但基本上都是将计算拆分,把子问题放到多台计算机上,分而治之地计算求解。分布式计算的每台计算机(物理机或虚拟机)又被称为一个节点。
分布式计算的概念听起来很高深,其背后的思想却十分朴素,即分而治之,又称为分治法(Divide and Conquer)。如图 {numref}`fig-divide-conquer` 所示,分治法是指将一个原始问题分解为多个子问题,多个子问题分别在多台计算机上求解,借助必要的数据交换和合并策略,将子结果汇总即可求出最终结果的方法。具体而言,不同的分布式系统使用的算法和策略根据所要解决的问题各有不同,但基本上都是将计算拆分,把子问题放到多台计算机上,分而治之地计算求解。分布式计算的每台计算机(物理机或虚拟机)又被称为一个节点。

```{figure} ./img/divide-conquer.png
---
width: 60%
name: divide-conquer
name: fig-divide-conquer
---
分治法
```
Expand All @@ -45,12 +45,12 @@ name: divide-conquer

### MPI

MPI 是一个 “老牌” 分布式计算框架,从 MPI 这个名字也可以看出,MPI 主要解决节点间数据通信的问题。在前 MapReduce 时代,MPI 是分布式计算的业界标准。MPI 现在依然广泛运用于全球各大超级计算中心、大学、研究机构中,许多物理、生物、化学、能源等基础学科的大规模分布式计算都依赖 MPI。{numref}`mpi`所示为使用 MPI 在 4 台服务器上并行计算的示意图。
MPI 是一个 “老牌” 分布式计算框架,从 MPI 这个名字也可以看出,MPI 主要解决节点间数据通信的问题。在前 MapReduce 时代,MPI 是分布式计算的业界标准。MPI 现在依然广泛运用于全球各大超级计算中心、大学、研究机构中,许多物理、生物、化学、能源等基础学科的大规模分布式计算都依赖 MPI。{numref}`fig-mpi`所示为使用 MPI 在 4 台服务器上并行计算的示意图。

```{figure} ./img/mpi.png
---
width: 60%
name: mpi
name: fig-mpi
---
在 4 台服务器上使用 MPI 进行并行计算
```
Expand All @@ -69,14 +69,14 @@ MPI 能够以很细的粒度控制数据的通信,这是它的优势,从某

比起 MPI,MapReduce 编程模型将更多的中间过程做了封装,程序员只需要将原始问题转化为更高层次的应用程序接口(Application Programming Interface,API),至于原始问题如何分解为更小的子问题、中间数据如何传输和交换、如何将计算扩展到多个节点等一系列细节问题可以交给大数据编程模型来解决。因此,MapReduce 相对来说学习门槛更低,使用更方便,编程开发速度更快。

{numref}`mapreduce-sandwichs` 所示为使用 MapReduce 思想制作三明治的过程,读者可以通过这幅图更好的理解 MapReduce。
{numref}`fig-mapreduce-sandwichs` 所示为使用 MapReduce 思想制作三明治的过程,读者可以通过这幅图更好的理解 MapReduce。

假设我们需要大批量地制作三明治,三明治的每种食材可以分别单独处理,Map 阶段将原材料在不同的节点上分别进行处理,生成一些中间食材,Shuffle/Group 阶段将不同的中间食材进行组合,Reduce 阶段最终将一组中间食材组合成三明治成品。可以看到,这种 Map + Shuffle/Group + Reduce 的方式就是分治法的一种实现。

```{figure} ./img/mapreduce-sandwichs.jpeg
---
width: 60%
name: mapreduce-sandwichs
name: fig-mapreduce-sandwichs
---
使用 MapReduce 制作三明治的过程
```
Expand Down
18 changes: 9 additions & 9 deletions doc/ch-big-data-intro/stream-processing-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@

比起批处理,流处理对窗口(Window)和时间概念更为敏感。在批处理场景下,数据已经按照某个时间维度被分批次地存储了。一些公司经常将用户行为日志按天存储,一些开放数据集都会说明数据采集的时间始末。因此,对于批处理任务,处理一个数据集,其实就是对该数据集对应的时间窗口内的数据进行处理。在流处理场景下,数据以源源不断的流的形式存在,数据一直在产生,没有始末。我们要对数据进行处理时,往往需要明确一个时间窗口,比如,数据在 “每秒”“每小时”“每天” 的维度下的一些特性。窗口将数据流切分成多个数据块,很多数据分析都是在窗口上进行操作,比如连接、聚合以及其他时间相关的操作。

{numref}`three-type-window` 展示了 3 种常见的窗口形式:滚动窗口、滑动窗口、会话窗口。
{numref}`fig-three-type-window` 展示了 3 种常见的窗口形式:滚动窗口、滑动窗口、会话窗口。

```{figure} ./img/three-type-window.png
---
width: 60%
name: three-type-window
name: fig-three-type-window
---
3 种常见的窗口形式
```

- **滚动窗口(Tumbling Window)**:模式一般定义一个固定的窗口长度,长度是一个时间间隔,比如小时级的窗口或分钟级的窗口。窗口像车轮一样,滚动向前,任意两个窗口之间不会包含同样的数据。
- **滑动窗口(Sliding Window)**:模式也设有一个固定的窗口长度。假如我们想每分钟开启一个窗口,统计 10 分钟内的股票价格波动,就使用滑动窗口模式。当窗口的长度大于滑动的间隔,可能会导致两个窗口之间包含同样的事件。其实,滚动窗口模式是滑动窗口模式的一个特例,滚动窗口模式中滑动的间隔正好等于窗口的大小。
- **会话窗口(Session Window)**:模式的窗口长度不固定,而是通过一个间隔来确定窗口,这个间隔被称为会话间隔(Session Gap)。当两个事件之间的间隔大于会话间隔,则两个事件被划分到不同的窗口中;当事件之间的间隔小于会话间隔,则两个事件被划分到同一窗口。
- 滚动窗口(Tumbling Window):模式一般定义一个固定的窗口长度,长度是一个时间间隔,比如小时级的窗口或分钟级的窗口。窗口像车轮一样,滚动向前,任意两个窗口之间不会包含同样的数据。
- 滑动窗口(Sliding Window):模式也设有一个固定的窗口长度。假如我们想每分钟开启一个窗口,统计 10 分钟内的股票价格波动,就使用滑动窗口模式。当窗口的长度大于滑动的间隔,可能会导致两个窗口之间包含同样的事件。其实,滚动窗口模式是滑动窗口模式的一个特例,滚动窗口模式中滑动的间隔正好等于窗口的大小。
- 会话窗口(Session Window):模式的窗口长度不固定,而是通过一个间隔来确定窗口,这个间隔被称为会话间隔(Session Gap)。当两个事件之间的间隔大于会话间隔,则两个事件被划分到不同的窗口中;当事件之间的间隔小于会话间隔,则两个事件被划分到同一窗口。

### 时间语义

Expand All @@ -56,12 +56,12 @@ name: three-type-window

#### “一分钟” 真的是一分钟吗?

在很多应用场景中,时间有着不同的语义,“一分钟” 真的是一分钟吗?很多手机游戏中多玩家在线实时竞技,假设我们在玩某款手机游戏,该游戏将数据实时发送给游戏服务器,服务器计算一分钟内玩家的一些操作,这些计算影响用户该局游戏的最终得分。当游戏正酣,我们进入了电梯,手机信号丢失,一分钟后才恢复信号;幸好手机在电梯期间缓存了掉线时的数据,并在信号恢复后将缓存数据传回了服务器,{numref}`data-transmission-signal-loss` 展示了这个场景的流处理过程。在丢失信号的这段时间,你的数据没有被计算进去,显然这样的计算不公平。当信号恢复时,数据重传到服务器,再根据 Event Time 重新计算一次,那就非常公平了。我们可以根据 Event Time 复现一个事件序列的实际顺序。因此,使用 Event Time 是最准确的。
在很多应用场景中,时间有着不同的语义,“一分钟” 真的是一分钟吗?很多手机游戏中多玩家在线实时竞技,假设我们在玩某款手机游戏,该游戏将数据实时发送给游戏服务器,服务器计算一分钟内玩家的一些操作,这些计算影响用户该局游戏的最终得分。当游戏正酣,我们进入了电梯,手机信号丢失,一分钟后才恢复信号;幸好手机在电梯期间缓存了掉线时的数据,并在信号恢复后将缓存数据传回了服务器,{numref}`fig-data-transmission-signal-loss` 展示了这个场景的流处理过程。在丢失信号的这段时间,你的数据没有被计算进去,显然这样的计算不公平。当信号恢复时,数据重传到服务器,再根据 Event Time 重新计算一次,那就非常公平了。我们可以根据 Event Time 复现一个事件序列的实际顺序。因此,使用 Event Time 是最准确的。

```{figure} ./img/signal.png
---
width: 60%
name: data-transmission-signal-loss
name: fig-data-transmission-signal-loss
---
数据传输过程恰好遇到信号丢失
```
Expand All @@ -76,12 +76,12 @@ Watermark 是一种折中解决方案,它假设某个时间点上,不会有

## 状态与检查点

状态是流处理区别于批处理的特有概念。如果我们对一个文本数据流进行处理,把英文大写字母都改成英文小写字母,这种处理是无状态的,即系统不需要记录额外的信息。如果我们想统计这个数据流一分钟内的单词出现次数,一方面要处理每一瞬间新流入的数据,另一方面要保存之前一分钟内已经进入系统的数据,额外保存的数据就是状态。{numref}`state-stateless` 展示了无状态和有状态两种不同类型的计算。
状态是流处理区别于批处理的特有概念。如果我们对一个文本数据流进行处理,把英文大写字母都改成英文小写字母,这种处理是无状态的,即系统不需要记录额外的信息。如果我们想统计这个数据流一分钟内的单词出现次数,一方面要处理每一瞬间新流入的数据,另一方面要保存之前一分钟内已经进入系统的数据,额外保存的数据就是状态。{numref}`fig-state-stateless` 展示了无状态和有状态两种不同类型的计算。

```{figure} ./img/state-stateless.png
---
width: 60%
name: state-stateless
name: fig-state-stateless
---
无状态计算和有状态计算
```
Expand Down
Loading
Loading