欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【TIDB】3、数据库的发展历史、现在、未来

程序员文章站 2022-04-10 20:49:33
1、从单机数据库说起(Mysql、Oracle、PostgreSQL) 关系型数据库起源自1970年代,其最基本的功能有两个: 把数据存下来; 满足用户对数据的计算需求。 第一点是最基本的要求,如果一个数据库没办法把数据安全完整存下来,那么后续的任何功能都没有意义。当满足第一点后,用户紧接着就会要求 ......

1、从单机数据库说起(mysql、oracle、postgresql)

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

  1. 把数据存下来;  

  2. 满足用户对数据的计算需求。

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

在数据库发展早期阶段,这两个需求其实不难满足,比如有很多优秀的商业数据库产品,如oracle/db2。在1990年之后,出现了开源数据库mysql和postgresql。这些数据库不断地提升单机实例性能,再加上遵循摩尔定律的硬件提升速度,往往能够很好地支撑业务发展。

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

2、分布式数据库之nosql的进击(hbase/cassadra/mongodb)

hbase是其中的典型代表。hbase是hadoop生态中的重要产品,google bigtable的开源实现。

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出现的一个原因。

3、分布式数据库之rdms的救赎(cobar、zebra、atlas、vitess)

rdms系统做了不少努力来适应业务的变化,也就是关系型数据库的中间件和分库分表方案。做一款中间件需要考虑很多,比如解析 sql,解析出shardkey,然后根据shardkey分发请求,再合并结果。另外在中间件这层还需要维护session及事务状态,而且大多数方案并不支持跨shard的事务。还有动态的扩容缩容和自动的故障恢复,在集群规模越来越大的情况下,运维和ddl的复杂度是指数级上升。

4、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来完成请求。

5、spanner和f1的追随者

spanner/f1论文引起了社区的广泛的关注,很快开始出现了追随者。第一个团队是cockroachlabs做的cockroachdb。cockroachdb的设计和spanner很像,但是没有选择truetime api ,而是使用hlc(hybrid logical clock),也就是ntp +逻辑时钟来代替truetime时间戳,另外cockroachdb选用raft做数据复制协议,底层存储落地在rocksdb中,对外的接口选择了pg协议。

另一个追随者就是我们做的tidb。tidb本质上是一个更加正统的spanner和f1实现,并不cockroachdb那样选择将sql和kv融合,而是像spanner和f1一样选择分离。

和 spanner一样,tidb是一个无状态的mpp sql layer,整个系统的底层是依赖 tikv 来提供分布式存储和分布式事务的支持,tikv的分布式事务模型采用的是google percolator的模型,但是在此之上做了很多优化,percolator的优点是去中心化程度非常高,整个继续不需要一个独立的事务管理模块,事务提交状态这些信息其实是均匀分散在系统的各个key的meta中,整个模型唯一依赖的是一个授时服务器,在我们的系统上,极限情况这个授时服务器每秒能分配 400w以上个单调递增的时间戳,大多数情况基本够用了(毕竟有google量级的场景并不多见),同时在tikv中,这个授时服务本身是高可用的,也不存在单点故障的问题。

tikv和cockroachdb一样也是选择了raft作为整个数据库的基础,不一样的是,tikv整体采用rust语言开发,作为一个没有gc和 runtime的语言,在性能上可以挖掘的潜力会更大。不同tikv实例上的多个副本一起构成了一个raft group,pd负责对副本的位置进行调度,通过配置调度策略,可以保证一个raft group的多个副本不会保存在同一台机器/机架/机房中。

 6、未来趋势

1、数据库会随着业务云化,未来一切的业务都会跑在云端,不管是私有云或者公有云,运维团队接触的可能再也不是真实的物理机,而是一个个隔离的容器或者「计算资源」

2、多租户技术会成为标配,一个大数据库承载一切的业务,数据在底层打通,上层通过权限,容器等技术进行隔离

