https://raft.github.io/#implementations
NewSQL 是对各种新的可扩展/高性能数据库的简称,这类数据库不仅具有NoSQL对海量数据的存储管理能力,还保持了传统数据库支持ACID和SQL等特性。
NewSQL是指这样一类新式的关系型数据库管理系统,针对OLTP(读-写)工作负载,追求提供和NoSQL系统相同的扩展性能,且仍然保持ACID和SQL等特性(scalable and ACID and (relational and/or sql -access))。
NewSQL一词是由451 Group的分析师Matthew Aslett在研究论文中提出的。它代指对老牌数据库厂商做出挑战的一类新型数据库系统。
NoSQL将改变数据的定义范围。它不再是原始的数据类型,如整数、浮点。数据可能是整个文件。NoSQL可能会吓到DBA,因为他们担心失去他们自己的领域。
NoSQL数据库是非关系的、水平可扩展、分布式并且是开源的。MongoDB的创始人Dwight Merriman表示NoSQL可作为一个Web应用服务器、内容管理器、结构化的事件日志、移动应用程序的服务器端和文件存储的后备存储。
分三类:
新架构
第一类型的NewSQL系统是全新的数据库平台,它们均采取了不同的设计方法。它们大概分两类:
(1) 这类数据库工作在一个分布式集群的节点上,其中每个节点拥有一个数据子集。 SQL查询被分成查询片段发送给自己所在的数据的节点上执行。这些数据库可以通过添加额外的节点来线性扩展。现有的这类数据库有: Google Spanner, VoltDB, Clustrix, NuoDB.
(2) 这些数据库系统通常有一个单一的主节点的数据源。它们有一组节点用来做事务处理,这些节点接到特定的SQL查询后,会把它所需的所有数据从主节点上取回来后执行SQL查询,再返回结果。
SQL引擎
第二类是高度优化的SQL存储引擎。这些系统提供了MySQL相同的编程接口,但扩展性比内置的引擎InnoDB更好。这类数据库系统有:TokuDB, MemSQL。
透明分片
这类系统提供了分片的中间件层,数据库自动分割在多个节点运行。这类数据库包扩:ScaleBase,dbShards, Scalearc。
NoSQL数据库在以下环境中会体现出明显的优势:
1、数据模型比较简单;
2、需要灵活性更强的IT系统;
3、对数据库性能要求较高;
4、不需要高度的数据一致性;
5、对于给定key,比较容易映射复杂值的环境。
但是,很快NoSQL的问题就暴露出来了,首先由于缺乏统一的标准,不同的系统都有各自的规范,切换成本高,很难通用。而SQL经过多年的发展,已经形成了完整的生态链。
其次NoSQL数据库语言的不成熟增加了系统的复杂性,出现很多胶水代码,一方面系统和应用的对接更加复杂,同时缺乏专业的运维人员和运维工具。非规范反而导致了数据的膨胀和僵化。
传统的SQL无法应对海量数据和高并发的场景,而NoSQL因缺少标准而无法通用,那么数据库的未来在哪里?
目前市场上很多NewSQL数据库是MySQL(开源数据库)结合了大数据的解决方案(比如Hadoop)之后而形成的新的数据库类型,比如 TiDB,OceanBase等。TiDB 能够通过使用 Raft 算法构建分布式可扩展的后端存储系统。当然还有从Pg 与大数据结合衍生出的Cockroach DB 等。
NewSQL的出现代表着SQL标准的回归,也代表数据库的新的变革方向,未来数据库领域终将向着分布式前进,在完善的标准下不断创新和演进,适应海量数据和高并发的业务场景。
https://www.nuodb.com/techblog/benchmarking-google-cloud-spanner-cockroachdb-nuodb
NewSQL概念几乎是紧跟着NoSQL之后变得火热的。Google Bigtable与AWS Dynamo奠定了NoSQL技术的根基,而Google Spanner&F1则引领了NewSQL技术的发展
传统的RDBMS在Scalability能力上的受限,是促使NoSQL技术出现的一个关键因素。在这次Meetup的主题中,涉及到了Cassandra、HBase、MongoDB、CouchDB、HyperTable等开源技术,而该Meetup描述信息中所提及的”open source, distributed, non relational databases”为NoSQL技术给出了精炼的描述。彼时,SQL几乎是RDBMS的代名词,自然而言的,Non-SQL也成了Non-Relational的代名词。
随着近些年的快速发展,SQL已经逐步被应用在了更广泛的领域,因此,SQL已不再是RDBMS的专属特征,NoSQL技术体系中也引入了SQL能力,因此而演变出来的Not-Only-SQL的概念,虽有自圆其说之嫌,但的确给出了更合理的解读。无论如何,”open source, distributed, non relational databases”关于大多数NoSQL技术边界的定义,也依然是合理的,只是,”open source”是一个可选特征,而”distributed”以及”non relational”却是典型NoSQL技术的基本特征。大多数NoSQL技术,弱化了对ACID语义以及复杂关联查询的支持,采用了更加简洁或更加专业的数据模型,优化了读写路径,从而能够换取更高的读写性能。
NewSQL
NewSQL可以说是传统的RDBMS与NoSQL技术结合之下的产物,如下是Wiki中为NewSQL给出的定义:
NewSQL is a class of modern relational database management systems that seek to provide the same scalable performance of NoSQL systems for online transaction processing (OLTP) read-write workloads while still maintaining the ACID guarantees of a traditional database system.
因此,可以将典型NewSQL技术理解成分布式关系型数据库,能够支持分布式事务是一个基本前提。NoSQL与NewSQL在技术栈上有很多重叠,但在是否支持关系型模型及对复杂事务的支持力度上是存在明显区别的。某些地方也将NewSQL划在Not-Only-SQL的范畴之内,即NewSQL技术也被纳入到NoSQL概念体系中,该说法虽也合理,但使得NoSQL一词过于泛化。
业界观点
近期,Timescale DB的联合创始人Ajay Kulkarni曾经发表过如下一篇文章:
“Why SQL is beating NoSQL, and what this means for the future of data”
文章标题话题感十足,主要观点总结如下:
很多新兴技术都已经在拥抱SQL,如AWS Aurora, Google Spanner, Kafka也已经支持了SQL接口等等。
大多数NoSQL技术都定义了独立的且不完善的查询语言接口(DSL),尽管有些NoSQL技术提供了SQL-Like接口,但与标准SQL接口兼容性极差。
NewSQL的兴起,而且开始积极拥抱标准SQL接口。Spanner是典型的例子,最初版本的Spanner的SQL语法的支持度是非常受限的,而最近几年的时间里一直在不断完善SQL语法的支持。
在当前时代,数据的价值越来越大,SQL依然是不同数据源之间的标准接口。而关于SQL语法的支持度,是未来数据分析工作的最大瓶颈点。
Bigtable/HBase/Dynamo是典型NoSQL技术,而Spanner/CockroachDB以及国内的TiDB,可以将其归类为典型NewSQL技术,但像Kudu,它本身的存储引擎层是典型NoSQL技术,而在此基础上提供了完善的SQL能力以及复杂的事务支持,因此,它兼顾了NoSQL与NewSQL的很多特征,更像是集两者于一身的技术。
因此,非NoSQL即NewSQL的简单二分法是不合理的,很多技术都在将两者进行不断的融合,至于这个合理的平衡点在哪里,要取决于这个分布式存储技术要解决的核心问题是什么。
当我们谈论NoSQL,更多的是在谈论一种分布式、非关系型数据存储技术,而谈起NewSQL,更多可能是在讨论一种分布式关系型数据库技术。当用NoSQL或者NewSQL来为一个技术进行归类时,更多考虑的可能是该技术更像什么,例如,如果提供了标准SQL接口以及复杂事务能力,优先使用NewSQL一词来描述是更加贴切的,但该技术幕后的存储引擎,也许是基于NoSQL技术实现的。
最后的总结
在阐述了NoSQL与NewSQL的概念以及两者的范畴之后,再回到本文标题中所提出来的命题,该命题似乎成了一个伪命题,因为两者也都在慢慢演进/融合。所以,对该命题存在疑惑的人,更多是针对如下命题:
分布式关系型数据库技术是否会取代分布式非关系型数据存储技术?
分布式关系型数据库技术在分布式事务以及关系型模型上的强化,导致在数据吞吐量/并发能力上的弱化。借助NuoDB官方提供的一个NuoDB与Spanner/Cockroach的benchmark对比结果(“原文:Benchmarking Google Cloud Spanner, CockroachDB, and NuoDB”)来进一步说明该观点:
可以看出,无论哪种Workload下,Spaner与CockroachDB的Throughput都是很低的。尽管NuoDB也可以归类到 NewSQL的范畴中,但它也大量借鉴了NoSQL技术,将事务机制与持久化机制分层处理以及更好的利用缓存技术是性能取得质的提升的关键。上图中部分Workload中,NuoDB的Throughput几乎达到了主流 NoSQL技术的Throughtput水准,但还是可以看出,当读写比例相当或者写多读少的场景下,NuoDB的Throughput较之主流的NoSQL技术存在明显的差距。
因此,分布式关系型数据库技术与分布式非关系型数据存储技术依然是针对不同的应用场景的,前者主要还是针对传统RDBMS的部分应用场景,而分布式非关系型数据存储技术,则更适合高吞吐、高并发的新兴应用场景,而随着物联网、车联网的不断普及,分布式非关系型数据存储技术也会带来更大的价值。两者还会走向进一步的融合,也会看到更彻底的分离。
1、TiDB:
说明:
PingCAP 公司基于 Google Spanner / F1 论文实现的开源分布式 NewSQL 数据库。
开源分布式 NewSQL 关系型数据库 TiDB 是新一代开源分布式 NewSQL 数据库,模型受 Google Spanner / F1 论文的启发,实现了自动的水平伸缩,强一致性的分布式事务,基于 Raft 算法的多副本复制等重要 NewSQL 特性。TiDB 结合了 RDBMS 和 NoSQL 的优点,部署简单,在线弹性扩容和异步表结构变更不影响业务, 真正的异地多活及自动故障恢复保障数据安全,同时兼容 MySQL 协议,使迁移使用成本降到极低
特性:
SQL支持(TiDB 是 MySQL 兼容的) 水平弹性扩展(吞吐可线性扩展) 分布式事务 跨数据中心数据强一致性保证 故障自恢复的高可用 海量数据高并发实时写入与实时查询(HTAP 混合负载) TiDB 的设计目标是 100% 的 OLTP 场景和 80% 的 OLAP 场景,更复杂的 OLAP 分析可以通过 TiSpark 项目来完成。
2、CockroachDB:
说明:
构建于事务处理及强一致性KV存储上的分布式SQL数据库,支持水平扩展、自动容错处理、强一致性事务,并且提供SQL接口用于数据处理,是Google Spanner/F1的开源实现。 CockroachDB适用于应用对数据要求精确、可靠、完全正确的场景,支持自动复制、均匀分布、基于极小配置的数据恢复,可用于分布式的、可复制的联机事务处理(OLTP),多数据中心的部署,私有云的基础构建,它不适用于读少写多的场景,可以用内存数据库来代替,也不适用于复杂的join查询,重量级的数据分析及联机分析处理(OLAP)。
特性:
支持PostgreSQL
对标准SQL支持较完善
较稳定
TiDB和Cockroach之间存在一些关键差异。
1.用户界面和生态系统尽管TiDB和CockroachDB都支持SQL,但TiDB与MySQL协议兼容,而Cockroach选择PostgreSQL。您可以使用任何MySQL客户端直接连接到TiDB服务器。
2.体系结构整个TiDB项目在逻辑上分为两部分:无状态SQL层(TiDB)和分布式存储层(TiKV)。由于TiDB建立在TiKV之上,开发人员可以根据自己的业务自由选择使用TiDB或TiKV。如果您只需要分布式键值数据库,则可以单独使用TiKV以获得更高的性能和更低的延迟。
总之,我们的系统是高度分层和模块化的,而CockroachDB是一个P2P系统。我们系统的设计导致我们使用两种编程语言:Go for TiDB和Rust for TiKV以提高存储性能。
并且受益于高度分层的架构,我们构建了另一个项目[1],以便在TiDB / TiKV之上运行Apache Spark来回答复杂的OLAP查询。它利用了Spark平台和分布式TiKV集群的优势。
3.事务模型尽管CockroachDB和TiDB都支持ACID事务,但TiDB使用了Google的Percolator引入的模型。该模型的关键特性是它需要一个独立的时间戳分配器。与Spanner一样,TiDB中的每个事务都有一个时间戳来隔离不同的事务。
CockroachDB使用的模型类似于Google在其论文中描述的TrueTime API。然而,与Google不同,CockroachDB没有构建原子钟和GPS接收器来保持不同数据中心的时间一致。相反,它使用NTP进行时钟同步,这导致了不确定错误的问题。为了解决这个问题,CockroachDB采用了混合逻辑时钟(HLC)算法。
4.编程语言TiDB使用Go作为SQL层,使用Rust作为存储引擎层。由于Go具有垃圾收集器(GC)和运行时,我们认为调整性能将花费我们几天的时间。因此,我们对TiKV使用Rust,一种静态语言。它的表现要好得多。CockroachDB只使用Go。
3、FoundationDB:
2018-4 重新开源,资料较少
根据FoundationDB的官方文档,FoundationDB有一系列的局限性:
单个事务数据量不能超过10MB
键的长度不能超过10KB, 值的长度不能超过100KB
系统针对并且只针对SSD优化,使用传统HHD既不保证性能也不保证数据库可用性
FoundationDB对于需要读比较大的主键值范围的查询性能不好
该系统没有实现任何的安全和权限管理,任何人都可以去读和写任意一个主键
系统不支持长时间运行的事务 ,具体来说,一个事务的第一个操作后超过5秒如果事务还没有结束,系统就会报错。
系统只在<500个Core的情况下仔细测过,有性能保证
数据库的数据大小不能超过100TB
系统对每个分区都做3份拷贝,而不会自动对热点增加更多的拷贝,所以读的性能有上限。
4、商用NewSQL:
Spanner、F1:谷歌
OceanBase:阿里
TDSQL:腾讯
UDDB:UCloud
RadonDB:青云中间件
F1是Google开发的分布式关系型数据库,主要服务于Google的广告系统。Google的广告系统以前使用MySQL,广告系统的用户经常需要使用复杂的query和join操作,这就需要设计shard规则时格外注意,尽量将相关数据shard到同一台MySQL上。扩容时对数据reshard时也需要尽量保证这一点,广告系统扩容比较艰难。在可用性方面老的广告系统做的也不够,尤其是整个数据中心挂掉的情况,部分服务将不可用或者丢数据。对于广告系统来说,短暂的宕机服务不可用将带来重大的损失。为了解决扩容/高可用的问题,Google研发了F1,一个基于Spanner(看这里)的跨数据中心的分布式关系型数据库,支持ACID,支持全局索引。2012年初已上线。
F1的几个特性
高可用
可以说,几乎都是Spanner搞定的,Spanner通过原子钟和GPS接收器实现的TrueTime API搞定了跨数据中心时钟误差问题,进而搞定了分布式事务的时序问题,从而搞定了对外部的一致性。多个副本的一致通过Paxos搞定。
全局索引
基于Spanner提供的分布式读写事务(严格的两阶段锁+两阶段提交),F1实现了全局索引。索引表和数据表实际上是两张表,这两张表一般来说存在不同的Spanner机器上,两张表的一致性通过Spanner的分布式读写事务解决。在这里,同一个事务中涉及的全局索引不宜过多,因为每多一个全局索引,相当于多一个两阶段提交中的participant,对于分布式事务来说,participant越多,性能越差,并且事务成功的概率越小。
级联Schema
思想和MegaStore类似,表和表之间有层次关系。将相关表中的相关数据存储在一台机器上。比如对于广告系统来说,就是将一个广告客户以及他的compaign等存储在一起,广告客户作为一张表,compaign作为另外一张表,广告客户表中每行代表一个广告客户,广告客户表叫做root表,compaign表叫做子表,广告客户表中的每行叫做root记录,compaign表中行叫做子记录,那么同一个广告客户下所有的compaign和这个广告客户都存储在同一台Spanner机器上。这样做的好处就是一个操作就可以取到所有的相关数据,join很快,不用跨机。
三种事务
快照读。 直接利用Spanner提供的快照读事务
悲观事务。 直接利用Spanner提供的读写事务,加两阶段锁
乐观事务。 基于Spanner的悲观事务实现的。这样的事务分为两个阶段,第一个阶段是读阶段,持续时间不限,不加任何锁,第二个阶段是写阶段,即commit事务阶段。基本思想是在读阶段将访问的所有行的最后一次修改时间保存在F1客户端,写阶段将所有的时间发到F1,F1开启一个Spanner的读写事务,这个读写事务会重新读取这些行的最后一次修改时间进行check,如果已经变了,说明检测到了写写冲突,事务abort。
F1默认使用乐观事务,主要考虑了如下几个方面:
由于读阶段不加锁,能容忍一些客户端的误用导致的错误
同样,读阶段不加锁,适合F1中一些需要和终端交互的场景。
对于一些出错场景,可以直接在F1 Server进行重试,不需要F1 Client参与。
由于所有的状态都在F1 Client端维护的,故某个F1 Server挂掉后,这个请求可以发给其他的F1 Server继续处理。
当然,这会带来两个问题:
对于不存在的行,没有最后一次修改时间,那么在其他读事务执行期间,同一条语句执行多次返回的行数可能不一样,这种情况在repeatable read这种隔离级别下是不允许的,这个问题典型的解决方案是gap锁,即范围锁,在F1中,这个锁可以是root表中root记录的一列,这个列代表一把gap锁,只有拿到这把锁,才能往child表中某个范围插入行。
对同一行高并发修改性能低。显然,乐观协议不适合这种场景。
部署
Google将广告系统使用的F1和Spanner集群部署在美国的5个数据中心,东海岸两个,西海岸两个,中间一个。相当于每份数据5个副本,其中东海岸一个数据中心被作为leader数据中心。在spanner的paxos实现中,5个副本中有一个leader副本,所有的对这个副本的读写事务都经过它,这个leader副本一般就存在leader数据中心中。由于paxos协议的运行只需要majority响应即可,那么一次paxos操作的延时基本取决于东海岸的leader数据中心和东海岸另外一个数据中心,和中间那个数据中心之间的延时。从这里也可以看出,对于写比较多的F1 Client来说,F1 Client和F1 Server都部署在leader数据中心性能最好。在这个配置下,F1用户的commit延时大概在50ms到150ms之间。读延时大约5~10ms。
mysql的问题在哪?
一、不能通过mysql的server把InnoDB变成一个分布式数据库。
因为mysql生成的执行计划是个单机的
二、一个分布式的plan执行起来很复杂且低效。
比如使用分布式方案Proxy,因为它不支持分布式的transaction,也不支持跨节点的join
三、异步或半同步复制
因为有时候数据出问题你不知道是否应该切换节点,因为异步的方式会导致一部分数据“还在路上”。尤其是对于多数据中心的复制和数据中心的容灾。
而NewSQL真正发展起来是在2014年末到2015年初的时候,Raft论文发表之后,真正的NewSQL理论基础就基本确立了。
那么从技术实现的角度分析,为什么这样的技术会诞生呢?它又能解决哪些过去的产品解决不了或者不是最优方案的场景呢?
首先,举一个范围查询的例子,如果要查找一个班级里成绩在80-90之间的学生,那么通过KV的API的要很麻烦的,但是SQL的优化器就很容易解决此类问题,写一句SQL就可以搞定。
其次是高可用,未来的系统肯定是要设计成Auto-Failover的,即自动恢复,需要人工去干预的容灾系统不是好厨子。
然后针对业务还要说几点:
比如按照ID去分库分表,比如使用一致性哈希去指导节点均衡。如果问题上升到了一定的复杂度,如果再使用应用层的程序逻辑来决定数据流向,那么未免有些low。以后的系统肯定是要设计成完全解耦的,即应用层只负责处理业务逻辑,而数据流转全部交由基础设施层来决策。
下面先介绍下Google Spanner / F1,
http://www.valleytalk.org/wp-content/uploads/2012/10/Spanner-Chinese.pdf
这是厦大老师翻译的,非常棒的一篇论文。
现在有个想法突然冒出来:为什么工业界的论文可以诞生优秀的产品,而学术界却一直默默无闻呢?答案在下面链接中能找到:
http://news.zol.com.cn/647/6477905.html
TiDB and TiKV
首先看下他的架构模型:
其中TiKV对应的事Spanner,而TiDB对应的是F1。
F1强调分布式SQL层实现的方式,这里最重要的一点是它兼容了MySQL协议,对于迁移来说实在太合适不过了。
再来看下逻辑视图:
这个系统共分了六层,最底下的实现是RocksDB(基于LevelDB实现,具有高速写入的特性),在上层的Raft并没有实现Transaction,因为此时他需要保证写入的数据复制了足够多的副本。之后在分布式事务满足了之后再加上SQL层。
然后讲下扩容:
这个很容易理解,每个Region的所有副本组成一个raft group,所以一共有三个raft group,在每个Node上面数据的分布较均匀。因为每个region都分布在了不同的节点上,就算一个节点宕机,其他节点里的每个region也会通过raft的选举策略选出那个备份作为新的leader,将原leader中reply但没有commit的log做一个commit+apply,具体细节可以参考raft官网:https://raft.github.io/#implementations
最后说下分布式事务模型:
大家应该都知道,分布式事务的实现基本都是2PC的,也有2+xPC的,1PC很难做到,除非你在级别上做弱化,如果隔离级别要求很高,1PC是不太好做的。TiDB有一个TiKV driver,可以很好的将SQL语句落到存储层再映射到KV上面。对外的编码格式是Google Protocol Buffer