首页 > 其他分享 >spanner,mit6.824论文解读

spanner,mit6.824论文解读

时间:2024-05-27 11:28:56浏览次数:27  
标签:事务 读取 只读 Paxos T2 解读 提交 spanner mit6.824

为什么选择这篇论文(Google Spanner, OSDI 2012)?

  • 宽域分布式事务的罕见示例。
    • 非常理想。
    • 但是二阶段提交被视为太慢并且容易阻塞。
  • 宽域同步复制的罕见示例。
  • 巧妙的想法:
    • 通过Paxos进行的两阶段提交。
    • 同步时间用于快速只读事务。
  • 在Google内部广泛使用。

动机用例是什么?

  • Google F1广告数据库(第5.4节)。
  • 之前分片在许多MySQL和BigTable DBs上;笨拙。
  • 需要:
    • 更好的(同步)复制。
    • 更灵活的分片。
    • 跨分片事务。
  • 工作负载主要由只读事务主导(表6)。
  • 需要强一致性。
    • 外部一致性/线性一致性/可串行化。

基本组织结构:

  • 数据中心A:
    • “客户端”是Web服务器,例如用于gmail
    • 数据在多个服务器上分片:
      • a-m
      • n-z
  • 数据中心B:
    • 拥有自己的本地客户端
    • 以及数据分片的自己的副本
      • a-m
      • n-z
  • 数据中心C:
    • 相同的设置
  • 通过Paxos管理复制;每个分片一个Paxos组。

    • 副本位于不同的数据中心。

    • 类似于Raft – 每个Paxos组都有一个领导者。

    • 如实验室中一样,Paxos复制操作日志。

为什么采用这种安排?

  • 分片通过并行性允许巨大的总吞吐量。
  • 数据中心独立失败 – 不同的城市。
  • 客户端可以读取本地副本 – 快速!
  • 可以将副本放置在相关客户附近。
  • Paxos只需要多数 – 容忍慢的/远程的副本。

面临的挑战是什么?

  • 读取本地副本必须获得最新数据。
    • 但是本地副本可能不反映最新的Paxos写入!
  • 一个事务可能涉及多个分片 -> 多个Paxos组。
  • 读取多个记录的事务必须是可串行化的。
    • 但是本地分片可能反映了不同子集的已提交事务!

Spanner对读/写事务和只读事务进行不同的处理。

  • 首先,读/写事务。

    • 读/写事务示例(银行转账):

    • BEGIN
          x = x + 1
          y = y - 1
        END
      
    • 我们不希望任何读取或写入x或y在我们两个操作之间偷偷进行。提交后,所有读取都应该看到我们的更新。

  • 总结:使用Paxos复制参与者的两阶段提交(2pc)。

    • (现在省略时间戳。)(这适用于读/写事务,而不是只读事务。)
    • 客户端选择一个唯一的事务ID(TID)。
    • 客户端将每个读取发送到相关分片的Paxos领导者(2.1)。
      • 每个分片首先在相关记录上获取锁。(可能必须等待)。
      • 每个分片的领导者都有单独的锁表。
      • 通过Paxos不复制读锁,所以领导者失败 -> 中止。
    • 客户端保持写操作私有直到提交。
    • 当客户端提交(4.2.1)时:
      • 选择一个Paxos组充当2pc事务协调器(TC)。
      • 将写操作发送到相关分片领导者。
      • 每个被写入的分片领导者:
        • 在被写入的记录上获取锁。
        • 通过Paxos记录一个“准备”记录,以复制锁和新值。
        • 告诉TC它已准备好。
        • 如果崩溃从而丢失锁表则告诉TC“不”。
    • 事务协调器:
      • 决定提交或中止。
      • 通过Paxos将决定记录到其组。
      • 告诉参与者领导者和客户端结果。
    • 每个参与者领导者:
      • 通过Paxos记录TC的决定。
      • 释放事务的锁。
  • 只读(r/o)事务

    • Spanner为r/o事务消除了两个大成本:

      • 从本地副本读取,避免Paxos和跨数据中心消息。
        • 但请注意,本地副本可能不是最新的!
      • 没有锁,没有两阶段提交,没有事务管理器。

        • 再次避免跨数据中心消息到Paxos领导者。
        • 并避免减慢读/写事务。
      • 表3和表6显示结果是10倍的延迟改善!

      • 如何与正确性相协调?

    • r/o事务的正确性约束:

      • 可串行化:

        • 结果与事务逐一执行相同。
          • 尽管它们实际上可能并发执行。
        • 即r/o事务必须本质上适合在r/w事务之间。
        • 看到之前事务的所有写入,之后事务的没有。
      • 外部一致性:

        • 如果T1在T2开始之前完成,T2必须看到T1的写入。
          • “之前”指的是实际(挂钟)时间。
          • 类似于线性一致性。
          • 排除了读取陈旧数据。

