progress: ch6 review

This commit is contained in:
Vonng 2018-03-21 09:32:30 +08:00
parent 8f80644cb6
commit 7580e80d16
6 changed files with 56 additions and 48 deletions

View File

@ -6,6 +6,20 @@
- Gitbook地址[ddia-cn](https://www.gitbook.com/book/vonng/ddia-cn)(需要科学上网)
- 建议使用[Typora](https://www.typora.io)或Gitbook以获取最佳阅读体验。
## 法律声明
从原作者处得知已经有简体中文的翻译计划将于2018年末完成。
译者纯粹出于**学习目的**与**个人兴趣**翻译本书,不追求任何经济利益。
译者保留对此版本译文的署名权,其他权利以原作者和出版社的主张为准。
本译文只供学习研究参考之用,不得公开传播发行或用于商业用途。有能力阅读英文书籍者请购买正版支持。
## 译序
> 不懂数据库的全栈工程师不是好架构师
@ -44,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)
@ -89,7 +103,7 @@
| 第四章:编码与演化 | 初翻 | |
| 第二部分:分布式数据——概览 | 精翻 | |
| 第五章:复制 | 精翻 30% | Vonng |
| 第六章:分 | 初翻 | |
| 第六章:分 | 初翻 | |
| 第七章:事务 | 精翻 60% | Vonng |
| 第八章:分布式系统中的问题 | 初翻 | |
| 第九章:一致性与共识 | 初翻 30% | Vonng |
@ -107,22 +121,16 @@
## CONTRIBUTION
欢迎贡献
欢迎贡献初翻后的章节接受ISSUE指正。参与翻译前请先锁定相应章节。
整章的翻译、精校请使用PR将列入署名少量词法、语法、译法问题请使用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)
## 法律声明
译者纯粹出于学习目的与个人兴趣翻译,本译文只供学习研究参考之用,不得公开传播发行或用于商业用途。有能力阅读英文书籍者请购买正版支持。
译者保留对译文的署名权,其他权利以原作者和出版社的主张为准。
## 译读者交流微信群

View File

@ -9,7 +9,7 @@
* [第四章:编码与演化](ch4.md)
* [第二部分:分布式数据](part-ii.md)
* [第五章:复制](ch5.md)
* [第六章:分](ch6.md)
* [第六章:分](ch6.md)
* [第七章:事务](ch7.md)
* [第八章:分布式系统的麻烦](ch8.md)
* [第九章:一致性与共识](ch9.md)

2
ch5.md
View File

@ -919,4 +919,4 @@ LWW实现了最终收敛的目标但以**持久性**为代价:如果同一
| 上一章 | 目录 | 下一章 |
| :--------------------------------: | :-----------------------------: | :--------------------: |
| [第二部分:分布式数据](part-ii.md) | [设计数据密集型应用](README.md) | [第六章:分](ch6.md) |
| [第二部分:分布式数据](part-ii.md) | [设计数据密集型应用](README.md) | [第六章:分](ch6.md) |

48
ch6.md
View File

