Spanner 是一个可扩展的、全球分布式的数据库,提供分布式ACID。

架构

  • universe:一个部署的实例成为universe,目前谷歌有3个,分别为开发/测试/线上
  • Zone:一个数据中心,相当于一个Hbase/Bigtable

  • Universemaster: 监控这个universe里zone级别的状态信息
  • Placement driver:提供跨区数据迁移时管理功能
  • Zonemaster:相当于BigTable的Master。管理Spanserver上的数据
  • Location proxy:存储数据的Location信息。客户端要先访问他才知道数据在那个Spanserver上
  • Spanserver:相当于BigTable的ThunkServer,用于存储数据

SpanServer

  • tablet:一张表的多个横切的组合(相当于bigtable多个tablet组合),拥有多个副本
  • paxos:每个tablet上都有一个tablet状态机。相关副本的集合成为一个paxos group。
  • lock table:leader采用锁的方式实现并发控制
  • transaction manager:采用两阶段提交完成跨paxos group(多个tablet)的分布式事务。如果事务集中在单个paxos group,可以绕过transaction manager。
  • participan leader和coordinator leader:事务管理器用于实现了participan leader。然后其中一个一个paxos group,被选举为协调者。它的leader和slave分别被称为coordinator leader和coordinator slave

总结:

  1. 使用paxos协议保证了副本的一致性
  2. 多个tablet之间选举协调者(如何选?paxos?),采用两阶段提交处理分布式事务

目录和放置

  • 目录:一个表的横切,相当鱼bigtable的tablet
    movedir后台任务可以让目录在多个paxos group之间迁移

数据模型

spanner数据库的表必须被客户端切割为一个或多个层次结构。使用INTERLEAVE IN语句声明这种层次结构。父表和子孙表相同的第一列放在一起,这样用户定义了这张大表的位置关系。DELETE CASCADE代表级连删除

TrueTime

采用GPS和原子钟提供了TrueTime API

并发控制

spanner提供外部一致性,无锁的只读事务。一定要区分spanner客户端看到的写操作和paxos看到的写操作

时间戳管理

spanner支持的事务类型:

  1. 读写事务(包括单独的写事务)
  2. 只读事务(预先声明的快照隔离事务)
  3. 快照读

paxos领导者租约

paxos leader有租约时间,可以隐式或显示地延长自己的租约时间。

为读写事务分配时间戳

事务读和写采用两段锁协议。当事务获得所有锁后,就给事务分配时间戳。这个时间戳是分配给paxos写操作的,代表事务的提交时间。

spanner依赖以下单调性:每个paxos组内(跨越多个leader,事务相关group吧?)会分配单调递增的时间戳。

spanner外部一致性:如果事务T2在事务T1提交后开始执行,那么事务T1的时间戳一定比T1的时间戳大。

某个时间戳下的读操作

每个副本都会跟踪记录一个值, 这个值被称为安全时间 t(safe), tsafe=min(tsafe_Paxos , tsafe_TM)。小于这个安全时间的读操作,都可以被读取。

为只读事务分配时间戳

一个只读事务分成两个阶段执行: 分配一个时间戳TT.now().latest, 然后当成 快照读来执行事务读操作。

细节

读写事务

将读写事务分为读操作,写操作。写操作先在客户端缓存,所以读操作并不会看到当前事务写的数据。

读操作

读操作先执行,使用伤停等待来避免死锁。读操作执行的时候会获取读锁

写操作

  1. 客户端发起所有写操作的两阶段提交协议,将所有写操作发送给作为协调者的领导者。
  2. 非协调者领导者首先执行预备提交,写操作开始要获取写锁,并将预备提交写入日志
  3. 协调者领导者获取写锁直接提交,写入paxos(时间戳比所有预备提交时间戳大)
  4. 协调者领导者等待获得的提交时间戳成为真实的过去,告知所有非协调者者领导者提交事务,并告知客户端。

时间戳单调性:非协调者leader预备提交->协调者leader获取提交时间戳,提交->协调者等待获得的提交时间戳成为真实的过去->告知非协调者leader和客户端提交,提交后释放锁。

理解:两阶段提交不能单独使用,这里面配合了写锁,paxos协议才保证了事务的一致性。

流程

思考

采用wound-wait解决死锁:

  1. 当较新的任务尝试获得锁,等待直到锁释放
  2. 当较老的任务尝试获得锁,结束较新任务

只读事务

对于只读事务,spanner指定一个读事务时间戳。

  1. 只需要读一个paxos group:直接读请求发给paxos leader,获取一个最新已提交事务时间戳,返回给客户端。
  2. 需要读多个paxos group:
    1. 复杂方式:获取所有paxos group,得到最新的提交事务时间戳
    2. 简单方式:等到当前时间戳成为确定的过去,s_read = TT.now().latest

总结

  1. spanner事务隔离级别为可串行化
  2. 采用两阶段提交协议,锁表(不知道粒度,猜测为tablet级),paxos协议实现事务,TrueTime等待提交(必须有啊,因为只读事务不加锁)
  3. TrueTime API用于给数据加上全局唯一的版本号
    1. 用于实现外部一致性,T1提交后T2才开始,那么此时T1的时间戳肯定小于T2的时间戳
    2. 提供了一致性快照读

