1.3 NoSQL的瓶颈和SQL数据库的回归
关系型数据库虽然很好地满足了结构化数据库的分析需求,但是对于存储非结构化的数据,则一直是业界面临的难题。为了解决非结构化数据的存储问题,各种NoSQL数据库纷纷涌现,并且逐渐赋能给传统数据库,大幅提升了SQL数据库的能力。
1.3.1 NoSQL产品的发展
NoSQL数据库最初是指不使用SQL标准的数据库,现在泛指非关系型数据库。NoSQL一词最早出现于1998年,是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的数据库。该数据库使用文本文件存储数据,每个元组由制表键分隔的字段组成。使用Shell脚本访问数据,虽然不支持SQL接口,但是仍然是关系型数据库。
现在NoSQL被普遍理解为“Not Only SQL”,意为不仅仅是SQL。NoSQL和传统的关系型数据库在很多场景下是相辅相成的,谁也不能完全替代谁。一般认为,NoSQL数据库是SQL数据库的一种补充,并不能完全替代关系型数据库。
2010年前后,随着互联网的飞速发展,快速增长的数据量给年轻的互联网公司带来了巨大的技术挑战:现有的数据处理技术无法适应数据量的快速增长。传统企业(如银行)也有大量数据,因为其核心业务是交易,所以可以通过控制数据量(特别是历史数据量),使现有的数据处理技术满足其业务需求。可是对于互联网公司,网页和手机端用户飞速增长,用户数据是其核心资产,只能努力前进,解决其他人还未遇到的难题。
虽然自20世纪80年代,学术界和企业就开始对分布式数据库进行研究和开发,但是当时还没有可以很好支持集群的商用事务型关系数据库。Oracle RAC和微软的SQL Server虽然支持集群,但是仍然基于共享磁盘,扩展能力有限。于是,互联网巨头不得不考虑其他存储方案。这些研究和技术为NoSQL的发展奠定了基础。许多知名的NoSQL产品也是从这一时期开始研发或者发布的,包括CouchDB(2005)、MongoDB(2007)、HyperTable(2008)、Redis(2009)、ElasticSearch(2010)等。图1-5所示是NoSQL具有代表性的产品。
图1-5 NoSQL的主要产品
NoSQL数据库的出现,解决了数据处理领域自关系模型出现以来就存在的对象和关系模型不匹配的问题。很多NoSQL数据库不再需要将数据转换成扁平的二维数据结构,而是可以直接以对象或者序列化字符串的形式进行存储。例如,文档数据库使用支持嵌套的JSON格式存储数据,而键值对数据库则忽略数据的内部格式,把内存中的数据序列化成二进制字符串存储,读取的时候再进行反序列化。
1.3.2 NoSQL的共性
NoSQL产品众多,出现的时机和原因各不相同,应用场景也多种多样,这些产品之间存在如下共性。
1)NoSQL数据库(开始时)不提供SQL接口,某些NoSQL数据库虽然提供了类SQL接口,但是都没有实现SQL标准的能力。
2)集群基因。NoSQL数据库大多具备良好的集群管理能力,有的NoSQL最初就是为了集群而设计的,具备很好的线性扩展能力和高可用性。
3)追求高性能和高吞吐量。由于NoSQL数据库大多以追求高性能、高吞吐量和高可用性为目标,因此放弃了某些关系型数据库的特性。
4)NoSQL数据库的数据模型都是非关系型的,常见的数据模型有键值、列族、文档类型和图类型,如表1-1所示。
表1-1 NoSQL数据模型介绍
5)由于NoSQL数据库只使用灵活的模式来管理数据,因此NoSQL数据库不需要事先设计完整的模式即可操作数据,给编程人员提供了灵活性和便利性。
6)大多数NoSQL数据库以不同的协议开放源码。
NoSQL的产品还在继续演进,其中一个趋势就是支持更多关系型数据库的优秀特征,如SQL标准。目前Apache社区有多个SQL-on-Hadoop项目,包括HAWQ、Presto、Impala、Kylin、Phoenix(SQL On HBase)等。此外,Kafka也开始提供SQL接口KSQL,Flink和Spark更是把SQL放在优先发展的位置。
传统的关系型数据库也开始支持越来越多的NoSQL特性,例如PostgreSQL 9.2开始支持JSON,MySQL从5.7版开始支持相对完整的JSON和相关函数,Oracle 12C引入了对JSON的支持等。
1.3.3 SQL数据库的回归
新一轮的数据库开发风潮展现出了向SQL回归的趋势,只不过这种趋势并非体现在更大、更好的硬件上(甚至不是在分片的架构上)运行传统的关系型数据库,而是通过NewSQL解决方案来实现数据库性能的提升。
NewSQL是各种新的可扩展/高性能数据库的简称,这类数据库不仅具有NoSQL对海量数据的存储管理能力,还保持了传统数据库支持ACID和SQL的特性。NewSQL数据库针对OLTP(读–写)工作负载,提供和NoSQL系统相同的扩展性能,且仍然保持ACID和SQL等特性,其中被广泛使用的一个解决方案就是数据分片。
Google(NoSQL最初的支持者之一)构建了分布式关系型数据库F1,将BigTable的高可用性和可伸缩性与SQL的“一致性和可用性”结合起来。Google在白皮书F1: A Distributed SQL Database That Scales中是这样介绍F1的。
这是由Google构建的一个容错、分布式的OLTP与OLAP数据库,作为新的存储系统,用于Google的AdWords系统。设计它的目标旨在替换分片的MySQL实现,因为后者已经无法满足日益增长的可伸缩性与可靠性需求了。
在F1之后,Google又研发出了更强大的数据库Spanner。Spanner是Google的全球级分布式数据库。Spanner的扩展性达到了令人咋舌的全球级,可以扩展到数百万台服务器、数以百计的数据中心、上万亿行记录。除了夸张的扩展性之外,Spanner还能通过同步复制和多版本满足外部一致性,可用性也是很好的。Spanner冲破了CAP的枷锁,在三者之间达到完美平衡。
其后,各种模仿Spanner架构的数据库纷纷涌现,包括TiDB、Doris等都在一定程度上借鉴了Spanner的设计。
NewSQL提供了与NoSQL相同的可扩展性,而且仍基于关系模型,并保留了极其成熟的SQL作为查询语言,保证了ACID事务特性。简单来讲,NewSQL就是在传统的关系型数据库上集成了NoSQL强大的可扩展性。传统的SQL架构设计基因中是没有分布式的,而NewSQL生于云时代,天生就是分布式架构。表1-2针对传统数据库(Old SQL)、NoSQL、NewSQL数据库之间的差异做了对比。
表1-2 Old SQL、NoSQL、NewSQL三者对比
NewSQL的主要特性如下。
1)分布式架构。NewSQL系统是全新的数据库平台,采取分布式架构,每个节点拥有一个数据子集。SQL查询语句被分成查询片段发送给自己所在的数据节点上执行。这些数据库可以通过添加额外的节点进行线性扩展。
2)SQL引擎支持。高度优化的SQL存储引擎,支持复杂查询和大数据分析。
3)透明分片。NewSQL数据库支持弹性伸缩,扩容缩容对于业务层完全透明。
4)自动容灾。由于NewSQL数据库支持的集群规模大,因此必须支持自动容灾以满足高可用要求。目前只有主备自动切换和失败自动重启两种模式。