2018年4月20日,Apple宣布开源FoundationDB——一个分布式KVNoSQL系统,支持多种数据模型、高性能、高可用性、可扩展性和ACID事务。FoundationDB已经在苹果内部生产环境中使用了三年,主要用于iCloud上的云存储服务。Apple在2015年收购了开源的FoundationDB并将其关闭。这次再次开源,是因为苹果预见到FoundationDB有潜力成为下一代分布式数据库系统的底层基础设施。同时,我们也希望借助社区的力量,利用FoundationDB设计的分层机制,开发出以其为底层核心,满足各种应用定制需求的存储系统。这也间接让苹果的底层基础设施更加安全可靠,最终实现公司与社区的双赢。撇开苹果开源FoundationDB背后的商业利益不谈,FoundationDB有两个技术点值得关注:NoSQL+ACID+SQLLayer=NewSQL在独立的KV存储服务上实现事务性ACID语义,然后通过分层设计实现事务性ACID语义在应用层支持文档、图形、SQL等多种数据模型。MVCC+OCC=SSI基于多版本/乐观并发控制技术实现序列化快照隔离级别。1、NoSQL没落?说到NoSQL,大家就会想到谷歌的Bigtable(2008)和亚马逊的Dynamo(2007)。前者是出于互联网企业数据量爆炸式增长的需求,实施了CP系统;而后者基于商业用户的高可用需求,实现了AP系统。1.Bigtable&Dynamo,在CAP定理(2000)的推动下,NoSQL运动如火如荼(AP系统如Cassandra、Voldemort、TokyoCabinet、Riak,CP系统如HBase、Hypertable、MongoDB、Redis),以及总结自己的设计理念:noSQLnoACIDnoschema高性能高可扩展性高可用性低延迟宽松的一致性然而,随着NoSQL系统在应用中的广泛使用,系统设计中遗弃的技术债务已经成为应用开发者的负担。接口千奇百怪,数据不一致问题百出,交易一致性无法保证。正如EricBrewer所说:forfeitingconsistency的隐藏成本,即需要了解系统的不变量。一致系统的微妙之处在于,即使设计者不知道不变量是什么,不变量也往往成立。尤其是谷歌公开的Spanner(2012),在互联网界有着神级存在,成为压垮NoSQL的最后一根稻草,再次改变了分布式数据库系统的发展方向。方向。2、谷歌从NoSQL到NewSQL的过渡谷歌内部存储系统,在自身业务需求的驱动下,经历了几代系统演进,Bigtable、Percolator、Megastore、NoSQLSpanner、F1、SQLSpanner,本质上是一个NoSQL,从NoSQL+APPACID到NoSQL+ACID到NoSQL到ACID到NoSQL到ACID+SQL到SQL。Percolator(2010,NoSQL+APPACID)被实现为一个基于Bigtable的业务系统,用于构建搜索索引。在论文中,作者指出了Bigtable在应用程序需求方面的局限性:像Bigtable这样的分布式存储系统可以扩展到我们存储库的大小,但没有提供工具来帮助程序员在面对并发更新时保持数据不变性。还描述了支持事务语义的好处:...使用户更容易推理系统状态并避免将错误引入长期存储库。Percolator通过2PL技术实现多行ACID事务:...将其锁存储在存储数据的同一个Bigtable中的特殊内存列中,并在访问该行中的数据时读取或修改Bigtable行事务中的锁...Megastore(2011,NoSQL+ACID)本系统用于内部交互式在线NoSQL系统。作者还在论文中指出了实现事务语义的好处:尽管最终一致性系统具有操作优势,但目前在快速应用程序开发中放弃读取-修改-写入惯用语太难了。Megastore通过OCC技术在单个分区上实现ACID事务,但是论文没有详细描述实现细节。Spanner(2012,NoSQLwithACID)该系统是第一个不依赖Bigtable从零开始构建的分布式数据库系统。作者还在论文中强调了支持事务语义的好处:...最好让应用程序程序员在出现瓶颈时处理由于过度使用事务而导致的性能问题,而不是总是围绕缺少事务进行编码。Spanner通过2PL技术实现跨分区的多行ACID事务。F1(2012,NoSQLwithACID+SQL)本系统基于NoSQLSpanner实现为AdWords的存储系统。在论文中(同上),作者直接从业务的角度阐述了事务和SQL的缺失对业务发展的影响:...Thecomplexityofdealingwithanon-ACIDdatastoreineverypartofourbusiness逻辑太复杂了,如果没有SQL查询,我们的业务根本无法运作。F1借助Spanner实现了基于乐观锁的乐观事务,并详细描述了优缺点(无法避免幻读),这在数据库层面与基于OCC技术的事务有着本质区别。Spanner(2017,SQL)这个系统是一个全功能的SQL系统,作者在论文TheimportanceoftransactionsandSQL中再次强调了支持:...许多OLT??P应用的开发者发现如果没有一个强大的模式系统、跨行事务、一致性复制和强大的查询语言。如果没有表达能力强的查询语言:...开发人员不得不编写复杂的代码来处理和聚合其应用程序中的数据。同时,作者高度肯定了NoSQLwithACID+SQL的技术架构:可扩展、可管理、事务性的key-value存储或许是构建企业级全局存储系统的最低公分母。我们的同事已经证明了这一点F1团队认为事务性NoSQL核心可用于构建可扩展的SQLDBMS。此外,在存储系统中实现SQL是松耦合还是紧耦合仍然是一个需要认真讨论的问题:松耦合(以F1为例)和紧耦合的SQL设计都可以成功部署,甚至可以同时部署在事务性NoSQL核心。对这些设计的优缺点的详细探索仍然很突出。但也许可以公平地说,从许多在Google基础设施上工作的工程师的角度来看,SQL与NoSQL的二分法可能不再相关。二、NewSQL的繁荣?根据论文中的定义,NewSQL的核心特性如下:支持SQL接口,支持ACID事务语义。在OLTP场景下,具有NoSQL的高性能、高可用、高扩展性。自Spanner和F1论文发表以来,一些优秀的NewSQL开源项目诞生了:2015年6月4日,前谷歌员工创立了CockroachDB;2015年,它筹集了600万美元;2016年,它筹集了2000万美元;2017年,它筹集了2700万美元。2015年年中,前Peapod员工发布了TiDB;2017年,它筹集了1500万美元。2015年5月24日,惠普开源Trafodion,一个基于HBase的支持ACID事务和SI隔离级别的SQL数据库;2018年1月10日,Apache宣布Trafodion成为顶级项目。2017年11月2日,前Facebook员工创立了YugaByteDB;2017年,它筹集了800万美元;2018年,它筹集了1600万美元。从这些项目的实现架构来看,主要有两种:Native实现:如CockroachDB、YugaByteDBNoSQL+ACID+SQL:如TiDB、TrafodionVoltDB在博文evaluatingFoundationDB中,SQL实现在NoSQL+ACID+SQL架构表示质疑,这种架构的主要技术缺陷是计算不能下沉到存储节点,会造成大量的网络传输开销。不过在谷歌2017年的Spanner论文中,已经将类似这种架构的F1与SQLSpanner进行了对比。两种架构的优缺点还有待观察和研究,但它们的共同点是都依赖于一个支持事务的NoSQL基础。系统。从这个角度来看,以下支持事务的NoSQL系统也有进化为NewSQL的可能:2009年,FoundationDB开源,基于MVCCNoSQL,支持SSI隔离级别;2015年,闭源;2018年4月开源。2016年3月28日,雅虎开源Omid,基于HBase,支持SI隔离级别;它随后被关闭源并商业化为LeanXscale,它也支持SQL。2016年3月7日,Tephra开源,基于HBase,支持SI隔离级别;它由Cask商业化。2018年2月15日,MongoDB宣布在今夏发布的4.0版本中支持多文档ACID事务,基于WiredTiger存储引擎改造。3.事务的核心——并发控制从以上章节NewSQL的发展趋势来看,ACID事务的回归是必然的,在分布式场景下,都致力于实现可伸缩和高性能的串行隔离级别。这在传统数据库的实现中是很难做到的。事务管理的核心技术是并发控制,原子性、一致性、隔离性都与它有关。本章简要介绍事务并发控制技术。事务并发控制是实现事务调度。一个正确高效的事务调度应该满足以下属性:可串行化:多个并发事务的调度S产生与串行化调度相同的结果,调度S被称为可串行化;在数据库实现中,一般会使用冲突序列化技术。可恢复性:提交的事务还没有读到终止事务写入的数据,防止脏读异常。避免级联终止:避免由于事务T1的终止而终止事务T2。严格性:首先发生写操作的事务应该在其他冲突事务提交或终止之前提交或终止。并发控制从实现思路上可以分为以下三类:乐观型:注重事后检测,在事务提交时检查是否满足隔离级别。如果满意,提交;否则,回滚并自动重新执行。悲观:注重事前预防,事务执行时检查是否满足隔离级别。如果满意,继续执行;否则等待或回滚。半乐观:混合乐观和悲观技术来实现事务并发控制。并发控制从实现方式上可以分为以下几种:基于锁的并发控制2PL(两阶段锁定):事务在执行过程中明确分为增长阶段和收缩阶段,增长阶段只能持有锁,不能持有锁releaselocks;收缩阶段只能释放锁不能持有锁,只满足可恢复性;S2PL(stricttwo-phaselocking):在满足2PL的前提下,事务提交后必须释放需要持有的独占锁,避免Cascading回滚;SS2PL(strongstricttwo-phaselocking):在满足2PL的前提下,要求事务提交前不释放锁,保证严格性。基于时间戳的并发控制在事务开始时产生一个单调递增的时间戳,并在数据项上维护最新的读取时间戳和最新的写入时间戳。对于每一次读写操作,系统都会检查事务时间戳和数据项上的时间戳。对于任何读写操作,如果事务时间戳小于该数据项的最新写入时间戳,事务将被回滚;对于写操作,如果事务时间戳小于数据项的最新读取时间戳,则事务将被回滚;如果两者都满足,则继续访问下一个数据项。基于OCC的并发控制事务的生命周期分为三个阶段,序列化检测推迟到commit阶段:读阶段:事务写操作只更新事务私有空间的数据,不更新数据项在数据库中进行真正的更新,保证读阶段没有事务冲突和锁开销;验证阶段:检查事务是否满足序列化隔离级别;写入阶段:将事务私有空间中的更新数据写入数据库。基于多版本的并发控制每次写操作都会产生一个新的数据项版本。数据项的版本号可以使用交易的时间戳或交易号;系统维护多个数据版本,读取操作基于交易的时间戳或交易号。事务号可以读取指定的版本,这样读写或写读操作就不会阻塞,写操作冲突取决于2PL实现。以上只是传统数据库时代总结的并发控制技术。在分布式场景下,一般会结合MVCC和其他并发控制技术来提高并发性,降低同步开销。4.悲观or乐观在了解了数据库的基本并发控制技术后,本章对今天感兴趣的生产级NewSQL分布式数据库所使用的并发控制技术做一个简单的总结:从上表可以看出,FoundationDB是第一个使用OCC技术实现ACID事务的生产级数据库系统(严格来说Google的MegaStore也使用了OCC,用于GoogleAPPEngine等业务,但是其ACID事务实现只作用于单个分区).当然,FoundationDB的OCC实现也有一些限制。比如官方文档对KV和交易的大小和时长有如下限制:key不超过10K;值不超过100K;事务不超过10M(包括所有读写涉及的KV);只支持运行时间不超过5s的读写事务。这些限制在OLTP场景中是完全可以接受的。要在其Layer机制上实现OLAP场景,需要进行自适应转换。不管怎样,FoundationDB通过OCC技术实现了NoSQL+ACID,并且通过了苹果企业级生产环境的考验。NewSQL的设计者究竟应该使用悲观还是乐观的并发控制技术,现在看来是一个需要认真思考的问题。.以上是对目前NewSQL的发展趋势以及所使用的相关并发控制技术的一些思考。参考资料1,分布式并发控制的评估2,分布式数据库系统中的并发控制3,NewSQL的真正新功能是什么?4,CAP十二年后:“规则”如何改变5,foundationdbs-lesson-fast-key-value-store-不够
