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出色的编码系统所解决了。真的是太完美了。

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时间。

参考:

https://www.oschina.net/news/84386/about-distributed-database?utm_source=tuicool

https://www.syn029.com/h-nd-489.html?groupId=-1

【TIDB】3、数据库的发展历史、现在、未来的更多相关文章

  1. 为什么会出现container、injection技术?发展历史及未来发展趋势

    container 原因: 随着软件开发的发展,相比于早期的集中式应用部署方式,现在的应用基本都是采用分布式的部署方式,一个应用可能包含多种服务或多个模块,因此多种服务可能部署在多种环境中,如虚拟服务 ...

  2. Update(stage3):第1节 redis组件:1 - 3、web发展历史以及redis简介

    Redis课程教案 1. NoSQL数据库的发展历史简介 1.web系统的变迁历史 web1.0时代简介 基本上就是一些简单的静态页面的渲染,不会涉及到太多的复杂业务逻辑,功能简单单一,基本上服务器性 ...

  3. CentOS以及Oracle数据库发展历史及各版本新功能介绍, 便于构造环境时有个对应关系

    CentOS版本历史 版本 CentOS版本号有两个部分,一个主要版本和一个次要版本,主要和次要版本号分别对应于RHEL的主要版本与更新包,CentOS采取从RHEL的源代码包来构建.例如CentOS ...

  4. FPGA技术的发展历史和动向

    本文关键字:fpga技术,fpga发展, fpga培训,FPGA应用开发入门与典型实例 一.FPGA技术的发展历史 纵观数字集成电路的发展历史,经历了从电子管.晶体管.小规模集成电路到大规模以及超大规 ...

  5. JavaScript 、ECMAScript、commonJS 发展历史 与标准化发展

    本文介绍下JavaScript和 ECMAScript的诞生及发展历史,以及标准化过程. 一.JavaScript诞生 1994年,网景公司(Netscape)发布了Navigator浏览器0.9版. ...

  6. Java EE中的容器和注入分析,历史与未来

    Java EE中的容器和注入分析,历史与未来 java中的容器 java中的注入 容器和注入的历史和展望 一.java中的容器 java EE中的注入,使我们定义的对象能够获取对资源和其他依赖项的引用 ...

  7. Web开发技术发展历史

    Web开发技术发展历史   来自:天码营 原文:http://www.tianmaying.com/tutorial/web-history Web的诞生 提到Web,不得不提一个词就是"互 ...

  8. .net版本发展历史

    最近装上了VS2013,发现好多新特性.新功能,公司办公还在使用VS2005.VS2008,不过用着也很顺手,在最新版Visual Studio中,微软加入了git源码管理工具,和之前的TFS大体上类 ...

  9. Hadoop发展历史简介

    简介 本篇文章主要介绍了Hadoop系统的发展历史以及商业化现状, 科普文. 如果你喜欢本博客,请点此查看本博客所有文章:http://www.cnblogs.com/xuanku/p/index.h ...

随机推荐

  1. C#winform的datagridview设置选中行

    this.dataGridView1.CurrentCell = this.dataGridView1[colIndex, rowIndex];this.dataGridView1.BindingCo ...

  2. 使用 eslint 和 editorconfig 规范代码

    项目中使用eslint 为什么使用eslint : 为了保持代码风格的统一 在做vue项目的时候, 基本上都会使用 vue-cli 脚手架去创建一个vue 项目,里面可以选择使用eslint 代码检测 ...

  3. 【Leetcode-easy】Remove Element

    思路:遍历数组,count保存下一个元素的位置,如果不与该元素相同,那么将该数保存在count位置,并且count++,否则,继续遍历. public int removeElement(int[] ...

  4. SQL语句性能优化操作

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引. 2.应尽量避免在where子句中对字段进行null值判断,创建表时NULL是默认值,但大多数时候应 ...

  5. 常用的.gitignore文件

    target/ !.mvn/wrapper/maven-wrapper.jar ### STS ### .apt_generated .classpath .factorypath .project ...

  6. HDU4825 Xor Sum —— Trie树

    题目链接:https://vjudge.net/problem/HDU-4825 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Li ...

  7. Contiki源码结构

    Contiki源码结构 apps目录下,用于存放Application,也就是我们的应用程序放在这个目录下.如webserver,webrowser等,如下图所示. core目录是contiki操作系 ...

  8. CSS3实现水位充满文字特效

    CSS3实现水位充满文字特效是一款既是Loading特效也是文字特效,Loading动画开始时,文字中的水位渐渐上升,为了模拟水位上升的真实效果,水面还会波浪浮动,当Loading动画结束时,文字中的 ...

  9. Meta viewport 学习整理

    The meta viewport tag contains instructions to the browser in the matter of viewports and zooming. I ...

  10. PHP读取xml方法介绍

    一,什么是xml,xml有什么用途 XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Marku ...