Skip to content

Commit

Permalink
Merge branch 'master' into fix-typo
Browse files Browse the repository at this point in the history
  • Loading branch information
Vonng authored Oct 23, 2020
2 parents b3489c9 + 0e640d1 commit 49d3c6e
Show file tree
Hide file tree
Showing 30 changed files with 11,128 additions and 15 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
- 作者: [Martin Kleppmann](https://martin.kleppmann.com)
- 原书名称:[《Designing Data-Intensive Application》](http://shop.oreilly.com/product/0636920032175.do)
- 译者:[冯若航]( http://vonng.com/about)fengruohang@outlook.com
- Gitbook地址:[ddia-cn](https://www.gitbook.com/book/vonng/ddia-cn)
- Gitbook地址:[ddia-cn](https://vonng.gitbooks.io/ddia-cn)
- 使用[Typora](https://www.typora.io)或Gitbook以获取最佳阅读体验。

* [繁體中文版本](zh-tw/README.md)



Expand Down Expand Up @@ -89,6 +90,7 @@
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)
6. 感謝[@afunTW](https://github.com/afunTW)提供繁體中文的版本

https://github.com/Vonng/ddia/pulls)

Expand All @@ -98,4 +100,4 @@ https://github.com/Vonng/ddia/pulls)

## LICENSE

CC-BY 4.0
CC-BY 4.0
13 changes: 13 additions & 0 deletions bin/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
opencc = "*"
click = "*"

[dev-packages]

[requires]
python_version = "3.6"
36 changes: 36 additions & 0 deletions bin/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions bin/translate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Convert zh-cn to zh-tw
Refer to https://github.com/BYVoid/OpenCC
"""
import click
import opencc

from pathlib import Path
from pprint import pprint


@click.group()
def cli():
pass


def convert(infile: str, outfile: str, cfg: str):
"""read >> convert >> write file
Args:
infile (str): input file
outfile (str): output file
cfg (str): config
"""
converter = opencc.OpenCC(cfg)
with open(infile, "r") as inf, open(outfile, "w+") as outf:
data = inf.readlines()
data = list(map(converter.convert, data))
outf.writelines(data)
print(f"Convert to {outfile}")


@cli.command()
@click.option("-i", "--input", "infile", required=True)
@click.option("-o", "--output", "outfile", required=True)
@click.option("-c", "--config", "cfg", required=True, default="s2twp.json")
def file(infile: str, outfile: str, cfg: str):
"""read >> convert >> write file
Args:
infile (str): input file
outfile (str): output file
cfg (str): config
"""
convert(infile, outfile, cfg)


@cli.command()
@click.option("-i", "--input", "infolder", required=True)
@click.option("-o", "--output", "outfolder", required=True)
@click.option("-c", "--config", "cfg", required=True, default="s2twp.json")
def repo(infolder, outfolder, cfg):
if not Path(outfolder).exists():
Path(outfolder).mkdir(parents=True)
print(f"Create {outfolder}")
infiles = Path(infolder).resolve().glob("*.md")
pair = [
{"infile": str(infile), "outfile": str(Path(outfolder).resolve() / infile.name)}
for idx, infile in enumerate(infiles)
]
for p in pair:
convert(p["infile"], p["outfile"], cfg)


if __name__ == "__main__":
cli()
4 changes: 2 additions & 2 deletions ch1.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
​ 另一类错误是内部的**系统性错误(systematic error)**【7】。这类错误难以预料,而且因为是跨节点相关的,所以比起不相关的硬件故障往往可能造成更多的**系统失效**【5】。例子包括:

* 接受特定的错误输入,便导致所有应用服务器实例崩溃的BUG。例如2012年6月30日的闰秒,由于Linux内核中的一个错误,许多应用同时挂掉了。
* 失控进程会占用一些共享资源,包括CPU时间、内存、磁盘空间或网络带宽。
* 失控进程会用尽一些共享资源,包括CPU时间、内存、磁盘空间或网络带宽。
* 系统依赖的服务变慢,没有响应,或者开始返回错误的响应。
* 级联故障,一个组件中的小故障触发另一个组件中的故障,进而触发更多的故障【10】。

Expand Down Expand Up @@ -266,7 +266,7 @@

​ 有些系统是 **弹性(elastic)** 的,这意味着可以在检测到负载增加时自动增加计算资源,而其他系统则是手动扩展(人工分析容量并决定向系统添加更多的机器)。如果负载**极难预测(highly unpredictable)**,则弹性系统可能很有用,但手动扩展系统更简单,并且意外操作可能会更少(参阅“[重新平衡分区](ch6.md#分区再平衡)”)。

​ 跨多台机器部署**无状态服务(stateless services)** 非常简单,但将带状态的数据系统从单节点变为分布式配置则可能引入许多额外复杂度。出于这个原因,常识告诉我们应该将数据库放在单个节点上(纵向扩展),直到扩展成本或可用性需求迫使其改为分布式。
​ 跨多台机器部署 **无状态服务(stateless services)** 非常简单,但将带状态的数据系统从单节点变为分布式配置则可能引入许多额外复杂度。出于这个原因,常识告诉我们应该将数据库放在单个节点上(纵向扩展),直到扩展成本或可用性需求迫使其改为分布式。

​ 随着分布式系统的工具和抽象越来越好,至少对于某些类型的应用而言,这种常识可能会改变。可以预见分布式数据系统将成为未来的默认设置,即使对不处理大量数据或流量的场景也如此。本书的其余部分将介绍多种分布式数据系统,不仅讨论它们在可扩展性方面的表现,还包括易用性和可维护性。

Expand Down
10 changes: 5 additions & 5 deletions ch10.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ top5.each{|count, url| puts "#{count} #{url}" } # 5

​ Hadoop的各种高级工具(如Pig 【30】,Hive 【31】,Cascading 【32】,Crunch 【33】和FlumeJava 【34】)也能自动布线组装多个MapReduce阶段,生成合适的工作流。

### Reduce端连接与分组
### Reduce侧连接与分组

​ 我们在[第2章](ch2.md)中讨论了数据模型和查询语言的联接,但是我们还没有深入探讨连接是如何实现的。现在是我们再次捡起这条线索的时候了。

Expand Down Expand Up @@ -363,7 +363,7 @@ top5.each{|count, url| puts "#{count} #{url}" } # 5



### Map端连接
### Map侧连接

​ 上一节描述的连接算法在Reducer中执行实际的连接逻辑,因此被称为Reduce端连接。Mapper扮演着预处理输入数据的角色:从每个输入记录中提取键值,将键值对分配给Reducer分区,并按键排序。

Expand Down Expand Up @@ -395,13 +395,13 @@ top5.each{|count, url| puts "#{count} #{url}" } # 5

​ 分区散列连接在Hive中称为**Map端桶连接(bucketed map joins)【37】**

#### Map端合并连接
#### Map侧合并连接

​ 如果输入数据集不仅以相同的方式进行分区,而且还基于相同的键进行**排序**,则可适用另一种Map端联接的变体。在这种情况下,输入是否小到能放入内存并不重要,因为这时候Mapper同样可以执行归并操作(通常由Reducer执行)的归并操作:按键递增的顺序依次读取两个输入文件,将具有相同键的记录配对。

​ 如果能进行Map端合并连接,这通常意味着前一个MapReduce作业可能一开始就已经把输入数据做了分区并进行了排序。原则上这个连接就可以在前一个作业的Reduce阶段进行。但使用独立的仅Map作业有时也是合适的,例如,分好区且排好序的中间数据集可能还会用于其他目的。

#### MapReduce工作流与Map端连接
#### MapReduce工作流与Map侧连接

​ 当下游作业使用MapReduce连接的输出时,选择Map端连接或Reduce端连接会影响输出的结构。Reduce端连接的输出是按照**连接键**进行分区和排序的,而Map端连接的输出则按照与较大输入相同的方式进行分区和排序(因为无论是使用分区连接还是广播连接,连接较大输入端的每个文件块都会启动一个Map任务)。

Expand Down Expand Up @@ -909,4 +909,4 @@ top5.each{|count, url| puts "#{count} #{url}" } # 5

| 上一章 | 目录 | 下一章 |
| --------------------------------- | ------------------------------- | ------------------------ |
| [第三部分:派生数据](part-iii.md) | [设计数据密集型应用](README.md) | [第十一章:流处理](ch11.md) |
| [第三部分:派生数据](part-iii.md) | [设计数据密集型应用](README.md) | [第十一章:流处理](ch11.md) |
2 changes: 1 addition & 1 deletion ch2.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ MapReduce是一个由Google推广的编程模型,用于在多台机器上批

MapReduce将[第10章](ch10.md)中有更详细的描述。现在我们将简要讨论一下MongoDB使用的模型。

MapReduce既不是一个声明式的查询语言,也不是一个完全命令式的查询API,而是处于两者之间:查询的逻辑用代码片断来表示,这些代码片段会被处理框架重复性调用。它基于`map`(也称为`collect`)和`reduce`(也称为`fold``inject`)函数,两个函数存在于许多函数式编程语言中。
MapReduce既不是一个声明式的查询语言,也不是一个完全命令式的查询API,而是处于两者之间:查询的逻辑用代码片段来表示,这些代码片段会被处理框架重复性调用。它基于`map`(也称为`collect`)和`reduce`(也称为`fold``inject`)函数,两个函数存在于许多函数式编程语言中。

最好举例来解释MapReduce模型。假设你是一名海洋生物学家,每当你看到海洋中的动物时,你都会在数据库中添加一条观察记录。现在你想生成一个报告,说明你每月看到多少鲨鱼。

Expand Down
4 changes: 2 additions & 2 deletions ch3.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ $ cat database

#### 用SSTables制作LSM树

这里描述的算法本质上是LevelDB 【6】和RocksDB 【7】中使用的关键值存储引擎库,被设计嵌入到其他应用程序中。除此之外,LevelDB可以在Riak中用作Bitcask的替代品。在Cassandra和HBase中使用了类似的存储引擎【8】,这两种引擎都受到了Google的Bigtable文档【9】(引入了SSTable和memtable)的启发。
这里描述的算法本质上是LevelDB 【6】和RocksDB 【7】中使用的键值存储引擎库,被设计嵌入到其他应用程序中。除此之外,LevelDB可以在Riak中用作Bitcask的替代品。在Cassandra和HBase中使用了类似的存储引擎【8】,这两种引擎都受到了Google的Bigtable文档【9】(引入了SSTable和memtable)的启发。

最初这种索引结构是由Patrick O'Neil等人描述的。在日志结构合并树(或LSM树)【10】的基础上,建立在以前的工作上日志结构的文件系统【11】。基于这种合并和压缩排序文件原理的存储引擎通常被称为LSM存储引擎。

Expand Down Expand Up @@ -440,7 +440,7 @@ Teradata,Vertica,SAP HANA和ParAccel等数据仓库供应商通常使用昂

这个模板的变体被称为雪花模式,其中尺寸被进一步分解为子尺寸。例如,品牌和产品类别可能有单独的表格,并且 `dim_product` 表格中的每一行都可以将品牌和类别作为外键引用,而不是将它们作为字符串存储在 `dim_product` 表格中。雪花模式比星形模式更规范化,但是星形模式通常是首选,因为分析师使用它更简单【55】。

在典型的数据仓库中,表格通常非常宽泛:事实表格通常有100列以上,有时甚至有数百列【51】。维度表也可以是非常宽的,因为它们包括可能与分析相关的所有元数据——例如,`dim_store` 表可以包括在每个商店提供哪些服务的细节,它是否具有店内面包房,方形镜头,商店第一次开幕的日期,最后一次改造的时间,离最近的高速公路的距离等等。
在典型的数据仓库中,表格通常非常宽泛:事实表格通常有100列以上,有时甚至有数百列【51】。维度表也可以是非常宽的,因为它们包括可能与分析相关的所有元数据——例如,`dim_store` 表可以包括在每个商店提供哪些服务的细节,它是否具有店内面包房,店面面积,商店第一次开幕的日期,最后一次改造的时间,离最近的高速公路的距离等等。



Expand Down
2 changes: 1 addition & 1 deletion ch7.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ SELECT COUNT(*)FROM emails WHERE recipient_id = 2 AND unread_flag = true

### 快照隔离和可重复读

如果只从表面上看读已提交隔离级别你就认为它完成了事务所需的一切,那是可以原谅的。它允许**中止**(原子性的要求);它防止读取不完整的事务结果,并且防止并发写入造成的混合。事实上这些功能非常有用,比起没有事务的系统来,可以提供更多的保证。
如果只从表面上看读已提交隔离级别你就认为它完成了事务所需的一切,那是可以原谅的。它允许**中止**(原子性的要求);它防止读取不完整的事务结果,并且防止并发写入造成的混乱。事实上这些功能非常有用,比起没有事务的系统来,可以提供更多的保证。

但是在使用此隔离级别时,仍然有很多地方可能会产生并发错误。例如[图7-6](img/fig7-6.png)说明了读已提交时可能发生的问题。

Expand Down
4 changes: 2 additions & 2 deletions ch9.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

​ 现在我们将继续沿着同样的路线前进,寻求可以让应用忽略分布式系统部分问题的抽象概念。例如,分布式系统最重要的抽象之一就是**共识(consensus)****就是让所有的节点对某件事达成一致**。正如我们在本章中将会看到的那样,尽管存在网络故障和流程故障,可靠地达成共识是一个令人惊讶的棘手问题。

​ 一旦达成共识,应用可以将其用于各种目的。例如,假设你有一个单主复制的数据库。如果领导者挂掉,并且需要故障切换到另一个节点,剩余的数据库节点可以使用共识来选举新的领导者。正如在“[处理节点宕机](ch5.md#处理节点宕机)”中所讨论的那样,重要的是只有一个领导者,且所有的节点都认同其领导。如果两个节点都认为自己是领导者,这种情况被称为**脑裂(split brain)**,且经常导致数据丢失。正确实现共识有助于避免这种问题。
​ 一旦达成共识,应用可以将其用于各种目的。例如,假设你有一个单主复制的数据库。如果主库挂掉,并且需要故障切换到另一个节点,剩余的数据库节点可以使用共识来选举新的领导者。正如在“[处理节点宕机](ch5.md#处理节点宕机)”中所讨论的那样,重要的是只有一个领导者,且所有的节点都认同其领导。如果两个节点都认为自己是领导者,这种情况被称为**脑裂(split brain)**,且经常导致数据丢失。正确实现共识有助于避免这种问题。

​ 在本章后面的“[分布式事务和共识](#分布式事务和共识)”中,我们将研究解决共识和相关问题的算法。但首先,我们首先需要探索可以在分布式系统中提供的保证和抽象的范围。

Expand Down Expand Up @@ -73,7 +73,7 @@
​ 线性一致性背后的基本思想很简单:使系统看起来好像只有一个数据副本。然而确切来讲,实际上有更多要操心的地方。为了更好地理解线性一致性,让我们再看几个例子。

[图9-2](img/fig9-2.png) 显示了三个客户端在线性一致数据库中同时读写相同的键`x`。在分布式系统文献中,`x`被称为**寄存器(register)**,例如,它可以是键值存储中的一个****,关系数据库中的一****,或文档数据库中的一个**文档**

![](img/fig9-2.png)

**图9-2 如果读取请求与写入请求并发,则可能会返回旧值或新值**
Expand Down
Loading

0 comments on commit 49d3c6e

Please sign in to comment.