加入收藏 | 设为首页 | 会员中心 | 我要投稿 辽源站长网 (https://www.0437zz.com/)- 云专线、云连接、智能数据、边缘计算、数据安全!
当前位置: 首页 > 服务器 > 安全 > 正文

谈谈PhxSQL的设计和实现哲学(下)

发布时间:2021-01-09 15:29:37 所属栏目:安全 来源:网络整理
导读:《谈谈PhxSQL的设计和实现哲学(下)》要点: 本文介绍了谈谈PhxSQL的设计和实现哲学(下),希望对您有用。如果有疑问,可以联系我们。 开源地址 https://github.com/tencent-wechat/phxsql 摘要 前面讨论了我们为什么要做PhxSQL和为什么这样做PhxSQL.这里
副标题[/!--empirenews.page--]

《谈谈PhxSQL的设计和实现哲学(下)》要点:
本文介绍了谈谈PhxSQL的设计和实现哲学(下),希望对您有用。如果有疑问,可以联系我们。

开源地址

https://github.com/tencent-wechat/phxsql

摘要

前面讨论了我们为什么要做PhxSQL和为什么这样做PhxSQL.这里我们主要谈谈为什么不做某些特性.舍得舍得,有舍才有得.CAP告诉我们只能三选二,俗话告诉我们天下没有免费的午餐.每个特性除了自身提供的功能,也有其代价.为了保证强一致的线性一致性、高可用、serializable级别事务隔离、完全兼容MySQL、和最小侵入MySQL,PhxSQL放弃了一些特性.

上一章链接:谈谈PhxSQL的设计和实现哲学(上)

正文

7. Why Not?

7.1. 为什么不支持多写?

多写想想就很诱人.多写可以充分利用每台机器写时需要的资源.例如某些写操作可能非常耗费CPU,多写可以把写操作分散在各台机器上,充分利用各个机器的CPU资源,极大提高写入的性能.多写使得换主没有存在的必要,也就没有换主时可能存在的不可写时间窗问题.多写还使得客户端可以就近写入,减少跨数据中心写入带来的网络延迟.

多写有两种:大家熟知的分shard或者组,各shard或者组间并行写入,以Google Spanner[8]为典型代表;在shard或者组内并行,以Galera和MySQL Group Replication为代表.

7.1.1. 组间多写

组间多写是把数据分成多个不相交的shard,每个组的机器负责一个shard .当一个事务涉及的数据(读集合和或写集合)都在某个组时,这种事务称为本地事务.当一个事务涉及的数据分布在超过一个组时,这种事务称为分布式事务.

本地事务可以在本组独立执行,组之间不需要任何通信.为了减少事务冲突带来的性能降低,一般都是由组内leader执行本地事务,通过Paxos等一致性协议保证组内机器的数据一致[8].各个组间并行执行本地事务,可以极大提高本地型事务的写性能.

组间多写最大的阻碍是分布式事务,而分布式事务是非常昂贵的.在SQL的模型中,为了实现read repeatable级别的事务隔离,事务管理器需要检查两个并发事务的写数据集是否冲突;为了达到serializable级别的事务隔离,事务管理器需要检查两个并发事务的读数据集和写事务集是否冲突[10].这一般通过严格两阶段锁(strict two-phase locking,严格2PL)和/或者多版本并发控制MVCC实现.当这些数据集跨组时,就涉及到跨组的机器通信.

一个组同时遇到本地事务和分布式事务时,在本组需要根据事务的隔离级别,由事务管理器仲裁执行.

以Google Spanner为例,一个涉及两个机器组(Spanner中的组是指Paxos组)事务就需要在coordinator leader和non-coordinator-participant leader之间两次通信,前者组内还涉及一次Paxos写操作,后者组内再加两次Paxos写操作[8,Sec. 4.2.1 Read-Write Transactions].当跨机房部署时,机器之间的网络延迟使得通信代价更加高昂.Spanner为了减少这种昂贵的跨组事务,要求所有数据都必须有Primary key,并且其它数据尽量挂接在Primary key下面,使得事务尽量在一个组内、且由组内leader执行.

7.1.2. 组内多主多写

组内多主多写时每个机器都有完整的数据,但这份数据分成不相交的逻辑集合,每个机器负责一个集合的写入.这台机器称为这个集合的主机,这个集合称为这个主机负责的数据,其它机器称为这个集合的备机.客户端将写操作发到所涉及数据的主机,由主机通过atomic broadcast原子广播将更新请求发送给组内所有的机器,包括主机本身[9].Galera和MySQL Group Replication都是采用这种方法.

图 3:组内多主多写架构[9]

原子广播具有3个特性:

  1. 如果一台机器执行一条消息所带的更新命令,那么所有的其它机器都执行这条命令(delivered).这里“执行”指的是原子广播层将消息交给上层,真实的执行时刻由上层决定.在数据库中,这个上层一般是并发事务管理器,它决定这些消息的真实执行顺序.
  2. 所有机器以相同的顺序执行命令
  3. 如果一台机器成功广播了一条消息,那么最终所有机器都将执行这条消息

使用原子广播后,事务的生命周期从prepare->committed/aborted改变为prepare->committing->committed/aborted.

图 4:事务生命周期状态转换[9]

当一个事务只涉及到一个集合的数据时,称为本地事务,由这个集合的主机的本地事务管理器先使用本地严格2PL仲裁,然后将committing状态的事务通过原子广播发给其它备机.

当一个事务涉及到多于一个集合的数据时,称为复合事务(complex transaction).这个事务所涉及的某个数据集合的主机将committing事务状态,包括读集合(如果需要serializable级别隔离.这里的一个小优化是采用dummy row减少可能极其庞大的读集合[10])、写集合、以及committing状态,通过原子广播发给全组进行仲裁.Galera和MySQL Group Replication都只是校验写集合,因此不支持serializable级别事务隔离[18].

每台机器都可以通过本地事务状态和原子广播收到的消息,独立判定committing事务最终是提交还是终止.这种判定由原子广播的特性保证全局一致.

图 5:Deferred Update Replication和Certification-based Replication事务执行时序[11]

强调一下:在机器通过原子广播进行数据同步时,事务的最终结果不能在广播前决定,而是在执行这条消息依赖的前置消息及这条消息后才能决定.这称为Deferred Update Replication[9][14]推迟的更新复制或者Certification-based Replication[11].这里有个重要特点需要注意:只有收到一条消息的所有前置消息后,这条消息和所有未执行的前置消息才能由事务管理器并发执行.因此,这里引入了一定的串行化.

原子广播的突出优点是在低延迟局域网有很高的吞吐率.

但同时原子广播有不小的按机器个数放大的网络延迟,在非低延迟网络会显著放大网络延迟.MySQL Group Replication使用的Corosync[16]和Galera[15]支持的Spread[17]都是基于Totem[13]这个成员管理和原子广播协议.

(编辑:辽源站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读