为什么不让r/o事务只读取最新提交的值?

  • 假设我们有两次银行转账,和一个读取两者的事务。

    • T1:  Wx  Wy  C
      T2:                 Wx  Wy  C
      T3:             Rx             Ry
      
    • 结果将不符合任何串行顺序!

      • 不是T1, T2, T3。
      • 也不是T1, T3, T2。
    • 我们希望T3看到T2的所有写入,或者一个也不看。

    • 我们希望T3的读取全部在与T1/T2相同的点发生。

  • 想法:快照隔离(SI):

    • 同步所有计算机的时钟(到实际挂钟时间)。

      • 给每个事务分配一个时间戳。

        • 读/写:提交时间。
        • 读/只:开始时间。
      • 执行时,仿佛按时间戳顺序逐一进行。

        • 即使实际读取顺序不同。
      • 每个副本存储每条记录的多个时间戳版本。

        • 一个读/写事务的所有写入获得相同的时间戳。
    • 一个读/只事务的读取看到的是事务时间戳时的版本。

      • 记录版本的时间戳小于事务的,且是最高的。
  • 我们的例子使用快照隔离:

    •     x@10=9         x@20=8
          y@10=11        y@20=12
      T1 @ 10:  Wx  Wy  C
      T2 @ 20:                 Wx  Wy  C
      T3 @ 15:             Rx             Ry
      
    • “@ 10”表示时间戳。

      • 现在T3的读取将都来自@10的版本。
      • T3不会看到T2的写入,即使T3的读取发生在T2之后。
    • 现在结果是可串行化的:T1 T2 T3
      • 串行顺序与时间戳顺序相同。
    • 为什么T3读取y的旧值是可以的,即使有一个更新的值?
      • T2和T3是并发的,因此外部一致性允许任何顺序。
      • 记住:只读事务需要读取它们时间戳时的值,不看到之后的写入。
  • 问题:如果T3从一个还没看到T1写入的副本读取x会怎样?

    • 因为该副本不在Paxos多数派中?
    • 解决方案:副本“安全时间”。

      • Paxos领导者按时间戳顺序发送写入。

        • 在时间20提供读取服务之前,副本必须看到时间>20的Paxos写入。
          • 所以它知道它已经看到了所有<20的写入。
      • 如果有准备好但未提交的事务也必须延迟(第4.1.3节)。

      • 因此:只读事务可以从本地副本读取 – 通常很快。

  • 问题:如果时钟不是完美同步会怎样?

    • 如果时钟没有完全同步会出现什么问题?

      • 对于读/写事务,使用锁,没有问题。
        • 如果只读事务的TS太大:
          • 它的TS将高于副本安全时间,读取将被阻塞。
          • 正确但慢 – 由于时钟误差增加了延迟。
        • 如果只读事务的TS太小:
          • 它会错过在只读事务开始之前提交的写入。
            • 因为它的低TS将导致它使用记录的旧版本。
            • 这违反了外部一致性。
  • 如果只读事务的TS太小的问题示例:

    • 读/写 T0 @  0: Wx1 C
        读/写 T1 @ 10:         Wx2 C
        只读 T2 @  5:                   Rx?
      (C表示提交)
      
    • 这将导致T2读取时间为0的x版本,即1。但T2在T1提交(实时)之后开始,因此外部一致性要求T2看到x=2。所以必须有解决不正确时钟可能性的方案!

