Skip to content

Commit

Permalink
update punction marks
Browse files Browse the repository at this point in the history
  • Loading branch information
yingang committed Dec 23, 2021
1 parent 37f3ed9 commit c8ed9a1
Show file tree
Hide file tree
Showing 18 changed files with 96 additions and 96 deletions.
34 changes: 17 additions & 17 deletions ch1.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
* 将人们最容易犯错的地方与可能导致失效的地方**解耦(decouple)**。特别是提供一个功能齐全的非生产环境**沙箱(sandbox)**,使人们可以在不影响真实用户的情况下,使用真实数据安全地探索和实验。
* 在各个层次进行彻底的测试【3】,从单元测试、全系统集成测试到手动测试。自动化测试易于理解,已经被广泛使用,特别适合用来覆盖正常情况中少见的**边缘场景(corner case)**
* 允许从人为错误中简单快速地恢复,以最大限度地减少失效情况带来的影响。 例如,快速回滚配置变更,分批发布新代码(以便任何意外错误只影响一小部分用户),并提供数据重算工具(以备旧的计算出错)。
* 配置详细和明确的监控,比如性能指标和错误率。 在其他工程学科中这指的是**遥测(telemetry)**(一旦火箭离开了地面,遥测技术对于跟踪发生的事情和理解失败是至关重要的。)监控可以向我们发出预警信号,并允许我们检查是否有任何地方违反了假设和约束。当出现问题时,指标数据对于问题诊断是非常宝贵的。
* 配置详细和明确的监控,比如性能指标和错误率。 在其他工程学科中这指的是**遥测(telemetry)**(一旦火箭离开了地面,遥测技术对于跟踪发生的事情和理解失败是至关重要的)。监控可以向我们发出预警信号,并允许我们检查是否有任何地方违反了假设和约束。当出现问题时,指标数据对于问题诊断是非常宝贵的。
* 良好的管理实践与充分的培训——一个复杂而重要的方面,但超出了本书的范围。

### 可靠性有多重要?
Expand Down Expand Up @@ -285,7 +285,7 @@

* 简单性(Simplicity)

从系统中消除尽可能多的**复杂度(complexity)**,使新工程师也能轻松理解系统(注意这和用户接口的简单性不一样。)
从系统中消除尽可能多的**复杂度(complexity)**,使新工程师也能轻松理解系统(注意这和用户接口的简单性不一样)。

* 可演化性(evolability)

Expand All @@ -299,26 +299,26 @@

运维团队对于保持软件系统顺利运行至关重要。一个优秀运维团队的典型职责如下(或者更多)【29】:

* 监控系统的运行状况,并在服务状态不佳时快速恢复服务
* 跟踪问题的原因,例如系统故障或性能下降
* 及时更新软件和平台,比如安全补丁
* 监控系统的运行状况,并在服务状态不佳时快速恢复服务
* 跟踪问题的原因,例如系统故障或性能下降
* 及时更新软件和平台,比如安全补丁
* 了解系统间的相互作用,以便在异常变更造成损失前进行规避。
* 预测未来的问题,并在问题出现之前加以解决(例如,容量规划)
* 建立部署,配置、管理方面的良好实践,编写相应工具
* 执行复杂的维护任务,例如将应用程序从一个平台迁移到另一个平台
* 当配置变更时,维持系统的安全性
* 预测未来的问题,并在问题出现之前加以解决(例如,容量规划)
* 建立部署,配置、管理方面的良好实践,编写相应工具
* 执行复杂的维护任务,例如将应用程序从一个平台迁移到另一个平台
* 当配置变更时,维持系统的安全性
* 定义工作流程,使运维操作可预测,并保持生产环境稳定。
* 铁打的营盘流水的兵,维持组织对系统的了解。

良好的可操作性意味着更轻松的日常工作,进而运维团队能专注于高价值的事情。数据系统可以通过各种方式使日常任务更轻松:

* 通过良好的监控,提供对系统内部状态和运行时行为的**可见性(visibility)**
* 为自动化提供良好支持,将系统与标准化工具相集成
* 避免依赖单台机器(在整个系统继续不间断运行的情况下允许机器停机维护)
* 提供良好的文档和易于理解的操作模型(“如果做X,会发生Y”)
* 提供良好的默认行为,但需要时也允许管理员自由覆盖默认值
* 有条件时进行自我修复,但需要时也允许管理员手动控制系统状态
* 行为可预测,最大限度减少意外
* 通过良好的监控,提供对系统内部状态和运行时行为的**可见性(visibility)**
* 为自动化提供良好支持,将系统与标准化工具相集成
* 避免依赖单台机器(在整个系统继续不间断运行的情况下允许机器停机维护)
* 提供良好的文档和易于理解的操作模型(“如果做X,会发生Y”)
* 提供良好的默认行为,但需要时也允许管理员自由覆盖默认值
* 有条件时进行自我修复,但需要时也允许管理员手动控制系统状态
* 行为可预测,最大限度减少意外


### 简单性:管理复杂度
Expand Down Expand Up @@ -357,7 +357,7 @@
一个应用必须满足各种需求才称得上有用。有一些**功能需求**(functional requirements,即它应该做什么,比如允许以各种方式存储,检索,搜索和处理数据)以及一些**非功能性需求*(nonfunctional,即通用属性,例如安全性、可靠性、合规性、可伸缩性、兼容性和可维护性)。在本章详细讨论了可靠性,可伸缩性和可维护性。


**可靠性(Reliability)** 意味着即使发生故障,系统也能正常工作。故障可能发生在硬件(通常是随机的和不相关的)软件(通常是系统性的Bug,很难处理)和人类(不可避免地时不时出错)。 **容错技术** 可以对终端用户隐藏某些类型的故障。
**可靠性(Reliability)** 意味着即使发生故障,系统也能正常工作。故障可能发生在硬件(通常是随机的和不相关的)软件(通常是系统性的Bug,很难处理)和人类(不可避免地时不时出错)。 **容错技术** 可以对终端用户隐藏某些类型的故障。

**可伸缩性(Scalability)** 意味着即使在负载增加的情况下也有保持性能的策略。为了讨论可伸缩性,我们首先需要定量描述负载和性能的方法。我们简要了解了推特主页时间线的例子,介绍描述负载的方法,并将响应时间百分位点作为衡量性能的一种方式。在可伸缩的系统中可以添加 **处理容量(processing capacity)** 以在高负载下保持可靠。

Expand Down
6 changes: 3 additions & 3 deletions ch12.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ Unix和关系数据库以非常不同的哲学来处理信息管理问题。Unix

在这个典型的Web应用模型中,数据库充当一种可以通过网络同步访问的可变共享变量。应用程序可以读取和更新变量,而数据库负责维持它的持久性,提供一些诸如并发控制和容错的功能。

但是,在大多数编程语言中,你无法订阅可变变量中的变更 —— 你只能定期读取它。与电子表格不同,如果变量的值发生变化,变量的读者不会收到通知(你可以在自己的代码中实现这样的通知 —— 这被称为**观察者模式** —— 但大多数语言没有将这种模式作为内置功能。)
但是,在大多数编程语言中,你无法订阅可变变量中的变更 —— 你只能定期读取它。与电子表格不同,如果变量的值发生变化,变量的读者不会收到通知(你可以在自己的代码中实现这样的通知 —— 这被称为**观察者模式** —— 但大多数语言没有将这种模式作为内置功能)。

