细说分布式数据库的过去、如今与将来


随着大数据这个概念的兴起以及真实需求在各个行业的落地,不少人都热衷于讨论分布式数据库,今天就这个话题,主要分为三部分:第一部分讲一下分布式数据库的过去和现状,但愿你们能对这个领域有一个全面的了解;第二部分讲一下TiDB的架构以及最近的一些进展;最后结合咱们开发TiDB过程当中的一些思考讲一下分布式数据库将来可能的趋势。


1、分布式数据库的历史和现状算法



一、从单机数据库提及数据库


关系型数据库起源自1970年代,其最基本的功能有两个:缓存


  1. 把数据存下来;  安全

  2. 知足用户对数据的计算需求。服务器


第一点是最基本的要求,若是一个数据库没办法把数据安全完整存下来,那么后续的任何功能都没有意义。当知足第一点后,用户紧接着就会要求可以使用数据,多是简单的查询,好比按照某个Key来查找Value;也多是复杂的查询,好比要对数据作复杂的聚合操做、连表操做、分组操做。每每第二点是一个比第一点更难知足的需求。架构


在数据库发展早期阶段,这两个需求其实不难知足,好比有不少优秀的商业数据库产品,如Oracle/DB2。在1990年以后,出现了开源数据库MySQL和PostgreSQL。这些数据库不断地提高单机实例性能,再加上遵循摩尔定律的硬件提高速度,每每可以很好地支撑业务发展。负载均衡


接下来,随着互联网的不断普及特别是移动互联网的兴起,数据规模爆炸式增加,而硬件这些年的进步速度却在逐渐减慢,人们也在担忧摩尔定律会失效。在此消彼长的状况下,单机数据库愈来愈难以知足用户需求,即便是将数据保存下来这个最基本的需求。框架


二、分布式数据库运维


因此2005年左右,人们开始探索分布式数据库,带起了NoSQL这波浪潮。这些数据库解决的首要问题是单机上没法保存所有数据,其中以HBase/Cassadra/MongoDB为表明。为了实现容量的水平扩展,这些数据库每每要放弃事务,或者是只提供简单的KV接口。存储模型的简化为存储系统的开发带来了便利,可是下降了对业务的支撑。分布式


(1)NoSQL的进击


HBase是其中的典型表明。HBase是Hadoop生态中的重要产品,Google BigTable的开源实现,因此这里先说一下BigTable。 


BigTable是Google内部使用的分布式数据库,构建在GFS的基础上,弥补了分布式文件系统对于小对象的插入、更新、随机读请求的缺陷。HBase也按照这个架构实现,底层基于HDFS。HBase自己并不实际存储数据,持久化的日志和SST file存储在HDFS上,Region Server经过 MemTable 提供快速的查询,写入都是先写日志,后台进行Compact,将随机写转换为顺序写。数据经过 Region 在逻辑上进行分割,负载均衡经过调节各个Region Server负责的Region区间实现,Region在持续写入后,会进行分裂,而后被负载均衡策略调度到多个Region Server上。


前面提到了,HBase自己并不存储数据,这里的Region仅是逻辑上的概念,数据仍是以文件的形式存储在HDFS上,HBase并不关心副本个数、位置以及水平扩展问题,这些都依赖于HDFS实现。和BigTable同样,HBase提供行级的一致性,从CAP理论的角度来看,它是一个CP的系统,而且没有更进一步提供 ACID 的跨行事务,也是很遗憾。


HBase的优点在于经过扩展Region Server能够几乎线性提高系统的吞吐,及HDFS自己就具备的水平扩展能力,且整个系统成熟稳定。但HBase依然有一些不足。首先,Hadoop使用Java开发,GC延迟是一个没法避免问题,这对系统的延迟形成一些影响。另外,因为HBase自己并不存储数据,和HDFS之间的交互会多一层性能损耗。第三,HBase和BigTable同样,并不支持跨行事务,因此在Google内部有团队开发了MegaStore、Percolator这些基于BigTable的事务层。Jeff Dean认可很后悔没有在BigTable中加入跨行事务,这也是Spanner出现的一个缘由。


(2)RDMS的救赎


