Update ch4.md

typo
This commit is contained in:
anaer 2021-09-13 17:40:05 +08:00 committed by GitHub
parent 5641af5781
commit 77d0bba07c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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)中对它们进行更详细的比较。
详细的交付语义因实现和配置而异,但通常情况下,消息代理的使用方式如下:一个进程将消息发送到指定的队列或主题,代理确保将消息传递给那个队列或主题的一个或多个消费者或订阅者。在同一主题上可以有许多生产者和许多消费者。