ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

读懂《The Log》第一部分:为什么日志是分布式实时数据的统一抽象

读懂《The Log》第一部分:为什么日志是分布式实时数据的统一抽象 文档教程知识库【免费下载链接】translations Chinese translations for classic software development resources项目地址https://gitcode.com/gh_mirrors/tr/translations点击查看免费下载导读本文基于本仓库收录的经典译文《日志每个软件工程师都应该知道的有关实时数据的统一抽象》第一部分part1-what-is-a-log.md系统拆解日志Log这一贯穿数据库、分布式系统与实时数据处理的核心抽象。你将理解为什么追加写入、按序读取的日志能定义分布式系统中的时间如何借助状态机复制原理让多副本保持一致以及表与事件的二象性为什么让日志成为比表更底层的数据结构。读完本文你可以带着这套底层认知继续阅读本仓库中《The Log》系列的数据集成、实时流处理与系统构建章节形成完整的知识闭环。日志最简单的存储抽象原文对日志的定义非常凝练日志是一种简单到不能再简单的存储抽象——只能追加append-only、按照时间完全有序totally-ordered的记录序列。它看起来就是上图那样一串从左到右排列的记录写入只在日志的末尾追加新记录从不修改或删除已有记录读取从左到右顺序读取先写入的记录先被读到编号每一条记录都拥有一个唯一、有序的日志记录编号sequence number。次序即时间日志与物理时钟的解耦这是第一部分最关键的一个洞察日志记录的次序ordering定义了时间概念——位于左侧的记录比右侧的更早日志记录编号可以看作这条记录的时间戳。刚开始把次序直接当成时间会让人觉得怪异但这个做法有一个极其便利的性质它把时间与任何一个特定的物理时钟physical clock解耦了。物理时钟在多机环境下不可靠不同机器的时钟可能不同步、可能被 NTP 校准回拨而基于日志次序的逻辑时间只依赖事件之间的先后关系天然与机器无关。原文特别强调引入分布式系统之后这会成为一个必不可少的性质。译注提示分布式系统中的时间、次序、时钟概念是整个领域最基础也最根本的问题关联文档中推荐了 Leslie Lamport 的论文《Time, Clocks and the Ordering of Events in a Distributed System》作为延伸阅读建议先读完本系列再深入研究。日志与文件、数据表的异同原文用一个简单的类比消解了日志很特殊的错觉文件是一系列字节数据表table是由一系列记录组成日志实际上就是一种按照时间顺序存储记录的数据表或文件。三者在存储形态上并没有本质区别。真正不同的是日志的用途日志记录的是什么时间发生了什么事情而记录发生了什么恰恰是分布式数据系统在许多方面要解决的真正核心问题。需要提醒的一点日志不可能无限追加因为存储空间总会耗尽——原文明确指出会在后续章节日志合并 log compaction回来讨论这个问题。先厘清概念数据日志与应用日志每个程序员都熟悉另一种日志——应用通过syslog或log4j写入本地文件的无结构错误信息或追踪信息。为了与本文讨论的日志区分原文将前者称为应用日志记录application logging。两者的核心区别在于面向的对象应用日志主要为了方便人阅读是文本形式数据日志journal / data logs用于程序的访问是结构化、可被机器解析的记录。原文甚至认为应用日志是日志概念的退化形态当系统涉及很多服务和服务器时靠人去阅读散落在各台机器上的文本日志很快就会变得难以管理——我们的真实目的很快就变成输入查询、输出用于理解多台机器行为的图表。因此文件中的字句文本几乎肯定不如本文所描述的结构化日志合适。数据库中的日志从 ACID 到复制的演进起源与崩溃恢复日志概念的起源已不可考——它可能像二分查找一样简单到发明者不觉得这是一项发明。早在 IBM 的系统 RSystem R时代日志就已出现。日志在数据库中的最初用法是崩溃恢复为了在崩溃时保持各种数据结构和索引的同步、保证操作的原子性atomic与持久性durable数据库在修改它维护的各种数据结构表、索引等之前先把要做的更改操作信息写入日志。这就是通常所说的**预写日志write-ahead log**机制。这里的核心思想值得反复咀嚼日志记录了发生了什么而每个表或者索引都只是更改历史中的一个投影projection。由于日志会被立即持久化一旦发生崩溃日志就成为恢复所有其他持久化结构的可靠来源。从 ACID 细节到复制机制随着时间的推移日志的用途从 ACID 的实现细节成长为数据库之间复制数据的一种方法。结论很直接发生在数据库上的更改序列正是与远程副本数据库replica database保持同步所需的操作。原文给出了当时的工程事实Oracle、MySQL 和 PostgreSQL都包含日志传送协议log shipping protocol把日志传输给作为备库slave的副本数据库Oracle还把日志产品化为通用的数据订阅机制为非 Oracle 数据订阅用户提供了XStreams与GoldenGate在 MySQL 和 PostgreSQL 中类似的设施是许多数据架构的关键组件。正是由于这样的起源机器可识别的日志概念长期以来被局限在数据库内部日志作为数据订阅机制的用法似乎是偶然出现的。但原文指出这恰恰是支持各种消息传输、数据流和实时数据处理的理想抽象——这一判断为后续三部分数据集成、实时流处理、系统构建埋下了伏笔。分布式系统中的日志排序与分发进入分布式场景日志的价值被彻底放大。原文明确日志解决了两个问题——更改动作的排序ordering和数据的分发distribution而这两者在分布式数据系统中尤为重要。协商达成一致的更改动作顺序或协商一致后去做有副作用的数据拷贝正是分布式系统设计的核心问题之一。状态机复制原理分布式系统以日志为中心的方案来自一个简单观察原文称之为状态机复制原理State Machine Replication Principle如果两个相同的、确定性的进程从同一状态开始并且以相同的顺序获得相同的输入那么这两个进程将会生成相同的输出并且结束在相同的状态。拆解其中的关键词确定性deterministic处理过程与时间无关且不受任何带外out of band输入影响。例如程序的输出如果受线程执行的具体顺序、getTimeOfDay调用或其他不可重复事件的影响那它通常就是非确定性的状态state进程保存在机器上的任何数据——处理结束时这些数据要么在内存里要么在磁盘上。以相同的顺序输入相同的内容这句话应当触发你的条件反射这个地方要引入日志。直觉上如果给两段确定性代码相同的日志输入它们就会产生相同的输出。应用到分布式计算中结论顺理成章把用多台机器执行相同事情的问题化简为用分布式一致性日志作为这些处理的输入的问题。日志的目的是把所有非确定性的东西排除在输入流之外以确保处理这些输入的各个副本replica保持同步。正如原文所说一旦理解后你会发现这个原理差不多等于确定性的处理过程就是确定性的——但它确实是分布式系统设计中一个更通用的工具。一个数字描述一个副本这个方案有一个绝妙之处用于索引日志的时间戳可以充当保持副本状态的时钟。因为每个副本只是按顺序消费日志所以你可以只用一个数字来描述每一个副本——即该副本已处理的最大日志记录的时间戳。日志中的时间戳与副本的完整状态一一对应知道了副本消费到哪条记录就知道了它的完整状态。这把描述整个副本状态的问题压缩成了维护一个偏移量的问题为后续讨论可重放的历史记录和按各自速度消费奠定了理论基础。日志里记什么物理日志与逻辑日志根据写进日志的内容不同状态机复制原理有不同的应用方式。理论上可以记录服务的输入请求日志从请求到响应的服务状态变化日志服务所执行的状态转换命令日志甚至各副本执行的机器指令序列、方法名和参数序列。只要两个进程以相同方式处理这些输入副本进程就会保持一致状态。不同领域对此有不同叫法。数据库工作者通常区分为物理日志physical logging记录每一行被改变的内容逻辑日志logical logging不记录被改变的行而是记录引起行内容改变的 SQL 语句insert、update、delete。两种复制模型主-主active-active与主备primary-backup分布式系统文献通常把处理与复制方案宽泛地分成两类状态机模型State Machine Model常被称为主-主模型active-active model记录输入请求日志各个副本各自处理每个请求主备模型primary-backup model选出一个副本作为 leaderleader 按请求到达顺序处理请求并输出它处理请求产生的状态变化日志其他副本按顺序应用 leader 的状态变化日志保持与 leader 同步并能在 leader 失败时接替它成为新 leader。为了理解两者差异原文给出了一个经典例子——一个需要复制的算法服务维护一个初始值为 0 的独立数字可对它进行加法和乘法运算主-主方式输出所进行的变换日志比如1、*2等。各个副本都应用这些变换从而经过一系列相同的值主备方式由一个独立的 Master 执行这些变换输出结果日志比如1、3、6等。这个例子清楚展示了为什么顺序是保证副本间一致性的关键加法和乘法的顺序改变将导致完全不同的结果(11)*2 4与(1*2)1 3不同。日志与一致性算法Paxos、ZAB、RAFT 与 Viewstamped Replication分布式日志可以看作建模一致性consensus问题的数据结构因为日志代表了下一个追加值的一系列决策。Paxos算法簇你需要眯起眼睛才能在 Paxos 中找到日志的身影尽管构建日志是它最常见的实际应用。Paxos 通过扩展协议multi-paxos来构建日志——把日志建模为一系列一致性值的问题日志的每条记录对应一个一致性值ZABZooKeeper 所用算法、RAFT、Viewstamped Replication这些协议中日志的身影明显得多它们建模的问题直接就是维护分布式一致的日志。原文还提出一个颇有远见的观点在现实中计算机系统几乎不需要决定单个的值而是要处理一序列的请求因此日志而不是简单的单值寄存器是更自然的抽象。对算法的专注有时掩盖了系统底层所需的日志抽象——正如我们讨论哈希表时不会纠结于用线性探测的 murmur hash 还是某个变种日志终将成为一种大众化的接口可以有多种竞争的算法和实现去提供最好的保证和最佳的性能。延伸阅读本仓库还收录了两篇与本节直接相关的一致性算法译文可与本文对照阅读Paxos Made Simple 中文翻译 与 PaxosLease实现租约的无盘 Paxos 算法前者给出多实例 PaxosMulti-Paxos的简洁描述后者是最简单且可以实际使用的 Paxos 算法变种。变更日志 101表与事件的二象性回到数据库场景原文揭示了变更日志与表之间迷人的二象性duality日志类似借贷清单和银行处理流水数据库表则是当前账户的余额。如果有变更日志你就可以应用这些变更生成数据表并得到当前状态而表记录的是每条数据的最后状态——即日志在某个特定时间点的投影。日志是更基本的数据结构由此可以认识到日志是更基本的数据结构——日志除了可用来创建原表也可以用来创建各类衍生表表也可以是非关系型用户使用的键值数据存储keyed data store。这个过程还是可逆的如果你对一张表进行更新你可以记录这些变更并把所有更新的变更日志发布到表的状态信息中——这些变更日志正是你所需要的、支持准实时复制的数据。基于此表与事件的二象性就变得清晰了表支持了静态数据日志记录了变更。日志的魅力在于它是变更的完整记录它不仅包含表的最终版本内容而且可以用于重建任何存在过的其它版本。事实上日志可以看作表每一个历史状态的一系列备份。译注二象性duality是个冷门词汇常借自光的波粒二象性——数据在不同条件下分别表现出表与事件的性质。若觉得二象难以理解可以理解为对偶互通对称或可逆即数据表和数据事件之间可以互相转化。版本控制的类比这可能会让你想到源代码版本控制source code version control——源码控制与数据库之间有着密切的关系版本管理解决的是与分布式数据系统非常类似的问题——管理分布式、并发的状态变更版本管理系统建模的是补丁序列the sequence of patches这实际上就是日志你可以检出当前代码的一个快照直接操作这个代码快照可以类比成表正如有状态的分布式系统一样版本控制系统通过日志来完成复制更新代码即拉下补丁并应用到当前快照。原文还提到销售日志数据库的公司Datomic在其系统设计中应用了这些想法——但这些想法并非 Datomic 专属相关理念在分布式系统和数据库文献中已沉淀多年。面向后续日志如何走向数据集成与实时处理第一部分的理论内容可能略显抽象但它是后续全部实战内容的地基。原文预告了剩下三部分的核心主题本仓库均已收录数据集成Data Integration——让组织中所有存储和处理系统可以容易地访问组织所有的数据核心方案是把所有数据提取到用于实时订阅的中心日志中实时数据处理——计算生成的数据流日志就是流的另一种说法日志是流处理的核心分布式系统设计——如何通过集中式日志的设计来简化实际应用系统。所有这些用法都是通过把日志用作一个独立服务来实现的。贯穿始终的底层逻辑是日志的好处都来自它所提供的简单功能——生成持久化的、可重放的历史记录。原文特别强调了一个令人意外的事实能让多台机器以确定性的方式、按各自的速度重放历史记录的能力正是这些问题的核心。如果你希望从更完整的视角进入这个主题建议先阅读本系列的概述与译序再依次读完数据集成、实时流处理与系统构建三个部分最后可参考文末的学术论文、系统与开源软件清单继续深挖。小结第一部分的核心结论可以浓缩为五句话日志是只能追加、完全有序的记录序列记录次序定义了时间日志编号即时间戳天然与物理时钟解耦日志与表只是同一枚硬币的两面日志记录发生了什么表是更改历史的投影日志是更基本的数据结构状态机复制原理让以相同顺序向确定性进程提供相同输入成为分布式一致性的通用解法一个偏移量数字即可描述副本状态数据库的预写日志从 ACID 实现细节演进为复制机制而分布式一致性算法Paxos、ZAB、RAFT、Viewstamped Replication的本质工作就是构建日志日志的核心能力是生成持久化、可重放的历史记录——这正是数据集成、实时流处理与分布式系统设计三大实战场景共同的地基。把握住日志即顺序、日志即时间、日志即历史这三层含义你就掌握了理解现代分布式数据系统的钥匙。赞分享文档教程知识库【免费下载链接】translations Chinese translations for classic software development resources项目地址https://gitcode.com/gh_mirrors/tr/translations点击查看免费下载相关推荐MMPose RTMPose 跨设备推理基准测试模型选型、测速方法与社区贡献指南MMPose RTMPose 跨设备推理基准测试模型选型、测速方法与社区贡献指南 本文以 RTMPose Benchmarks https://link.gi文档教程知识库Angular CLI Bazel 单仓工程化指南大型工具链项目如何组织构建与发布Angular CLI Bazel 单仓工程化指南大型工具链项目如何组织构建与发布 Angular CLI 仓库是 Angular 官方开发工具链的单仓工程文档教程知识库The Log 中文精读指南日志作为实时数据统一抽象的四大应用维度Jay Kreps 经典长文全解析The Log 中文精读指南日志作为实时数据统一抽象的四大应用维度Jay Kreps 经典长文全解析 导读 本文围绕仓库中《日志每个软件工程师都应该知文档教程知识库上一篇Open Generative AI深度技术指南开源AI创作平台架构解析与实战部署下一篇模块化精准控制重新定义桌面机械臂的开源方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表