Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Vonng authored Mar 24, 2018
2 parents 4fdcb25 + 7580e80 commit b1bf5d1
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 173 deletions.
62 changes: 37 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@
- 作者: [Martin Kleppmann](https://martin.kleppmann.com)
- 原书名称:[《Designing Data-Intensive Application》](http://shop.oreilly.com/product/0636920032175.do)
- 译者:[冯若航]( http://vonng.com/about)[email protected]
- Gitbook地址:[ddia-cn](https://www.gitbook.com/book/vonng/ddia-cn)(需要科学上网)
- 建议使用[Typora](https://www.typora.io)或Gitbook以获取最佳阅读体验。

-------------


## 法律声明

译者纯粹出于学习目的与个人兴趣翻译,本译文只供学习研究参考之用,不得公开传播发行或用于商业用途。有能力阅读英文书籍者请购买正版支持。
从原作者处得知,已经有简体中文的翻译计划,将于2018年末完成。

译者纯粹出于**学习目的****个人兴趣**翻译本书,不追求任何经济利益。

译者保留对此版本译文的署名权,其他权利以原作者和出版社的主张为准。

本译文只供学习研究参考之用,不得公开传播发行或用于商业用途。有能力阅读英文书籍者请购买正版支持。


译者保留对译文的署名权,其他权利以原作者和出版社的主张为准,侵删。

## 译序

Expand Down Expand Up @@ -51,24 +58,24 @@

### [数据系统的基石](part-i.md)

1. [可靠性、可扩展性、可维护性](ch1.md)
2. [数据模型与查询语言](ch2.md)
3. [存储与检索](ch3.md)
4. [编码与演化](ch4.md)
* [第一章:可靠性、可扩展性、可维护性](ch1.md)
* [第二章:数据模型与查询语言](ch2.md)
* [第三章:存储与检索](ch3.md)
* [第四章:编码与演化](ch4.md)

### [分布式数据](part-ii.md)

1. [复制](ch5.md)
2. [分片](ch6.md)
3. [事务](ch7.md)
4. [分布式系统的麻烦](ch8.md)
5. [一致性与共识](ch9.md)
* [第五章:复制](ch5.md)
* [第六章:分区](ch6.md)
* [第七章:事务](ch7.md)
* [第八章:分布式系统的麻烦](ch8.md)
* [第九章:一致性与共识](ch9.md)

### [派生数据](part-iii.md)

1. [批处理](ch10.md)
2. [流处理](ch11.md)
3. [数据系统的未来](ch12.md)
* [第十章:批处理](ch10.md)
* [第十一章:流处理](ch11.md)
* [第十二章:数据系统的未来](ch12.md)

### [术语表](glossary.md)

Expand All @@ -82,9 +89,7 @@

* 机翻:只在乎结构:梳理文章结构、图片、引用、备注。
* 初翻:保证经完全理解本章内容,人工修复显著的错误,重新组织语言。
* 精翻:阅读相关领域文献书籍,确定术语的最终译法,修复格式瑕疵,着力信达雅。

通常机翻一章1个小时左右,初翻一章6小时,精翻一章三到五天。
* 精校:阅读相关领域文献书籍,确定术语的最终译法,修复格式瑕疵,着力信达雅。

精翻可以看,机翻基本没法看,初翻对于业内人士能凑合看。

Expand All @@ -97,9 +102,9 @@
| 第三章:存储与检索 | 初翻 | |
| 第四章:编码与演化 | 初翻 | |
| 第二部分:分布式数据——概览 | 精翻 | |
| 第五章:复制 | 精翻 30% | |
| 第六章:分片 | 初翻 | |
| 第七章:事务 | 精翻 60% | |
| 第五章:复制 | 精翻 30% | Vonng |
| 第六章:分区 | 初翻 | |
| 第七章:事务 | 精翻 60% | Vonng |
| 第八章:分布式系统中的问题 | 初翻 | |
| 第九章:一致性与共识 | 初翻 30% | Vonng |
| 第三部分:前言 | 精翻 | |
Expand All @@ -110,17 +115,24 @@
| 后记 | 机翻 | |


计划在3月25日前完成所有章节的初翻
计划在3月内完成所有章节的初翻



## CONTRIBUTION

欢迎贡献,初翻后的章节,接受ISSUE指正。
欢迎贡献

整章的翻译、精校请使用PR,将列入译者署名,少量词法、语法、译法问题请使用ISSUE,将列入致谢。

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)


贡献者需要同意[法律声明](#法律声明)所叙内容,翻译请提前联系以免冲突。

有人建议拉个群,也许发布更新通知或者同步翻译进度吧
## 译读者交流微信群

![](img/ddia-wexin.JPG)

Expand Down
2 changes: 1 addition & 1 deletion SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* [第四章:编码与演化](ch4.md)
* [第二部分:分布式数据](part-ii.md)
* [第五章:复制](ch5.md)
* [第六章:分片](ch6.md)
* [第六章:分区](ch6.md)
* [第七章:事务](ch7.md)
* [第八章:分布式系统的麻烦](ch8.md)
* [第九章:一致性与共识](ch9.md)
Expand Down
2 changes: 1 addition & 1 deletion ch5.md
Original file line number Diff line number Diff line change
Expand Up @@ -919,4 +919,4 @@ LWW实现了最终收敛的目标,但以**持久性**为代价:如果同一

| 上一章 | 目录 | 下一章 |
| :--------------------------------: | :-----------------------------: | :--------------------: |
| [第二部分:分布式数据](part-ii.md) | [设计数据密集型应用](README.md) | [第六章:分片](ch6.md) |
| [第二部分:分布式数据](part-ii.md) | [设计数据密集型应用](README.md) | [第六章:分区](ch6.md) |
31 changes: 18 additions & 13 deletions ch6.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![](img/ch6.png)

> 我们必须跳出电脑指令序列的窠臼。 叙述定义、提供数据的描述和优先级、梳理关系,而不是编写过程。
> 我们必须跳出电脑指令序列的窠臼。 叙述定义、描述元数据、梳理关系,而不是编写过程。
>
> —— Grace Murray Hopper,未来的计算机及其管理(1962)
>
Expand All @@ -11,9 +11,9 @@

[TOC]

[第5章](ch5.md)中,我们讨论了复制 - 即数据在不同节点上的副本,对于非常大的数据集,或非常高的吞吐量,仅仅进行复制是不够的:我们需要将数据进行**分区(partitions)**,也称为**分片(sharding)**[^i]
[第5章](ch5.md)中,我们讨论了复制——即数据在不同节点上的副本,对于非常大的数据集,或非常高的吞吐量仅仅进行复制是不够的:我们需要将数据进行**分区(partitions)**,也称为**分片(sharding)**[^i]

[^i]: 正如本章所讨论的,分区是一种有意将大型数据库分解成小型数据库的方式。它与网络分区(net splits)无关,这是节点之间网络中的一种故障类型。我们将在第8章讨论这些错误
[^i]: 正如本章所讨论的,分区是一种有意将大型数据库分解成小型数据库的方式。它与**网络分区(net splits)**无关,这是节点之间网络中的一种故障类型。我们将在[第8章](ch8.md)讨论这些错误

> ##### 术语澄清
>
Expand All @@ -22,13 +22,13 @@
通常情况下,每条数据(每条记录,每行或每个文档)属于且仅属于一个分区。有很多方法可以实现这一点,本章将进行深入讨论。实际上,每个分区都是自己的小型数据库,尽管数据库可能支持同时进行多个分区的操作。

分区主要为了**可扩展性**。不同的分区可以放在不共享集群中的不同节点上(参阅[第二部分](part-ii.md)关于[无共享架构](part-ii.md#无共享架构)的定义)。因此,大数据集可以分布在多个磁盘上,并且查询负载可以分布在多个处理器上。
分区主要是为了**可扩展性**。不同的分区可以放在不共享集群中的不同节点上(参阅[第二部分](part-ii.md)关于[无共享架构](part-ii.md#无共享架构)的定义)。因此,大数据集可以分布在多个磁盘上,并且查询负载可以分布在多个处理器上。

对于在单个分区上运行的查询,每个节点可以独立执行对其自己的分区的查询,因此可以通过添加更多的节点来扩大查询吞吐量。大型,复杂的查询可能会跨越多个节点并行处理,尽管这也带来了新的困难。
对于在单个分区上运行的查询,每个节点可以独立执行对自己的查询,因此可以通过添加更多的节点来扩大查询吞吐量。大型,复杂的查询可能会跨越多个节点并行处理,尽管这也带来了新的困难。

分区数据库在20世纪80年代由Teradata和NonStop SQL【1】等产品率先推出,最近因为NoSQL数据库和基于Hadoop的数据仓库重新被关注。有些系统是为事务性工作设计的,有些系统则用于分析(参阅“[事务处理或分析]”):这种差异会影响系统的运作方式,但是分区的基本原理均适用于这两种工作方式。

在本章中,我们将首先介绍分割大型数据集的不同方法,并观察索引如何与分区配合。然后我们将讨论[再平衡](),如果想要添加或删除群集中的节点,则必须进行再平衡。最后,我们将概述数据库如何将请求路由到正确的分区并执行查询。
在本章中,我们将首先介绍分割大型数据集的不同方法,并观察索引如何与分区配合。然后我们将讨论[重新平衡分区](#重新平衡分区),如果想要添加或删除群集中的节点,则必须进行再平衡。最后,我们将概述数据库如何将请求路由到正确的分区并执行查询。

## 分区与复制

Expand Down Expand Up @@ -111,7 +111,9 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使

也许在将来,数据系统将能够自动检测和补偿偏斜的工作负载;但现在,您需要自己来权衡。

## 分区与次级索引

## 分片与次级索引


到目前为止,我们讨论的分区方案依赖于键值数据模型。如果只通过主键访问记录,我们可以从该键确定分区,并使用它来将读写请求路由到负责该键的分区。

Expand All @@ -123,7 +125,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使

### 按文档的二级索引

假设您正在经营一个销售二手车的网站(如图6-4所示)。 每个列表都有一个唯一的ID - 称之为文档ID - 并且用文档ID对数据库进行分区(例如,分区0中的ID为 0到499,分区1中的ID为500到999等)。
假设你正在经营一个销售二手车的网站(如[图6-4](img/fig6-4.png)所示)。 每个列表都有一个唯一的ID——称之为文档ID——并且用文档ID对数据库进行分区(例如,分区0中的ID 0到499,分区1中的ID 500到999等)。

你想让用户搜索汽车,允许他们通过颜色和厂商过滤,所以需要一个在颜色和厂商上的次级索引(文档数据库中这些是**字段(field)**,关系数据库中这些是**列(column)** )。 如果您声明了索引,则数据库可以自动执行索引[^ii]。例如,无论何时将红色汽车添加到数据库,数据库分区都会自动将其添加到索引条目`color:red`的文档ID列表中。

Expand All @@ -135,15 +137,17 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使

在这种索引方法中,每个分区是完全独立的:每个分区维护自己的二级索引,仅覆盖该分区中的文档。它不关心存储在其他分区的数据。无论何时您需要写入数据库(添加,删除或更新文档),只需处理包含您正在编写的文档ID的分区即可。出于这个原因,**文档分区索引**也被称为**本地索引(local index)**(而不是将在下一节中描述的**全局索引(global index)**)。

但是,从文档分区索引中读取需要注意:除非您对文档ID做了特别的处理,否则没有理由将所有具有特定颜色或特定品牌的汽车放在同一个分区中。在图6-4中,红色汽车出现在分区0和分区1中。因此,如果要搜索红色汽车,则需要将查询发送到所有分区,并合并所有返回的结果。
但是,从文档分区索引中读取需要注意:除非您对文档ID做了特别的处理,否则没有理由将所有具有特定颜色或特定品牌的汽车放在同一个分区中。在[图6-4](img/fig6-4.png)中,红色汽车出现在分区0和分区1中。因此,如果要搜索红色汽车,则需要将查询发送到所有分区,并合并所有返回的结果。


这种查询分区数据库的方法有时被称为**分散/聚集(scatter/gather)**,并且可能会使二级索引上的读取查询相当昂贵。即使并行查询分区,分散/聚集也容易导致尾部延迟放大(参阅“[实践中的百分位点](ch1.md#实践中的百分位点)”)。然而,它被广泛使用:MonDBDB,Riak 【15】,Cassandra 【16】,Elasticsearch 【17】,SolrCloud 【18】和VoltDB 【19】都使用文档分区二级索引。大多数数据库供应商建议您构建一个能从单个分区提供二级索引查询的分区方案,但这并不总是可行,尤其是当在单个查询中使用多个二级索引时(例如同时需要按颜色和制造商查询)。

这种查询分区数据库的方法有时被称为**分散/聚集(scatter/gather)**,并且可能会使二级索引上的读取查询相当昂贵。即使您并行查询分区,分散/聚集也容易导致尾部延迟放大(请参阅第16页的“实践中的百分比”)。然而,它被广泛使用:MongoDB,Riak 【15】,Cassandra 【16】,Elasticsearch 【17】,SolrCloud 【18】和VoltDB 【19】,都使用文档分区二级索引。大多数数据库供应商建议您构建一个能从单个分区提供二级索引查询的分区方案,但这并不总是可行,尤其是当在单个查询中使用多个二级索引时(例如同时需要按颜色和制造商查询)。

### 根据关键词(Term)的二级索引

我们可以构建一个覆盖所有分区数据的**全局索引**,而不是给每个分区创建自己的次级索引(本地索引)。但是,我们不能只把这个索引存储在一个节点上,因为它可能会成为瓶颈,违背了分区的目的。全局索引也必须进行分区,但可以采用与主键不同的分区方式。

[图6-5](img/fig6-5.png)阐述了这可能是什么样子:来自所有分区的红色汽车在红色索引中,并且索引是分区的,首字母从a到r的颜色在分区0中,s到z的在分区1。汽车制造商的索引也与之类似(分区边界在f和h之间)。
[图6-5](img/fig6-5.png)阐述了这可能是什么样子:来自所有分区的红色汽车在红色索引中,并且索引是分区的,首字母从`a``r`的颜色在分区0中,`s``z`的在分区1。汽车制造商的索引也与之类似(分区边界在`f``h`之间)。

![](img/fig6-5.png)

Expand Down Expand Up @@ -177,6 +181,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
* 再平衡发生时,数据库应该继续接受读取和写入。
* 节点之间只移动必须的数据,以便快速再平衡,并减少网络和磁盘I/O负载。


### 平衡策略

有几种不同的分区分配方法【23】,让我们依次简要讨论一下。
Expand All @@ -187,7 +192,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使

也许你想知道为什么我们不使用***mod***(许多编程语言中的%运算符)。例如,`hash(key) mod 10`会返回一个介于0和9之间的数字(如果我们将散列写为十进制数,散列模10将是最后一个数字)。如果我们有10个节点,编号为0到9,这似乎是将每个键分配给一个节点的简单方法。

模N方法的问题是,如果节点数量N发生变化,大多数密钥将需要从一个节点移动到另一个节点。例如,假设$hash(key)=123456$。如果最初有10个节点,那么这个键一开始放在节点6上(因为$123456\ mod\ 10 = 6$)。当您增长到11个节点时,密钥需要移动到节点3($123456\ mod\ 11 = 3$),当您增长到12个节点时,需要移动到节点0($123456\ mod\ 12 = 0$)。这种频繁的移动使再平衡的过程过于昂贵
模$N$方法的问题是,如果节点数量N发生变化,大多数密钥将需要从一个节点移动到另一个节点。例如,假设$hash(key)=123456$。如果最初有10个节点,那么这个键一开始放在节点6上(因为$123456\ mod\ 10 = 6$)。当您增长到11个节点时,密钥需要移动到节点3($123456\ mod\ 11 = 3$),当您增长到12个节点时,需要移动到节点0($123456\ mod\ 12 = 0$)。这种频繁的举动使得重新平衡过于昂贵

我们需要一种只移动必需数据的方法。

Expand Down Expand Up @@ -227,7 +232,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使

通过动态分区,分区的数量与数据集的大小成正比,因为拆分和合并过程将每个分区的大小保持在固定的最小值和最大值之间。另一方面,对于固定数量的分区,每个分区的大小与数据集的大小成正比。在这两种情况下,分区的数量都与节点的数量无关。

Cassandra和Ketama使用的第三种方法是使分区数与节点数成正比 - 换句话说,每个节点具有固定数量的分区【23, 27, 28】。在这种情况下,每个分区的大小与数据集大小成比例地增长,而节点数量保持不变,但是当增加节点数时,分区将再次变小。由于较大的数据量通常需要较大数量的节点进行存储,因此这种方法也使每个分区的大小较为稳定。
Cassandra和Ketama使用的第三种方法是使分区数与节点数成正比——换句话说,每个节点具有固定数量的分区【23,27,28】。在这种情况下,每个分区的大小与数据集大小成比例地增长,而节点数量保持不变,但是当增加节点数时,分区将再次变小。由于较大的数据量通常需要较大数量的节点进行存储,因此这种方法也使每个分区的大小较为稳定。

当一个新节点加入集群时,它随机选择固定数量的现有分区进行拆分,然后占有这些拆分分区中每个分区的一半,同时将每个分区的另一半留在原地。随机化可能会产生不公平的分割,但是平均在更大数量的分区上时(在Cassandra中,默认情况下,每个节点有256个分区),新节点最终从现有节点获得公平的负载份额。 Cassandra 3.0引入了另一种再分配的算法来避免不公平的分割【29】。

Expand Down
2 changes: 1 addition & 1 deletion ch7.md
Original file line number Diff line number Diff line change
Expand Up @@ -958,4 +958,4 @@ WHERE room_id = 123 AND

| 上一章 | 目录 | 下一章 |
| ---------------------- | ------------------------------- | ---------------------------------- |
| [第六章:分片](ch6.md) | [设计数据密集型应用](README.md) | [第八章:分布式系统的麻烦](ch7.md) |
| [第六章:分区](ch6.md) | [设计数据密集型应用](README.md) | [第八章:分布式系统的麻烦](ch7.md) |
Loading

0 comments on commit b1bf5d1

Please sign in to comment.