Google的时间参考系统(第5.3节)

  • [UTC, GPS卫星, 主服务器, 服务器, TTinterval]
  • 每个数据中心有几个时间主服务器。
  • 每个时间主服务器要么有一个GPS接收器,要么有一个“原子钟”。
  • GPS接收器通常精确到微秒级别。
  • 论文没有说明它所说的原子钟是什么意思。
    • 可能与GPS同步,但在没有GPS的情况下也能准确一段时间。
    • 如果是自由运行,误差会累积,可能是每周几微秒。
  • 其他服务器与几个附近的时间主服务器通信。
    • 由于网络延迟、检查之间的漂移而产生不确定性。

TrueTime

  • 时间服务产生一个TTinterval = [最早时间, 最晚时间]。
  • 正确的时间保证在这个区间内。
  • 区间宽度根据测量的网络延迟、时钟硬件规格计算而来。
  • 图6:间隔通常是微秒级,但有时超过10毫秒。
  • 因此:服务器时钟并非完全同步,但TrueTime提供了服务器时钟可能有多错的保证界限。

如何确保如果读/写事务T1在只读事务T2开始之前结束,那么TS1 < TS2。

  • 即,确保只读事务的时间戳不会太小。
  • 两条规则(4.1.2):
    • 开始规则:
      • 事务TS = TT.now().latest (获取最新时间)
        • 对于只读事务,是在开始时
        • 对于读/写事务,是当提交开始时
    • 提交等待,对于读/写事务:
      • 在提交之前,延迟直到TS < TS.now().earliest
      • 保证TS已经过去。

使用间隔和提交等待更新的示例:

  • 情景是T1提交,然后T2开始,T2必须看到T1的写入。

  • 即,我们需要TS1 < TS2。

    • 读/写 T0 @  0: Wx1 C
            			|1-----------10| |11--------------20|
      读/写 T1 @ 10:         Wx2 P           C
            							|10--------12|
      只读 T2 @ 12:                           Rx?
      (P表示准备)
      
    • C保证在其TS(10)之后发生,由于提交等待。

    • Rx在C之后发生,因此在时间10之后。

    • T2选择TT.now().latest,这在当前时间之后,即在10之后。

    • 所以TS2 > TS1。

为什么这提供了外部一致性:

  • 提交等待意味着读/写TS保证在过去。
  • 只读TS = TT.now().latest保证>=正确时间
    • 因此>=任何之前提交事务的TS(由于其提交等待)

更一般地:

  • 快照隔离为您提供可串行化的只读事务。
    • 时间戳设定一个顺序。
    • 快照版本(和安全时间)实现了在时间戳处一致的读取。
    • 事务看到来自低TS(时间戳)事务的所有写入,来自高TS事务的则没有。
    • 如果你不关心外部一致性,任何数字对于TS来说都可以。
  • 同步的时间戳产生外部一致性。
    • 即使在不同数据中心的事务之间也是如此。
    • 即使从可能滞后的本地副本读取也是如此。

这一切为什么有用?

  • 快速的只读事务:
    • 从客户端数据中心的副本读取。
    • 无锁定,无两阶段提交。
    • 因此,在表3和表6中实现了10倍的延迟改善。
  • 尽管如此:
    • 由于安全时间,只读事务读取可能会阻塞,以追赶。
    • 读/写事务的提交可能会在提交等待中阻塞。
    • 精确(小间隔)时间最小化这些延迟。

总结:

  • 很少看到部署的系统提供跨地理分布的数据的分布式事务。
  • Spanner是一个令人惊讶的证明,它可以是实用的。
  • 时间戳方案是最有趣的方面。
  • 在Google内部广泛使用;一个商业Google服务;有影响力。

