对分布式数据库感兴趣的朋友都知道,谷歌的F1和Spanner颠覆了NewSQL技术的发展,所以很多公司都在做NewSQL,导致很多人认为基于MySQL的分布式数据库已经落伍了。其实MySQL并没有过时。本文的主角——RadonDB,将NewSQL领域流行的分布式一致性算法与MySQL相结合,形成了新一代的分布式数据库MyNewSQL,同样实现了可扩展性、高可用、强一致性、易部署等特点。那么,如何将NewSQL领域的热门技术与MySQL相结合,打造全新的分布式数据库呢?一、RadonDB的架构首先看一下RadonDB的架构。如上图所示,上半部分是分布式SQL层,下半部分是存储层。如果我们把F1和Spanner抽象出来,会发现这两层也是。其中,SQL层主要负责解析用户SQL,然后生成分布式执行计划和执行器,然后将这些执行器发送到特定的存储节点执行。虽然架构看起来比较一致,但RadonDB的特殊之处在于底层存储层有多个存储节点。图中每个圆圈内是一个存储节点。每个存储节点都有三个副本。三副本使用Raft协议进行数据同步。每个副本都是一个MySQL。而其他的NewSQL就是一个KV或者其他的存储。2.RadonDB架构层分析下面对架构中的各个技术点进行详细的讲解。SQL节点让我们从查看SQL节点开始。用户请求到达SQL节点后,我们根据数据分布规则生成分布式执行计划,告诉用户SQL将分布到哪些存储节点,然后根据分布式执行计划生成分布式执行器,即是,哪些具体的Storage节点链接、执行、返回。执行完成后,SQL节点会进行二次操作。为什么叫二次手术呢?因为下面是MySQL,SQL节点将计算推送给MySQL,SQL节点进行二次操作,包括limit/groupby/aggregation/join。因此,SQL节点是去中心化的、无状态的、可扩展的。3.存储层存储层由多个Node组成,每个Node是MySQL一主两从,但是这个MySQL比较特殊,因为MySQL没有高可用的方案,大家可能是MHA或者写一个master-slave自己切换脚本来运维。但是,RadonDB引入了去中心化的Raft协议。当主库挂掉时,通过Raft协议选出新的master,数据同步基于MySQLGTID机制。基于MySQL的好处是不仅有存储能力,还有计算能力。如果一个副本只是一个KV,那么它的计算能力是比较有限的。SQL层将数据推送到存储层,再返回给SQL节点进行计算,这样存储层就会和SQL层有更多的交互。我们尽量把计算能力下放到存储层,让MySQL来完成,因为MySQL和数据是在一起的,不涉及网络传输,只需要很少的I/O就可以过滤掉数据。4.数据分布刚才说了SQL层和存储层,我们来看看数据是怎么分布的?创建一张T1表,后面指定的分区方式为HASH。在RadonDB中,全表默认共有4096个slot,每张小表默认有128个slot。其实就是把一个大表分成32个小表,比如两个存储节点。T1表的32张小表中,前16张小表在第一个存储节点上,后16张小表在第二个节点上,均匀分布。很多人可能会觉得基于MySQL的扩展是个问题,但是正如上文所说,RadonDB在分表后,以小表为单位进行数据迁移,所以扩展非常方便。如果新增节点,RadonDB会把一些动态小表迁移到新节点上,因为我们是基于MySQL的,会先做全量,然后记下位置,等待全量完成后增加增量,迁移过程基本不影响业务。因此,每个小表都可以在多个存储节点上动态漂移。这些迁移规则也可以自定义,比如先迁移比较大的表或者流行度高的表,这样可以尽可能快的实现整体资源分配的最大化。5、如何保证高可用?一个存储节点三副本如何保证高可用?我们将分布式共识算法Raft与MySQL自带的GTID相结合。Raft主要做了两件事,一是master选举,二是数据同步。MySQL5.7GTID类似于Raft中的日志索引。数据同步是通过GTID,master选择是通过Raft。我们开发了一个Raft框架来实时监控MySQL的状态。如果master异常,我们会发起新的master选举。选举后如何同步新的master和另外两个slave数据库的数据?两个slave根据各自的GTID从master拉取数据,进行数据同步。MySQL5.7可以并行复制,过程非常快,主从之间基本没有延迟,高压情况下延迟很小。而且比较强的半同步保证了交易不丢失。存储节点中的Raft和GTID不中心化,可以跨机房部署,非常灵活。6.分布式事务我们来看看分布式事务。为什么分布式数据库需要分布式事务?因为数据是分布式存储在存储节点中的,比如一张表存储在节点1、节点2、节点3,然后执行一个操作,节点1成功,节点2失败,并在节点3中成功。如果这时候没有分布式事务,那表其实是坏了。如果没有分布式事务保证,数据将随时不可用,只能用来存储不重要的业务。所以RadonDB提供了分布式事务。比如刚才的案例,2发生故障后,存储节点1和3会自动回滚,这是分布式事务的保证。RadonDB分布式事务也是基于MySQL实现的,在MySQL中是分两阶段提交的。首先,它会执行xastart,然后执行SQL,执行xaend,第四次执行xaprepare。这是第一阶段,此时会从副本复制交易;第二阶段是xacommit。因此RadonDB在SQL层实现了事务管理,将MySQL的5个步骤抽象为3个。第一是开始,第二是执行,第三是提交。如果Prepare失败,可以执行Rollback。说到分布式事务,你可能会问,这个事务的隔离级别是多少?RadonDB实现了SnapshotIsolation,也就是快照隔离级别。什么概念?当部分分区没有提交时,这个事务对其他事务是不可见的,即partialcommit是不可见的。另外,uncommitted是不可见的,也就是说prepare做了,但是没有Commit,也是不可见的。7、SI隔离级别大家可以看一下上图右边的两条SQL语句。连接两个客户端,一个客户端扫描表,第二个SQL语句不断更新表。对于SI隔离级别,我们使用了XeLabs/go-jepsen、1个更新线程和16个表扫描线程。经过100亿次以上的运行和监控,没有发现问题,可以随机杀掉存储节点的主副本。这些都证明了MySQLXA具有非常强大的功能。RadonDB还支持HTAP混合模式。在传统的解决方案中,一般有两个系统,即两个端口。当需要事务和分析时,分别在两个端口处理,通过中间的ETL通道进行数据同步。但是,RadonDB中只有一个端口。如果是OLAP操作,我们会自动路由到计算节点,OLTP和OLAP两种计算资源是隔离的,互不影响。8.性能***看看RadonDB的性能。上图是单个MySQL和四个存储节点的RadonDB的对比。我们用sysbench16张表,512个线程,随机写入了5000万条数据。测试结果表明,RadonDB基本可以做到26589TBS,单机是9346TBS。可以看出,RadonDB在TBS级别的性能几乎是单机延迟的三倍,但延迟只有三分之一。这就是分布式数据库的强大之处,性能和容量可以随着节点的增加线性增长。作者简介张燕飞,青云QingCloud数据库高级技术专家。TokuDB内核贡献者和维护者,TokuDB企业热备份工具作者。