3、olap和oltp业务会融合,用户将数据存储进去后,需要比较方便高效的方式访问这块数据,但是oltp和olap在sql优化器/执行器这层的实现一定是千差万别的。以往的实现中,用户往往是通过etl工具将数据从oltp数据库同步到olap数据库,这一方面造成了资源的浪费,另一方面也降低了olap的实时性。对于用户而言,如果能使用同一套标准的语法和规则来进行数据的读写和分析,会有更好的体验。

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

7、知识拓展

7.1、gps同步时钟工作原理

在最初的同步通信系统中,我们会找到一个时钟源,然后把所有的收发子系统都接到这个时钟源上。小型的同步通信系统完全可以这样做,比如一台电脑中的一个同步通信的系统,他们就用电缆线接到一个共同的时钟源上,再来收发信号。

可是一旦同步通信的系统变大到全国性的呢?如果还用电缆或者光缆接到同一个时钟源上,会发生很多问题。首先,建设的成本太大了,要在全国范围内铺设线路,只为传输一个时钟信号,不划算。其次,如果收发信机分别在黑龙江和广东,时钟信号即使以光速传过去,还会产生一定的延时。

每个gps卫星上都有2~3个高精度的原子钟,这几块原子钟互为备份的同时,也互相纠正。另外地面的控制站会定期发送时钟信号,和每一颗卫星进行时钟校准。 

当然你可能会担心卫星信号传送到地面的延迟问题。gps信号中自带了误差纠正码,接收端可以很容易的把延迟的这段传输延迟去掉。另外,由于卫星信号很微弱,只有在室外才能接受的到,因此每个gps授时系统都应当有室外天线,否则就不能用了。

这样一来上面列出的两个问题都解决了。用来铺设全国性电缆并不是每家公司都有资金实力的,而且铺设的成本用来买gps接收器,那肯定可以买到无数个了。而延时的问题,也被gps出色的编码系统所解决了。真的是太完美了。

【TIDB】3、数据库的发展历史、现在、未来

spanner是如何保证每个事务最后得到的commit timestamp介于这个事务的start和commit之间?

在事务开始阶段调用一次truetime,返回[t-ε1,t1+ε1],在事务commit阶段时再调用一次truetime,返回[t2-ε2,t2+ε2],根据truetime的定义,显然,只要t1+ε1<t2-ε2,那么commit timestamp肯定位于start和commit之间。等待的时间大概为2ε,大约14ms左右。可以说,这个延时基本上还可以接受。

7.2、hybrid logical clock(hlc)

每个cockroach节点都维持了一个混合逻辑时钟(hlc) ,相关的论文见 hybridlogical clock paper。hlc时间使用的时间戳由一个物理部件(看作总是接近本地物理时钟)和一个逻辑部件(用于区分相同物理部件上的事件)组成。它使我们能够以较少的开销跟踪相关联事件的因果性,类似于向量时钟(译注:vector clock,可参考leslie lamport在1978年发表的一篇论文《time, clocks, and the ordering of events in adistributed system》)。在实践中,它工作起来更像一个逻辑时钟:当一个节点收到事件时,它通知本地逻辑hlc由发送者提供的事件时间戳,而当事件被发送时会附加一个由本地hlc生成的时间戳。

cockroach使用hlc时间为事务选取时间戳。本文中,所有 时间戳 都是指hlc时间,hlc时钟在每个节点上是都是单一实例的(译注:也就是说每个节点上只有唯一一个hlc时钟,不会有两个时钟,产生两个时间的问题)。hlc时钟由节点上的每个读/写事件来更新,并且hlc 时间大于等于( >= )系统时间(wall time)。从来自其他节点的cockroach请求里接收到的读/写时间戳不仅仅用来标识操作的版本,也会更新本节点上的hlc时钟。这用于保证在一个节点上的所有数据读写时间戳都小于下一次hlc时间。