Merge branch 'master' of github.com:Vonng/ddia

This commit is contained in:
Vonng 2021-09-14 09:26:22 +08:00
commit 599f2504a6
2 changed files with 7 additions and 7 deletions

12
ch4.md
View File

@ -11,7 +11,7 @@
[TOC]
应用程序不可避免地随时间而变化。新产品的推出,对需求的深入理解,或者商业环境的变化,总会伴随着**功能feature** 的增增改改。[第一章](ch1.md)介绍了**可演化性(evolvability)**的概念:应该尽力构建能灵活适应变化的系统(请参阅“[可演化性:拥抱变化](ch1.md#可演化性:拥抱变化)”)。
应用程序不可避免地随时间而变化。新产品的推出,对需求的深入理解,或者商业环境的变化,总会伴随着**功能feature** 的增增改改。[第一章](ch1.md)介绍了**可演化性(evolvability)** 的概念:应该尽力构建能灵活适应变化的系统(请参阅“[可演化性:拥抱变化](ch1.md#可演化性:拥抱变化)”)。
在大多数情况下,修改应用程序的功能也意味着需要更改其存储的数据:可能需要使用新的字段或记录类型,或者以新方式展示现有数据。
@ -90,7 +90,7 @@ JSONXML和CSV属于文本格式因此具有人类可读性尽管它们
JSON比XML简洁但与二进制格式相比还是太占空间。这一事实导致大量二进制编码版本JSONMessagePackBSONBJSONUBJSONBISON和Smile等 和 XML例如WBXML和Fast Infoset的出现。这些格式已经在各种各样的领域中采用但是没有一个能像文本版JSON和XML那样被广泛采用。
这些格式中的一些扩展了一组数据类型例如区分整数和浮点数或者增加对二进制字符串的支持另一方面它们没有改变JSON / XML的数据模型。特别是由于它们没有规定模式所以它们需要在编码数据中包含所有的对象字段名称。也就是说在[例4-1]()中的JSON文档的二进制编码中需要在某处包含字符串`userName``favoriteNumber`和`interest`。
这些格式中的一些扩展了一组数据类型例如区分整数和浮点数或者增加对二进制字符串的支持另一方面它们没有改变JSON / XML的数据模型。特别是由于它们没有规定模式所以它们需要在编码数据中包含所有的对象字段名称。也就是说在[例4-1]()中的JSON文档的二进制编码中需要在某处包含字符串`userName``favoriteNumber`和`interests`。
**例4-1 本章中用于展示二进制编码的示例记录**
@ -152,7 +152,7 @@ Thrift和Protocol Buffers每一个都带有一个代码生成工具它采用
与[图4-1](Img/fig4-1.png)类似,每个字段都有一个类型注释(用于指示它是一个字符串,整数,列表等),还可以根据需要指定长度(字符串的长度,列表中的项目数) 。出现在数据中的字符串`(“Martin”, “daydreaming”, “hacking”)`也被编码为ASCII或者说UTF-8与之前类似。
与[图4-1](img/fig4-1.png)相比,最大的区别是没有字段名`(userName, favoriteNumber, interest)`。相反,编码数据包含字段标签,它们是数字`(1, 2和3)`。这些是模式定义中出现的数字。字段标记就像字段的别名 - 它们是说我们正在谈论的字段的一种紧凑的方式,而不必拼出字段名称。
与[图4-1](img/fig4-1.png)相比,最大的区别是没有字段名`(userName, favoriteNumber, interests)`。相反,编码数据包含字段标签,它们是数字`(1, 2和3)`。这些是模式定义中出现的数字。字段标记就像字段的别名 - 它们是说我们正在谈论的字段的一种紧凑的方式,而不必拼出字段名称。
Thrift CompactProtocol编码在语义上等同于BinaryProtocol但是如[图4-3](img/fig4-3.png)所示它只将相同的信息打包成只有34个字节。它通过将字段类型和标签号打包到单个字节中并使用可变长度整数来实现。数字1337不是使用全部八个字节而是用两个字节编码每个字节的最高位用来指示是否还有更多的字节来。这意味着-64到63之间的数字被编码为一个字节-8192和8191之间的数字以两个字节编码等等。较大的数字使用更多的字节。
@ -248,9 +248,9 @@ Avro的关键思想是Writer模式和Reader模式不必是相同的 - 他们只
使用Avro向前兼容性意味着您可以将新版本的模式作为Writer并将旧版本的模式作为Reader。相反向后兼容意味着你可以有一个作为Reader的新版本模式和作为Writer的旧版本模式。
为了保持兼容性,您只能添加或删除具有默认值的字段。 我们的Avro模式中的字段`favourNumber`的默认值为`null`。例如假设您添加了一个有默认值的字段这个新的字段将存在于新模式而不是旧模式中。当使用新模式的Reader读取使用旧模式写入的记录时将为缺少的字段填充默认值。
为了保持兼容性,您只能添加或删除具有默认值的字段。 我们的Avro模式中的字段`favoriteNumber`的默认值为`null`。例如假设您添加了一个有默认值的字段这个新的字段将存在于新模式而不是旧模式中。当使用新模式的Reader读取使用旧模式写入的记录时将为缺少的字段填充默认值。
如果你要添加一个没有默认值的字段新的Reader将无法读取旧Writer写的数据所以你会破坏向后兼容性。如果您要删除没有默认值的字段旧的Reader将无法读取新Writer写入的数据因此您会打破向前兼容性。在一些编程语言中null是任何变量可以接受的默认值但在Avro中并不是这样如果要允许一个字段为`null`,则必须使用联合类型。例如,`union {nulllongstring} field;`表示field可以是数字或字符串也可以是`null`。如果要将null作为默认值则它必须是union的分支之一[^iv]。这样的写法比默认情况下就允许任何变量是`null`显得更加冗长,但是通过明确什么可以和什么不可以是`null`有助于防止出错【22】。
如果你要添加一个没有默认值的字段新的Reader将无法读取旧Writer写的数据所以你会破坏向后兼容性。如果您要删除没有默认值的字段旧的Reader将无法读取新Writer写入的数据因此您会打破向前兼容性。在一些编程语言中null是任何变量可以接受的默认值但在Avro中并不是这样如果要允许一个字段为`null`,则必须使用联合类型。例如,`union {null, long, string} field;`表示field可以是数字或字符串也可以是`null`。如果要将null作为默认值则它必须是union的分支之一[^iv]。这样的写法比默认情况下就允许任何变量是`null`显得更加冗长,但是通过明确什么可以和什么不可以是`null`有助于防止出错【22】。
[^iv]: 确切地说默认值必须是联合的第一个分支的类型尽管这是Avro的特定限制而不是联合类型的一般特征。
@ -473,7 +473,7 @@ RPC方案的前后向兼容性属性从它使用的编码方式中继承
#### 消息代理
过去,**消息代理Message Broker**主要是TIBCOIBM WebSphere和webMethods等公司的商业软件的秀场。最近像RabbitMQActiveMQHornetQNATS和Apache Kafka这样的开源实现已经流行起来。我们将在[第十一章](ch11.md)中对它们进行更详细的比较。
过去,**消息代理Message Broker** 主要是TIBCOIBM WebSphere和webMethods等公司的商业软件的秀场。最近像RabbitMQActiveMQHornetQNATS和Apache Kafka这样的开源实现已经流行起来。我们将在[第十一章](ch11.md)中对它们进行更详细的比较。
详细的交付语义因实现和配置而异,但通常情况下,消息代理的使用方式如下:一个进程将消息发送到指定的队列或主题,代理确保将消息传递给那个队列或主题的一个或多个消费者或订阅者。在同一主题上可以有许多生产者和许多消费者。

2
ch5.md
View File

@ -449,7 +449,7 @@
最普遍的拓扑是全部到全部([图5-8 (c)](img/fig5-8.png)其中每个领导者将其写入每个其他领导。但是也会使用更多受限制的拓扑例如默认情况下MySQL仅支持**环形拓扑circular topology**【34】其中每个节点接收来自一个节点的写入并将这些写入加上自己的任何写入转发给另一个节点。另一种流行的拓扑结构具有星形的形状[^v]。一个指定的根节点将写入转发给所有其他节点。星型拓扑可以推广到树。
[^v]: 不要与星型模式混淆(请参阅“[星型和雪花型:分析的模式](ch2.md#星型和雪花型:分析的模式)”),其中描述了数据模型的结构,而不是节点之间的通信拓扑。
[^v]: 不要与星型模式混淆(请参阅“[星型和雪花型:分析的模式](ch3.md#星型和雪花型:分析的模式)”),其中描述了数据模型的结构,而不是节点之间的通信拓扑。
在圆形和星形拓扑中写入可能需要在到达所有副本之前通过多个节点。因此节点需要转发从其他节点收到的数据更改。为了防止无限复制循环每个节点被赋予一个唯一的标识符并且在复制日志中每个写入都被标记了所有已经过的节点的标识符【43】。当一个节点收到用自己的标识符标记的数据更改时该数据更改将被忽略因为节点知道它已经被处理过。