mirror of
https://github.com/oldratlee/translations.git
synced 2026-04-15 19:19:52 +08:00
审校Part 1
This commit is contained in:
@@ -1,45 +1,65 @@
|
||||
第一部分:日志是什么?
|
||||
=====================================================================
|
||||
|
||||
日志是一种简单的不能再简单的存储抽象。它是一个只能增加的,完全按照时间排序的一系列记录。日志看起来如下:
|
||||
日志可能是一种最简单的不能再简单的存储抽象。只能追加,完全按照时间排序的记录序列。日志看起来的样子:
|
||||
|
||||

|
||||
|
||||
我们可以给日志的末尾添加记录,并且可以从左到右读取日志记录。每一条记录都指定了一个唯一的有一定顺序的日志记录编号。
|
||||
我们可以给日志的末尾添加记录,读取日志记录则从左到右。每一条记录都指定了一个唯一有序的日志记录编号。
|
||||
|
||||
日志记录的排序是由“时间”来确定的,这是因为位于左边的日志记录比位于右边的要早些。日志记录编号可以看作是这条日志 记录的“时间戳”。在一开始就把这种排序说成是按时间排序显得有点多余 ,不过 ,与任何一个具体的物理时钟相比,时间 属性是非常便于使用的属性。在我们运行多个分布式系统的时候,这个属性就显得非常重要。
|
||||
日志记录的次序(`ordering`)定义了『时间』概念,因为位于左边的日志记录表示比右边的要早。
|
||||
日志记录编号可以看作是这条日志记录的『时间戳』。
|
||||
把次序直接看成是时间概念,刚开始你会觉得有点怪异,但是这样的做法有个便利的属性:解耦了 时间 和 任一特定的物理时钟(`physical clock`)。引入分布式系统后,这会成为一个必不可少的属性。
|
||||
|
||||
对于这篇讨论的目标而言,日志记录的内容和格式不怎么重要。另外提醒一下,在完全耗尽存储空间的情况下,我们不可能 再给日志添加记录。稍后我们将会提到这个问题。
|
||||
***【译注】***: 分布式系统的 时间、次序、时钟是最基础根本的问题,更多思考可以参见被引用最多的***Leslie Lamport***的论文[***Time Clocks and the Ordering of Events in a Distributed System***](http://duanple.blog.163.com/blog/static/709717672012920101343237/)。
|
||||
|
||||
日志并不是完全不同于文件或者数据表的。文件是由一系列字节组成,表是由一系列记录组成,而日志实际上只是按照时间顺序存储记录的 一种数据表或者文件。
|
||||
日志记录的内容和格式是什么对于本文讨论并不重要。另外,不可能一直给日志添加记录,因为总会耗尽存储空间。稍后我们会回到这个问题。
|
||||
|
||||
此时,你可能奇怪为什么要讨论这么简单的事情呢? 不同环境下的一个只可增加的有一定顺序的日志记录是怎样与数据系统关联起来的呢?答案是日志有其特定的应用目标:它记录了什么时间发生了什么事情。 而对分布式数据系统许多方面而言, 这才是问题的真正核心。
|
||||
所以,日志 和 文件或数据表(`table`)并没有什么大的不同。文件是一系列字节,表是由一系列记录组成,而日志实际上只是一种按照时间顺序存储记录的数据表或文件。
|
||||
|
||||
不过,在我们进行更加深入的讨论之前,让我先澄清有些让人混淆的概念。每个编程人员都熟悉另一种日志记录-应用使用syslog或者log4j可能写入到本地文件里的没有结构的错误信息或者追踪信息。为了区分开来,我们把这种情形的日志记录称为“应用日志记录”。应用日志记录是我在这儿所说的日志的一种低级的变种。最大的区别是:文本日志意味着主要用来方便人们阅读,而我所说明的“日志”或者“数据日志”的建立是方便程序访问。
|
||||
讨论到现在,你可能奇怪为什么要讨论这么简单的概念?只能追加的有序的日志记录究竟又是怎样与数据系统生产关系的?
|
||||
答案是日志有其特定的目标:它记录了什么时间发生了什么事情。而对分布式数据系统,在许多方面,这是要解决的问题的真正核心。
|
||||
|
||||
(实际上,如果你对它进行深入的思考,那么人们读取某个机器上的日志这种理念有些不顺应时代潮流。当涉及到许多服务和服务器的时候,这种方法很快就变成一个难于管理的方式,而且为了认识多个机器的行为,日志的目标很快就变成查询和图形化这些行为的输入了-对多个机器的某些行为而言,文件里的英文形式的文本同这儿所描述的这种结构化的日志相比几乎就不适合了。)
|
||||
不过,在我们进行更加深入的讨论之前,让我先澄清有些让人混淆的概念。每个程序员都熟悉另一种日志记录的定义 —— 应用使用`syslog`或者`log4j`写入到本地文件里的无结构的错误信息或者追踪信息。为了区分,这种情形的称为『应用日志记录』。
|
||||
应用日志记录是我说的日志概念的一种退化。两者最大的区别是:文本日志意味着主要用来方便人去阅读,而构建我所说的『日志(`journal`)』或者『数据日志(`data logs`)』是用于程序的访问。
|
||||
|
||||
数据库日志
|
||||
(实际上,如果你深入地思考一下,会觉得人去阅读某个机器上的日志这样的想法有些落伍过时了。
|
||||
当涉及到许多服务和服务器的时,这样的做法很快就变得难于管理,而且为了认识多个机器的行为,
|
||||
这样日志的目标很快就变成 输入查询 和 输出用于理解多台机器的行为的图表
|
||||
—— 在这种的情况止下,文件中的字句文本 几乎肯定不如 本文所描述的结构化日志 更合适。)
|
||||
|
||||
数据库中的日志
|
||||
-------------------------
|
||||
|
||||
我不知道日志概念起源于何处-可能它就像二进制搜索一样:发明者认为它太简单而不能当作一项发明。它早在IBM的[系统R](http://www.cs.berkeley.edu/~brewer/cs262/SystemR.pdf)出现时候就出现了。数据库里的用法是在崩溃的时候用它来同步各种数据结构和索引。为了保证操作的原子性和持久性,在对数据库维护的所有各种数据结构做更改之前,数据库把即将修改的信息誊写到日志里。日志记录了发生了什么,而且其中的每个表或者索引都是一些数据结构或者索引的历史映射。由于日志是即刻永久化的,可以把它当作崩溃发生时用来恢复其他所有永久性结构的可信赖数据源。
|
||||
我不知道日志概念起源于何处 —— 可能就像二分查找(`binary search`)一样,发明者觉得太简单了而不是一项发明。早在`IBM`的[系统R](http://www.cs.berkeley.edu/~brewer/cs262/SystemR.pdf)出现时候日志就出现了。
|
||||
在数据库里的用法是在崩溃的时候用它来保持各种数据结构和索引的同步。为了保证操作的原子性(`atomic`)和持久性(`durable`),
|
||||
在对数据库维护的所有各种数据结构做更改之前,数据库会把要做的更改操作的信息写入日志。
|
||||
日志记录了发生了什么,而每个表或者索引都是更改历史中的某个投影。由于日志是即刻持久化的,发生崩溃时,可以把它当作恢复其他所有永久性结构的可靠来源。
|
||||
|
||||
随着时间的推移,日志的用途从实现ACID细节成长为数据库间复制数据的一种方法。利用日志的结果就是发生在数据库上的更改顺序与远端复制数据库上的更改顺序需要保持完全同步。Oracle,MySQL 和PostgreSQL都包括用于给备用的复制数据库传输日志的日志传输协议。Oracle还把日志产品化为一个通用的数据订阅机制,这样非Oracle数据订阅用户就可以使用[XStreams](http://docs.oracle.com/cd/E11882_01/server.112/e16545/xstrm_intro.htm)和[GoldenGate](http://www.oracle.com/technetwork/middleware/goldengate/overview/index.html)订阅数据了,MySQL和PostgreSQL上的类似的实现则成为许多数据结构的关键组件。
|
||||
随着时间的推移,日志的用途从`ACID`的实现细节成长为数据库间复制数据的一种方法。
|
||||
原来,发生在数据库上的更改序列 即是 与远程副本数据库(`replica database`)保持同步 所需的操作。
|
||||
`Oracle`、`MySQL` 和`PostgreSQL`都包括一个日志传送协议(`log shipping protocol`),用于给作为备库(`Slave`)的副本数据库日志片段。
|
||||
`Oracle`还把日志产品化为一个通用的数据订阅机制,为非`Oracle`数据订阅用户提供了[`XStreams`](http://docs.oracle.com/cd/E11882_01/server.112/e16545/xstrm_intro.htm)和[`GoldenGate`](http://www.oracle.com/technetwork/middleware/goldengate/overview/index.html),而在`MySQL`和`PostgreSQL`中的类似设施已经许多数据架构的为关键组件。
|
||||
|
||||
正是由于这样的起源,机器可识别的日志的概念大部分都被局限在数据库内部。日志用做数据订阅的机制似乎是偶然出现的,不过要把这种 抽象用于支持所有类型的消息传输、数据流和实时数据处理是不切实际的。
|
||||
正是由于这样的起源,机器可识别的日志这个概念主要都被局限在数据库的内部。日志用做数据订阅的机制似乎是偶然出现的。
|
||||
但正是这样的抽象才非常适合用于支持所有类型的消息传输、数据流和实时数据处理。
|
||||
|
||||
分布式系统日志
|
||||
分布式系统中的日志
|
||||
-------------------------
|
||||
|
||||
日志解决了两个问题:更改动作的排序和数据的分发,这两个问题在分布式数据系统里显得尤为重要。协商出一致的更改动作的顺序(或者说保持各个子系统本身的做法,但可以进行存在副作用的数据拷贝)是分布式系统设计的核心问题之一。
|
||||
日志解决了两个问题:更改动作的排序和数据的分发,这两个问题在分布式数据系统里更是尤为重要。
|
||||
协商出一致的更改动作的顺序(或者协商出保持各个子系统本身的做法和可以进行存在副作用的数据拷贝)是分布式系统设计的核心问题之一。
|
||||
|
||||
以日志为中心实现分布式系统是受到了一个简单的经验常识的启发,我把这个经验常识称为状态机复制原理:**如果两个相同的、确定性的进程从同一状态开始,并且以相同的顺序获得相同的输入,那么这两个进程将会生成相同的输出,并且结束在相同的状态。**
|
||||
以日志为中心的分布式系统方案是受到了一个简单经验的启发,我把这个经验称为**状态机复制原理**(`State Machine Replication Principle`):
|
||||
|
||||
这也许有点难以理解,让我们更加深入的探讨,弄懂它的真正含义。
|
||||
**如果两个相同的、确定性的进程从同一状态开始,并且以相同的顺序获得相同的输入,那么这两个进程将会生成相同的输出,并且结束在相同的状态。**
|
||||
|
||||
[确定性](http://en.wikipedia.org/wiki/Deterministic_algorithm)意味着处理过程是与时间无关的,而且任何其他“外部的“输入不会影响到处理结果。例如,如果一个程序的输出会受到线程执行的具体顺序影响,或者受到gettimeofday调用、或者其他一些非重复性事件的影响,那么这样的程序一般最有可能被认为是非确定性的。
|
||||
听起来有点难以晦涩,让我们更加深入的探讨,弄懂它的真正含义。
|
||||
|
||||
进程状态是进程保存在机器上的任何数据,在进程处理结束的时候,这些数据要么保存在内存里,要么保存在磁盘上。
|
||||
[确定性](http://en.wikipedia.org/wiki/Deterministic_algorithm)(`deterministic `)意味着处理过程是与时间无关的,而且任何其他『带外数据(`out of band`)』的输入不会影响到处理结果。
|
||||
例如,如果一个程序的输出会受到线程执行的具体顺序影响,或者受到`gettimeofday`调用、或者其他一些非重复性事件的影响,那么这样的程序一般被认为是非确定性的。
|
||||
|
||||
进程***状态***是进程保存在机器上的任何数据,在进程处理结束的时候,这些数据要么保存在内存里,要么保存在磁盘上。
|
||||
|
||||
以相同的顺序获得相同输入的地方应当引起注意-这就是引入日志的地方。这儿有一个重要的常识:如果给两段确定性代码相同的日志输入,那么它们就会生成相同的输出。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user