标签:事务,读取,只读,Paxos,T2,解读,提交,spanner,mit6.824
From: https://blog.csdn.net/qq_52010229/article/details/139221752

相关文章

  • 解读注意力机制原理,教你使用Python实现深度学习模型
    本文分享自华为云社区《使用Python实现深度学习模型:注意力机制(Attention)》,作者:Echo_Wish。在深度学习的世界里,注意力机制(AttentionMechanism)是一种强大的技术,被广泛应用于自然语言处理(NLP)和计算机视觉(CV)领域。它可以帮助模型在处理复杂任务时更加关注重要信息,从而提高性能。在本......
  • 解读 MySQL 容器信息:`docker inspect` 字段详解
    前言在使用Docker时,dockerinspect命令是一个非常有用的工具,它能够返回容器或镜像的详细配置信息和状态。以下是对dockerinspectmysql命令输出的字段的详细解释,这些信息可以帮助您更好地了解容器的内部工作机制。容器基础信息Id:容器的唯一标识符。Created:容器......
  • 每日一题——Python实现PAT甲级1023 Have Fun with Numbers(举一反三+思想解读+逐步优
    一个认为一切根源都是“自己不够强”的INTJ个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数目录我的写法:​编辑代码点评:代码功能时间复杂度空间复杂度优化建议哲学和编程思想举一反三题目链接我的写法:num=input()digits_in......
  • 深度解读速卖通aliexpress.item_review API评论数据
    速卖通(AliExpress)是一个全球知名的跨境电商平台,它提供了各种API接口供开发者使用,以获取平台上的数据。其中,item_review API可能是指用于获取商品评论的API(请注意,实际的API接口名称和参数可能会根据速卖通平台的更新而有所变化)。在深度解读这个API时,我们需要考虑以下几个方面......
  • Go字符串及字符串拼接的反汇编代码解读
    Go字符串及字符串拼接的反汇编代码解读源代码packagemainfuncmain(){s:="helloworld"s+="go\n"print(s)}Go版本jagitch@34c4dd4d4a3e:str-demo$goversiongoversiongo1.22.2linux/amd64运行jagitch@34c4dd4d4a3e:str-demo$gorun......
  • [UDS诊断 03- 诊断会话控制(0x10)]-深度解读
     1.诊断会话       诊断会话模式由诊断服务层用于访问受限于特定会话的不同诊断服务。节点需要支持若干会话模式,如下所示:诊断会话定义    非默认会话启动时,控制器应启动S3_server定时器。如果在这个时间范围内没有从任何一......
  • [UDS诊断 02- 诊断服务及格式]-深度解读
    1.支持的诊断服务 支持的诊断服务注:1)P-物理寻址,F-功能寻址;2)1级和11级为强制等级,3级为支持防盗功能的控制器强制等级;3)控制器支持防盗功能,要求必须达到3级;4)在编程会话中,如果控制器接收到这些服务,应该响应NRC0x11。......
  • 113文章解读与程序——电力系统保护与控制EI\CSCD\北大核心《改进多元宇宙算法的主
    ......
  • 大模型的灵魂解读:Anthropic AI的Claude3 Sonnet可解释性研究
    大模型技术论文不断,每个月总会新增上千篇。本专栏精选论文重点解读,主题还是围绕着行业实践和工程量产。若在某个环节出现卡点,可以回到大模型必备腔调重新阅读。而最新科技(Mamba,xLSTM,KAN)则提供了大模型领域最新技术跟踪。若对于构建生产级别架构则可以关注AI架构设计专栏。技......
  • CyberRT_不同的启动方式的源码解读
    源码解读componentnodereader/writerservice/clientparameterscheduletransportapollo/cyber/cyber.ccCreateNode(){returnstd::unique_ptr<Node>(newNode(node_name,name_space))}apollo/cyber/init.ccInit() OnShutdown()apollo/cyber......