@ -1,8 +1,8 @@
# 6. 分
# 6. 分
![](img/ch6.png)
> 我们必须跳出电脑指令序列的窠臼。 叙述定义、提供数据的描述和优先级、梳理关系,而不是编写过程。
> 我们必须跳出电脑指令序列的窠臼。 叙述定义、描述元数据、梳理关系,而不是编写过程。
>
> —— Grace Murray Hopper未来的计算机及其管理1962
>
@ -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)讨论这些错误。
> ##### 术语澄清
>
@ -22,15 +22,15 @@
通常情况下,每条数据(每条记录,每行或每个文档)属于且仅属于一个分区。有很多方法可以实现这一点,本章将进行深入讨论。实际上,每个分区都是自己的小型数据库,尽管数据库可能支持同时进行多个分区的操作。
分区主要为了**可扩展性**。不同的分区可以放在不共享集群中的不同节点上(参阅[第二部分](part-ii.md)关于[无共享架构](part-ii.md#无共享架构)的定义)。因此,大数据集可以分布在多个磁盘上,并且查询负载可以分布在多个处理器上。
分区主要为了**可扩展性**。不同的分区可以放在不共享集群中的不同节点上(参阅[第二部分](part-ii.md)关于[无共享架构](part-ii.md#无共享架构)的定义)。因此,大数据集可以分布在多个磁盘上,并且查询负载可以分布在多个处理器上。
对于在单个分区上运行的查询,每个节点可以独立执行对自己的分区的查询,因此可以通过添加更多的节点来扩大查询吞吐量。大型,复杂的查询可能会跨越多个节点并行处理,尽管这也带来了新的困难。
对于在单个分区上运行的查询,每个节点可以独立执行对自己的查询,因此可以通过添加更多的节点来扩大查询吞吐量。大型,复杂的查询可能会跨越多个节点并行处理,尽管这也带来了新的困难。
分区数据库在20世纪80年代由Teradata和NonStop SQL【1】等产品率先推出最近因为NoSQL数据库和基于Hadoop的数据仓库重新被关注。有些系统是为事务性工作设计的有些系统则用于分析参阅“[事务处理或分析]”):这种差异会影响系统的运作方式,但是分区的基本原理均适用于这两种工作方式。
在本章中,我们将首先介绍分割大型数据集的不同方法,并观察索引如何与分区配合。然后我们将讨论[再平衡](),如果想要添加或删除群集中的节点,则必须进行再平衡。最后,我们将概述数据库如何将请求路由到正确的分区并执行查询。
在本章中,我们将首先介绍分割大型数据集的不同方法,并观察索引如何与分区配合。然后我们将讨论[重新平衡分区](#重新平衡分区),如果想要添加或删除群集中的节点,则必须进行再平衡。最后,我们将概述数据库如何将请求路由到正确的分区并执行查询。
## 分与复制
## 分与复制
分区通常与复制结合使用,使得每个分区的副本存储在多个节点上。 这意味着,即使每条记录属于一个分区,它仍然可以存储在多个不同的节点上以获得容错能力。
@ -72,7 +72,7 @@
为了避免传感器数据库中的这个问题,需要使用除了时间戳以外的其他东西作为主键的第一个部分。 例如,可以在每个时间戳前添加传感器名称,这样会首先按传感器名称,然后按时间进行分区。 假设有多个传感器同时运行,写入负载将最终均匀分布在不同分区上。 现在,当想要在一个时间范围内获取多个传感器的值时,您需要为每个传感器名称执行一个单独的范围查询。
### 根据键的散列分
### 根据键的散列分
由于偏斜和热点的风险,许多分布式数据存储使用散列函数来确定给定键的分区。
@ -112,7 +112,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
也许在将来,数据系统将能够自动检测和补偿偏斜的工作负载;但现在,您需要自己来权衡。
-------------------------
-------------------------
(以上完成)
## 分片与次级索引
@ -127,7 +127,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]。例如,无论何时将红色汽车添加到数据库,数据库分区都会自动将其添加到索引条目`colorred`的文档ID列表中。
@ -139,9 +139,9 @@ 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**,并且可能会使二级索引上的读取查询相当昂贵。即使并行查询分区,分散/聚集也容易导致尾部延迟放大(请参阅第16页的“实践中的百分比。然而它被广泛使用MonDBDBRiak 【15】Cassandra 【16】Elasticsearch 【17】SolrCloud 【18】和VoltDB 【19】都使用文档分区二级索引。大多数数据库供应商建议您构建一个能从单个分区提供二级索引查询的分区方案但这并不总是可行尤其是当在单个查询中使用多个二级索引时例如同时需要按颜色和制造商查询
这种查询分区数据库的方法有时被称为**分散/聚集scatter/gather**,并且可能会使二级索引上的读取查询相当昂贵。即使并行查询分区,分散/聚集也容易导致尾部延迟放大(参阅“[实践中的百分位点](ch1.md#实践中的百分位点)。然而它被广泛使用MonDBDBRiak 【15】Cassandra 【16】Elasticsearch 【17】SolrCloud 【18】和VoltDB 【19】都使用文档分区二级索引。大多数数据库供应商建议您构建一个能从单个分区提供二级索引查询的分区方案但这并不总是可行尤其是当在单个查询中使用多个二级索引时例如同时需要按颜色和制造商查询
@ -149,7 +149,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
我们可以构建一个覆盖所有分区数据的**全局索引**,而不是每个分区都有自己的次级索引(本地索引)。但是,我们不能只把这个索引存储在一个节点上,因为它可能会成为一个瓶颈,打破了分区的目的。全局索引也必须进行分区,但索引可以采用与主键不同的分区方式。
[图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)
@ -161,7 +161,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
全局(关键词分区)索引优于文档分区索引的优点是它可以使读取更有效率:而不是**分散/收集**所有分区,客户端只需要向包含关键词的分区发出请求它想要的。但是,全局索引的缺点在于写入速度较慢且较为复杂,因为写入单个文档现在可能会影响索引的多个分区(文档中的每个术语可能位于不同的分区上,位于不同的节点上) 。
在理想的世界里,索引总是最新的,写入数据库的每个文档都会立即反映在索引中。但是,在分区索引中,这需要跨库分布式事务,跨越所有被写入影响的分片,这在所有数据库中都不受支持(请参阅[第7章](ch7.md)和[第9章](ch9.md))。
在理想的世界里,索引总是最新的,写入数据库的每个文档都会立即反映在索引中。但是,在分区索引中,这需要跨库分布式事务,跨越所有被写入影响的分片,这在所有数据库中都不受支持(请参阅[第7章](ch7.md)和[第9章](ch9.md))。
在实践中,对全局二级索引的更新通常是**异步**的也就是说如果在写入之后不久读取索引刚才所做的更改可能尚未反映在索引中。例如Amazon DynamoDB指出在正常情况下其全局次级索引会在不到一秒的时间内更新但在基础架构出现故障的情况下可能会经历更长的传播延迟【20】。
@ -169,7 +169,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
## 重平衡分区
## 重平衡
在数据库中,随着时间的推移,事情也在起变化。
@ -177,13 +177,13 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
* 数据集大小增加所以您想添加更多的磁盘和RAM来存储它。
* 机器出现故障,其他机器需要接管故障机器的责任。
所有这些更改都要求数据和请求从一个节点移动到另一个节点。 从集群中的一个节点向另一个节点移动负载的过程称为**平衡reblancing**。
所有这些更改都要求数据和请求从一个节点移动到另一个节点。 从集群中的一个节点向另一个节点移动负载的过程称为**重新平衡reblancing**。
无论使用哪种分区方案,平衡通常都会满足一些最低要求:
无论使用哪种分区方案,重新平衡通常都会满足一些最低要求:
* 平衡之后,负载(数据存储,读取和写入请求)应该在集群中的节点之间公平地共享。
* 平衡正在发生时,数据库应该继续接受读取和写入。
* 节点之间不应移动超过所需的数据,以便快速平衡并尽量减少网络和磁盘I/O负载。
* 重新平衡之后,负载(数据存储,读取和写入请求)应该在集群中的节点之间公平地共享。
* 重新平衡正在发生时,数据库应该继续接受读取和写入。
* 节点之间不应移动超过所需的数据,以便快速重新平衡并尽量减少网络和磁盘I/O负载。
### 平衡策略
@ -195,7 +195,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$)。这种频繁的举动使得重新平衡过于昂贵。
我们需要一种不需要移动数据的方法。
@ -235,7 +235,7 @@ Cassandra采取了折衷的策略【11, 12, 13】。 Cassandra中的表可以使
通过动态分区,分区的数量与数据集的大小成正比,因为拆分和合并过程将每个分区的大小保持在固定的最小值和最大值之间。另一方面,对于固定数量的分区,每个分区的大小与数据集的大小成正比。在这两种情况下,分区的数量都与节点的数量无关。
Cassandra和Ketama使用的第三种方法是使分区数与节点数成比例 - 换句话说每个节点具有固定数量的分区【23, 27, 28】。在这种情况下每个分区的大小与数据集大小成比例地增长而节点数量保持不变但是当增加节点数时分区将再次变小。由于较大的数据量通常需要较大数量的节点进行存储因此这种方法也使每个分区的大小相当稳定。
Cassandra和Ketama使用的第三种方法是使分区数与节点数成比例——换句话说每个节点具有固定数量的分区【23, 27, 28】。在这种情况下每个分区的大小与数据集大小成比例地增长而节点数量保持不变但是当增加节点数时分区将再次变小。由于较大的数据量通常需要较大数量的节点进行存储因此这种方法也使每个分区的大小相当稳定。
当一个新节点加入集群时它随机选择固定数量的现有分区进行拆分然后占有这些拆分分区中每个分区的一半同时将每个分区的另一半留在原地。随机化可能会产生不公平的分裂但是当在更大数量的分区上进行平均时在Cassandra中默认情况下每个节点有256个分区新节点最终从现有节点获得公平的负载份额。 Cassandra 3.0引入了另一种可重用的算法来避免不公平的分裂【29】。
@ -295,7 +295,7 @@ Couchbase不会自动重新平衡这简化了设计。通常情况下
然而,通常用于分析的**大规模并行处理MPP, Massively parallel processing**关系数据库产品在其支持的查询类型方面要复杂得多。一个典型的数据仓库查询包含多个连接,过滤,分组和聚合操作。 MPP查询优化器将这个复杂的查询分解成许多执行阶段和分区其中许多可以在数据库集群的不同节点上并行执行。涉及扫描大部分数据集的查询尤其受益于这种并行执行。
数据仓库查询的快速并行执行是一个专门的话题由于分析有很强的商业重要性它收到了很多商业利益。我们将在第10章讨论并行查询执行的一些技巧。有关并行数据库中使用的技术的更详细的概述请参阅参考文献【1,33】。
数据仓库查询的快速并行执行是一个专门的话题,由于分析有很强的商业重要性,它收到了很多商业利益。我们将在[第10章](ch10.md)讨论并行查询执行的一些技巧。有关并行数据库中使用的技术的更详细的概述请参阅参考文献【1,33】。

2
ch7.md
View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 107 KiB