数据库继承了这种可变数据的被动方法:如果你想知道数据库的内容是否发生了变化,通常你唯一的选择就是轮询(即定期重复你的查询)。 订阅变更只是刚刚开始出现的功能(请参阅“[变更流的API支持](ch11.md#变更流的API支持)”)。

Expand Down Expand Up @@ -461,7 +461,7 @@ COMMIT;

即使我们可以抑制数据库客户端与服务器之间的重复事务,我们仍然需要担心终端用户设备与应用服务器之间的网络。例如,如果终端用户的客户端是Web浏览器,则它可能会使用HTTP POST请求向服务器提交指令。也许用户正处于一个信号微弱的蜂窝数据网络连接中,它们成功地发送了POST,但却在能够从服务器接收响应之前没了信号。

在这种情况下,可能会向用户显示错误消息,而他们可能会手动重试。 Web浏览器警告说,“你确定要再次提交这个表单吗?” —— 用户选“是”,因为他们希望操作发生(Post/Redirect/Get模式【54】可以避免在正常操作中出现此警告消息,但POST请求超时就没办法了。)从Web服务器的角度来看,重试是一个独立的请求;从数据库的角度来看,这是一个独立的事务。通常的除重机制无济于事。
在这种情况下,可能会向用户显示错误消息,而他们可能会手动重试。 Web浏览器警告说,“你确定要再次提交这个表单吗?” —— 用户选“是”,因为他们希望操作发生(Post/Redirect/Get模式【54】可以避免在正常操作中出现此警告消息,但POST请求超时就没办法了)。从Web服务器的角度来看,重试是一个独立的请求;从数据库的角度来看,这是一个独立的事务。通常的除重机制无济于事。

#### 操作标识符

Expand Down Expand Up @@ -490,7 +490,7 @@ COMMIT;

抑制重复事务的这种情况只是一个更普遍的原则的一个例子,这个原则被称为**端到端原则(end-to-end argument)**,它在1984年由Saltzer,Reed和Clark阐述【55】:

> 只有在通信系统两端应用的知识与帮助下,所讨论的功能才能完全地正确地实现。因而将这种被质疑的功能作为通信系统本身的功能是不可能的(有时,通信系统可以提供这种功能的不完备版本,可能有助于提高性能。)
> 只有在通信系统两端应用的知识与帮助下,所讨论的功能才能完全地正确地实现。因而将这种被质疑的功能作为通信系统本身的功能是不可能的(有时,通信系统可以提供这种功能的不完备版本,可能有助于提高性能)。
>
在我们的例子中**所讨论的功能**是重复抑制。我们看到TCP在TCP连接层次抑制了重复的数据包,一些流处理器在消息处理层次提供了所谓的恰好一次语义,但这些都无法阻止当一个请求超时时,用户亲自提交重复的请求。TCP,数据库事务,以及流处理器本身并不能完全排除这些重复。解决这个问题需要一个端到端的解决方案:从终端用户的客户端一路传递到数据库的事务标识符。
Expand Down
10 changes: 5 additions & 5 deletions ch2.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
采用NoSQL数据库的背后有几个驱动因素,其中包括:

* 需要比关系数据库更好的可伸缩性,包括非常大的数据集或非常高的写入吞吐量
* 相比商业数据库产品,免费和开源软件更受偏爱
* 相比商业数据库产品,免费和开源软件更受偏爱
* 关系模型不能很好地支持一些特殊的查询操作
* 受挫于关系模型的限制性,渴望一种更具多动态性与表现力的数据模型【5】

Expand Down Expand Up @@ -208,7 +208,7 @@ CODASYL中的查询是通过利用遍历记录列和跟随访问路径表在数

在关系数据库中,查询优化器自动决定查询的哪些部分以哪个顺序执行,以及使用哪些索引。这些选择实际上是“访问路径”,但最大的区别在于它们是由查询优化器自动生成的,而不是由程序员生成,所以我们很少需要考虑它们。

如果想按新的方式查询数据,你可以声明一个新的索引,查询会自动使用最合适的那些索引。无需更改查询来利用新的索引(请参阅“[数据查询语言](#数据查询语言)。)关系模型因此使添加应用程序新功能变得更加容易。
如果想按新的方式查询数据,你可以声明一个新的索引,查询会自动使用最合适的那些索引。无需更改查询来利用新的索引(请参阅“[数据查询语言](#数据查询语言))。关系模型因此使添加应用程序新功能变得更加容易。

关系数据库的查询优化器是复杂的,已耗费了多年的研究和开发精力【18】。关系模型的一个关键洞察是:只需构建一次查询优化器,随后使用该数据库的所有应用程序都可以从中受益。如果你没有查询优化器的话,那么为特定查询手动编写访问路径比编写通用优化器更容易——不过从长期看通用解决方案更好。

Expand Down Expand Up @@ -581,7 +581,7 @@ CREATE INDEX edges_heads ON edges (head_vertex);
关于这个模型的一些重要方面是:

1. 任何顶点都可以有一条边连接到任何其他顶点。没有模式限制哪种事物可不可以关联。
2. 给定任何顶点,可以高效地找到它的入边和出边,从而遍历图,即沿着一系列顶点的路径前后移动(这就是为什么[例2-2]()`tail_vertex``head_vertex`列上都有索引的原因。)
2. 给定任何顶点,可以高效地找到它的入边和出边,从而遍历图,即沿着一系列顶点的路径前后移动(这就是为什么[例2-2]()`tail_vertex``head_vertex`列上都有索引的原因)。
3. 通过对不同类型的关系使用不同的标签,可以在一个图中存储几种不同的信息,同时仍然保持一个清晰的数据模型。

这些特性为数据建模提供了很大的灵活性,如[图2-5](img/fig2-5.png)所示。图中显示了一些传统关系模式难以表达的事情,例如不同国家的不同地区结构(法国有省和州,美国有不同的州和州),国中国的怪事(先忽略主权国家和国家错综复杂的烂摊子),不同的数据粒度(Lucy现在的住所被指定为一个城市,而她的出生地点只是在一个州的级别)。
Expand All @@ -590,7 +590,7 @@ CREATE INDEX edges_heads ON edges (head_vertex);

### Cypher查询语言

Cypher是属性图的声明式查询语言,为Neo4j图形数据库而发明【37】(它是以电影“黑客帝国”中的一个角色来命名的,而与密码术中的密码无关【38】。)
Cypher是属性图的声明式查询语言,为Neo4j图形数据库而发明【37】(它是以电影“黑客帝国”中的一个角色来命名的,而与密码术中的密码无关【38】)。

[例2-3]()显示了将[图2-5](img/fig2-5.png)的左边部分插入图形数据库的Cypher查询。可以类似地添加图的其余部分,为了便于阅读而省略。每个顶点都有一个像`USA``Idaho`这样的符号名称,查询的其他部分可以使用这些名称在顶点之间创建边,使用箭头符号:`(Idaho) - [:WITHIN] ->(USA)`创建一条标记为`WITHIN`的边,`Idaho`为尾节点,`USA`为头节点。

Expand Down Expand Up @@ -790,7 +790,7 @@ RDF有一些奇怪之处,因为它是为了在互联网上交换数据而设

### SPARQL查询语言

**SPARQL**是一种用于三元组存储的面向RDF数据模型的查询语言【43】(它是SPARQL协议和RDF查询语言的缩写,发音为“sparkle”。)SPARQL早于Cypher,并且由于Cypher的模式匹配借鉴于SPARQL,这使得它们看起来非常相似【37】。
**SPARQL**是一种用于三元组存储的面向RDF数据模型的查询语言【43】(它是SPARQL协议和RDF查询语言的缩写,发音为“sparkle”)。SPARQL早于Cypher,并且由于Cypher的模式匹配借鉴于SPARQL,这使得它们看起来非常相似【37】。

与之前相同的查询 - 查找从美国转移到欧洲的人 - 使用SPARQL比使用Cypher甚至更为简洁(请参阅[例2-9]())。

Expand Down
4 changes: 2 additions & 2 deletions ch3.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ $ db_get 42
{"name":"San Francisco","attractions":["Golden Gate Bridge"]}
```

底层的存储格式非常简单:一个文本文件,每行包含一条逗号分隔的键值对(忽略转义问题的话,大致与CSV文件类似)。每次对 `db_set` 的调用都会向文件末尾追加记录,所以更新键的时候旧版本的值不会被覆盖 —— 因而查找最新值的时候,需要找到文件中键最后一次出现的位置(因此 `db_get` 中使用了 `tail -n 1 ` 。)
底层的存储格式非常简单:一个文本文件,每行包含一条逗号分隔的键值对(忽略转义问题的话,大致与CSV文件类似)。每次对 `db_set` 的调用都会向文件末尾追加记录,所以更新键的时候旧版本的值不会被覆盖 —— 因而查找最新值的时候,需要找到文件中键最后一次出现的位置(因此 `db_get` 中使用了 `tail -n 1 ` )。

```bash
$ db_set 42 '{"name":"San Francisco","attractions":["Exploratorium"]}'
Expand Down Expand Up @@ -236,7 +236,7 @@ Lucene是Elasticsearch和Solr使用的一种全文搜索的索引引擎,它使

[^ii]: 向B树中插入一个新的键是相当符合直觉的,但删除一个键(同时保持树平衡)就会牵扯很多其他东西了【2】。

这个算法可以确保树保持平衡:具有n个键的B树总是具有 $O(log n)$ 的深度。大多数数据库可以放入一个三到四层的B树,所以你不需要追踪多个页面引用来找到你正在查找的页面(分支因子为500的4KB页面的四层树可以存储多达256TB的数据。)
这个算法可以确保树保持平衡:具有n个键的B树总是具有 $O(log n)$ 的深度。大多数数据库可以放入一个三到四层的B树,所以你不需要追踪多个页面引用来找到你正在查找的页面(分支因子为500的4KB页面的四层树可以存储多达256TB的数据)。

#### 让B树更可靠

Expand Down
Loading

0 comments on commit c8ed9a1

Please sign in to comment.