除了NoSQL以外,RDMS系统也作了很多努力来适应业务的变化,也就是关系型数据库的中间件和分库分表方案。作一款中间件须要考虑不少,好比解析 SQL,解析出ShardKey,而后根据ShardKey分发请求,再合并结果。另外在中间件这层还须要维护Session及事务状态,并且大多数方案并不支持跨shard的事务,这就不可避免地致使了业务使用起来会比较麻烦,须要本身维护事务状态。此外,还有动态的扩容缩容和自动的故障恢复,在集群规模愈来愈大的状况下,运维和DDL的复杂度是指数级上升。


国内开发者在这个领域有过不少的著名的项目,好比阿里的Cobar、TDDL,后来社区基于Cobar改进的MyCAT,360开源的Atlas等,都属于这一类中间件产品。在中间件这个方案上有一个知名的开源项目是Youtube的Vitess,这是一个集大成的中间件产品,内置了热数据缓存、水平动态分片、读写分离等,但这也形成了整个项目很是复杂。


另一个值得一提的是PostgreSQL XC这个项目,其总体的架构有点像早期版本的OceanBase,由一个中央节点来处理协调分布式事务,数据分散在各个存储节点上,应该是目前PG 社区最好的分布式扩展方案,很多人在基于这个项目作本身的系统。


三、NewSQL的发展


2012~2013年Google 相继发表了Spanner和F1两套系统的论文,让业界第一次看到了关系模型和NoSQL的扩展性在一个大规模生产系统上融合的可能性。 Spanner 经过使用硬件设备(GPS时钟+原子钟)巧妙地解决时钟同步的问题,而在分布式系统里,时钟正是最让人头痛的问题。Spanner的强大之处在于即便两个数据中心隔得很是远,也能保证经过TrueTime API获取的时间偏差在一个很小的范围内(10ms),而且不须要通信。Spanner的底层仍然基于分布式文件系统,不过论文里也说是能够将来优化的点。


Google的内部的数据库存储业务,大可能是3~5副本,重要的数据须要7副本,且这些副本遍及全球各大洲的数据中心,因为广泛使用了Paxos,延迟是能够缩短到一个能够接受的范围(写入延迟100ms以上),另外由Paxos带来的Auto-Failover能力,更是让整个集群即便数据中心瘫痪,业务层都是透明无感知的。F1是构建在Spanner之上,对外提供了SQL接口,F1是一个分布式MPP SQL层,其自己并不存储数据,而是将客户端的SQL翻译成对KV的操做,调用Spanner来完成请求。


Spanner和F1的出现标志着第一个NewSQL在生产环境中提供服务,将下面几个功能在一套系统中提供:


  1. SQL支持 

  2. ACID事务 

  3. 水平扩展 

  4. Auto Failover

  5. 多机房异地容灾


正由于具有如此多的诱人特性,在Google内部,大量的业务已经从原来的 BigTable切换到Spanner之上。相信这对业界的思路会有巨大的影响,就像当年的Hadoop同样,Google的基础软件的技术趋势是走在社区前面的。


Spanner/F1论文引发了社区的普遍的关注,很快开始出现了追随者。第一个团队是CockroachLabs作的CockroachDB。CockroachDB的设计和Spanner很像,可是没有选择TrueTime API ,而是使用HLC(Hybrid logical clock),也就是NTP +逻辑时钟来代替TrueTime时间戳,另外CockroachDB选用Raft作数据复制协议,底层存储落地在RocksDB中,对外的接口选择了PG协议。


CockroachDB的技术选型比较激进,好比依赖了HLC来作事务,时间戳的精确度并无办法作到10ms内的延迟,因此Commit Wait须要用户本身指定,其选择取决于用户的NTP服务时钟偏差,这点对于用户来讲很是不友好。固然 CockroachDB的这些技术选择也带来了很好的易用性,全部逻辑都在一个组件中,部署很是简单,这个是很是大的优势。


另外一个追随者就是咱们作的TiDB。这个项目已经开发了两年时间,固然在开始动手前咱们也准备了很长时间。接下来我会介绍一下这个项目。


2、TiDB的架构和最近进展


TiDB本质上是一个更加正统的Spanner和F1实现,并不CockroachDB那样选择将SQL和KV融合,而是像Spanner和F1同样选择分离。下面是TiDB的架构图:



这样分层的思想也是贯穿整个TiDB项目始终的,对于测试,滚动升级以及各层的复杂度控制会比较有优点,另外TiDB选择了MySQL协议和语法的兼容,MySQL社区的ORM框架、运维工具,直接能够应用在TiDB上,另外和 Spanner同样,TiDB是一个无状态的MPP SQL Layer,整个系统的底层是依赖 TiKV 来提供分布式存储和分布式事务的支持,TiKV的分布式事务模型采用的是Google Percolator的模型,可是在此之上作了不少优化,Percolator的优势是去中心化程度很是高,整个继续不须要一个独立的事务管理模块,事务提交状态这些信息实际上是均匀分散在系统的各个key的meta中,整个模型惟一依赖的是一个授时服务器,在咱们的系统上,极限状况这个授时服务器每秒能分配 400w以上个单调递增的时间戳,大多数状况基本够用了(毕竟有Google量级的场景并很少见),同时在TiKV中,这个授时服务自己是高可用的,也不存在单点故障的问题。



上面是TiKV的架构图。TiKV和CockroachDB同样也是选择了Raft做为整个数据库的基础,不同的是,TiKV总体采用Rust语言开发,做为一个没有GC和 Runtime的语言,在性能上能够挖掘的潜力会更大。不一样TiKV实例上的多个副本一块儿构成了一个Raft Group,PD负责对副本的位置进行调度,经过配置调度策略,能够保证一个Raft Group的多个副本不会保存在同一台机器/机架/机房中。


除了核心的TiDB、TiKV以外,咱们还提供了很多易用的工具,便于用户作数据迁移和备份。好比咱们提供的Syncer,不但能将单个MySQL实例中的数据同步到TiDB,还能将多个MySQL实例中的数据汇总到一个TiDB集群中,甚至是将已经分库分表的数据再合库合表。这样数据的同步方式更加灵活好用。


TiDB目前即将发布RC3版本,预计六月份可以发布GA版本。在即将到来的 RC3版本中,对MySQL兼容性、SQL优化器、系统稳定性、性能作了大量的工做。对于OLTP场景,重点优化写入性能。另外提供了权限管理功能,用户能够按照MySQL的权限管理方式控制数据访问权限。对于OLAP场景,也对优化器作了大量的工做,包括更多语句的优化、支持SortMergeJoin算子、IndexLookupJoin算子。另外对内存使用也作了大量的优化,一些场景下,内存使用降低75%。


除了TiDB自己的优化以外,咱们还在作一个新的工程,名字叫TiSpark。简单来说,就是让Spark更好地接入TiDB。如今其实Spark已经能够经过JDBC接口读取TiDB中的数据,可是这里有两个问题:1. 只能经过单个TiDB节点读取数据且数据须要从TiKV中通过 TiDB 中转。2. 不能和Spark的优化器相结合,咱们指望能和Spark的优化器整合,将Filter、聚合能经过TiKV的分布式计算能力提速。这个项目已经开始开发,预计近期开源,五月份就能有第一个版本。


3、分布式数据库的将来趋势


关于将来,我以为将来的数据库会有几个趋势,也是TiDB项目追求的目标:


一、数据库会随着业务云化,将来一切的业务都会跑在云端,无论是私有云或者公有云,运维团队接触的可能不再是真实的物理机,而是一个个隔离的容器或者「计算资源」,这对数据库也是一个挑战,由于数据库天生就是有状态的,数据老是要存储在物理的磁盘上,而数据移动的代价比移动容器的代价可能大不少。


二、多租户技术会成为标配,一个大数据库承载一切的业务,数据在底层打通,上层经过权限,容器等技术进行隔离,可是数据的打通和扩展会变得异常简单,结合第一点提到的云化,业务层能够不再用关心物理机的容量和拓扑,只须要认为底层是一个无穷大的数据库平台便可,不用再担忧单机容量和负载均衡等问题。


三、OLAP和OLTP业务会融合,用户将数据存储进去后,须要比较方便高效的方式访问这块数据,可是OLTP和OLAP在SQL优化器/执行器这层的实现必定是千差万别的。以往的实现中,用户每每是经过ETL工具将数据从OLTP数据库同步到OLAP数据库,这一方面形成了资源的浪费,另外一方面也下降了OLAP的实时性。对于用户而言,若是能使用同一套标准的语法和规则来进行数据的读写和分析,会有更好的体验。


四、在将来分布式数据库系统上,主从日志同步这样落后的备份方式会被Multi-Paxos / Raft这样更强的分布式一致性算法替代,人工的数据库运维在管理大规模数据库集群时是不可能的,全部的故障恢复和高可用都将是高度自动化的。