分布式事务中的悲观锁和MVCC

下面是一点自己的想法

  1. 事务一般采用两阶段提交的方式
  2. 底层数据采用类paxos一致性协议保证可用性和一致性
  3. 悲观锁不需要全局时间戳,乐观锁需要全局时间戳(或者全局唯一的版本号)

参考资料

spanner的一些思考

Spanner:谷歌新一代全球部署的列式数据库的更多相关文章

  1. 列式数据库~clickhouse 场景以及安装

    一 简介:列式数据库clickhouse的安装与基本操作二 基本介绍:ClickHouse来自俄罗斯,是一款列式数据库三 适用场景: 简单类型的大数据统计四 限制     1 不支持更新操作,不支持事 ...

  2. 数仓选型必列入考虑的OLAP列式数据库ClickHouse(上)

    概述 定义 ClickHouse官网地址 https://clickhouse.com/ 最新版本22.4.5.9 ClickHouse官网文档地址 https://clickhouse.com/do ...

  3. 列式数据库~clickhouse 底层存储原理

    简介:今天介绍列式数据库的一些基本原理 一  数据目录 Data目录 数据存储目录,数据按照part分成多个文件夹,每个文件夹下存储相应数据和对应的元信息文件 Metadata 表定义语句,存储所有表 ...

  4. Hbase与Oracle比较(列式数据库与行式数据库)

    Hbase与Oracle比较(列式数据库与行式数据库) 1 主要区别 Hbase适合大量插入同时又有读的情况 Hbase的瓶颈是硬盘传输速度,Oracle的瓶颈是硬盘寻道时间.   Hbase本质上只 ...

  5. Hadoop HBase概念学习系列之HBase里的列式数据库(十七)

    列式数据库,从数据存储方式上有别于行式数据库,所有数据按列存取. 行式数据库在做一些列分析时,必须将所有列的信息全部读取出来 而列式数据库由于其是按列存取,因此只需在特定列做I/O即可完成查询与分析, ...

  6. 数仓选型必列入考虑的OLAP列式数据库ClickHouse(中)

    实战 案例使用 背景 ELK作为老一代日志分析技术栈非常成熟,可以说是最为流行的大数据日志和搜索解决方案:主要设计组件及架构如下: 而新一代日志监控选型如ClickHouse.StarRocks特别是 ...

  7. 主流列式数据库评测:InfiniDB

    ).本文测试的InfiniDB版本是2010年12月20日发布的2.02版,下载文件名分别为InfiniDB64-2.0.2-2.exe 和InfiniDB64-ent-2.0.2-2.exe.安装文 ...

  8. 列式数据库~clickhouse日常管理

    clickhouse日常管理一 变量相关  1 查看变量     system.setting相关表  2 设置变量     set variables= 请注意这里是session级别,如果想永久生 ...

  9. 列式数据库~clickhouse问题汇总

    一 简介:常见的clickhouse 问题汇总 二 问题系列  1 内存问题     Code: 241. DB::Exception: Received from localhost:9000, : ...

随机推荐

  1. queued frame 造成图形性能卡顿

    曾经遇到过卡顿是类似的原因:当时对显卡底层知识理解不懂,看到引擎底层有一个MaxFramexxx的接口,实现是使用注册表修改显卡底层的注册信息,当时还是一个掉接口习惯的客户端码农的思维,没理解底层含义 ...

  2. Checkpoint--相关问题

    Checkpoint是实例级别还是数据库级别? 答:数据库级别,在SQL Server关闭时,会对所有数据库逐一提交checkpoint 测试代码 USE DB0002 GO CHECKPOINT G ...

  3. Oracle数据库多行记录转换一行并排序函数

    Oracle数据库多行记录转换一行并排序方法 在ORACLE数据库查询中,我们通常会要求用到将多行记录转换成一行并排序,这时候我们自然会想到Oracle的一个“wx_concat”函数,可以将多行记录 ...

  4. C#之使用CefSharp创建客户端

    安装NuGet包 在Visio studio中右击解决方案,选择管理NuGet包,搜索安装CefSharp.WinForms. 配置工作 (1)首先右击项目选择属性,在"生成"选项 ...

  5. 如何使用socket进行java网络编程(四)

    在上一篇的结尾,提到过用来处理每一个服务端accept到的socket,我们由原来最开始的单线程改成了多线程去处理,但是对每一个接收到的socket都new一个thread去处理,这样效率太低,我们需 ...

  6. s11 day100路飞项目逻辑购物车一

    Luffy项目 先看练习,如下: 一. 添加购物车和查看 1. url url(r'^shoppingcar/$', shoppingcar.ShoppingCarView.as_view({&quo ...

  7. C# __arglist 关键字

    using System.Runtime.InteropServices; namespace Alpha { class Beta { [DllImport("msvcrt.dll&quo ...

  8. leetcode 121. 买卖股票的最佳时机 JAVA

    题目: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股票 ...

  9. 740. Delete and Earn

    Given an array nums of integers, you can perform operations on the array. In each operation, you pic ...

  10. python os.path 的使用

    import os #该文件所在位置:D:\第1层\第2层\第3层\第4层\第5层\test11.py path1 = os.path.dirname(__file__) print(path1)#获 ...