数据的积累是当今各行各业巨头的企业财富,数据库则是数据存储的重要途径。在大数据和微服务大行其道的今天,传统的关系型数据库也将迎来变革。云原生的数据库架构受到越来越多的关注,所以我想和大家一起来聊聊云原生数据架构。本文作为上篇,会先对当下各类数据库发展现状进行分析。
一、关系型数据库尚能饭否?
关系型数据库出现至今的几十年时间里,一直是数据库领域的佼佼者。下图是全球较为权威的DB-Engines的统计排名,排名主要依据Google以及Bing搜索引擎的关键字搜索数量、从业人数信息、职位搜索量、Stack Overflow上提问关注数量等:
DB-Engines 2018年6月公布的数据库排名
截止至2018年6月,排名前6位的数据库,仅有排名第5的MongoDB是文档型数据库,其余全部是关系型数据库,且前3位所占有的比重远远领先于其后的其他数据库。
1、优势
关系型数据库在经过大数据、NoSQL以及NewSQL等技术革新的轮番轰炸之后依然坚挺,与其固有的优势密不可分。它的优势主要体现在对开发人员、运维人员以及系统本身这3个方面的影响。
开发优势
对于开发人员来说,关系型数据库的首要优势是面向SQL。
SQL是关系型数据库的结构化查询语言,虽然不同的关系型数据库有不同的SQL方言,但基于ANSI标准的SQL是大部分关系型数据库都支持的。且SQL是面向数据库的访问语言,可以非常方便的对数据库进行增、删、改、查以及授权和管理。SQL的查询灵活度非常高,可以十分便捷的在联机事务处理(OLTP)与联机分析处理(OLAP)之间转换。
此外,SQL是应用开发工程师所必须掌握的一门编程语言,流行度非常广泛,招聘到一个完全不会写SQL的应用开发程序员的概率非常小。因此,SQL极大降低了开发人员招聘的成本。
除了SQL语言本身,各种开发语言对关系型数据库的支持也十分完善。以Java举例:JDBC是Java语言访问数据库的标准接口,各个关系型数据库厂商均提供了实现JDBC接口的驱动程序。使用Java语言开发的工程师无需感知不同关系型数据库间的差异,只要根据JDBC接口编程即可。
由于面向关系的数据库存储与面向对象的Java程序不易一一对应,产生了很多对象关系映射(ORM)框架用于简化关系对象模型的阻抗不匹配,如JPA及其官方实现Hibernate、MyBatis、Jooq等,进一步简化了应用工程师的日常开发工作。ORM框架大多是采用JDBC封装,对各个关系型数据库的兼容性非常高。
运维优势
关系型数据库由于存在时间长久,针对每一种常见的关系型数据库,都能较容易地招聘到相应的数据库管理员(DBA),以保证关系型数据库的稳定性、安全性、完整性以及性能,同时保证监控和分析关系型数据库的系统瓶颈以及设计的合理性。
成熟的关系型数据库都有自己完善的生态圈,用于保证高可用、数据备份、性能监测分析等成熟的配套工具。规模较大的企业及重要业务系统一般都需要专门的DBA进行运维工作。
系统优势
只有时间才是检验技术的成熟与稳定的标准。关系型数据库经历了几十年的考验,已经有超大规模的使用,其存储引擎已经十分成熟。基于MVCC的数据库引擎在性能和正确性上做到了很好的平衡,并且通过B+tree索引大幅提升了查询的效率。面对数据这样的关键节点,谨慎的选用关系型数据库是架构师们的首选方案。
基于ACID的事务是关系型数据库带给应用系统的又一强力保障。ACID指数据库事务能够正确执行的四个基本要素的首字母缩写。它包括原子性、一致性、隔离性和持久性。只有支持事务的数据库才能最大限度的保证数据的正确性和完整性:
● 原子性(Atomicity)。 位于同一事务中的所有操作,要么全部完成(提交),要么全部不完成(回滚),不能停滞在某个中间环节。如果事务在执行过程中发生错误,数据将会恢复到事务开始前的状态。● 一致性(Consistency)。 非只读的事务应封装数据库的状态从一个一致状态转变为另一个一致状态。一致状态是指数据库中的数据应满足完整性约束,并且事务的中间状态不应在事务之外被感知。
● 隔离性(Isolation)。 多事务并发执行时,不应相互影响其他事务,就像只有这一个操作在并行的被数据库执行一样。
● 持久性(Durability)。 事务完成后,该事务对数据库的所有更改将持久的保存在数据库中。
在编程中使用事务也并非难事,各类如Spring之类的开发框架已经在面向切面(AOP)层面将其做的十分简单和优雅了。
2、不足
关系型数据库的性能和访问承载能力,在面向单一数据节点的企业级应用时代是无可挑剔的。但在访问量和数据量急剧膨胀的今天,关系型数据库已经很难再像以前那样成为如此巨大规模系统的底层支撑,甚至成为了应用系统的瓶颈所在。
关系型数据库主要有以下三处不足:
● 单节点并发访问量受限。 在服务任意扩容和拆分的同时,由于数据库中存储的数据是有状态的,因此很难像服务一样任意拆分和扩容。单一的数据库节点承载大量的服务节点的查询和更新请求,这并非一个对等的架构部署模式。● 单节点数据承载量受限。 单一数据库节点对数据的承载能力是有限的。数据量越大,用于查询数据所创建的索引的深度就越深。索引深度决定IO访问的次数,索引深度越深,查找越慢。
● 分布式事务性能衰退严重。 将数据库拆分之后,需要使用分布式事务代替本地事务。基于XA的分布式事务采用两阶段提交,在准备阶段即锁定资源,直至整个事务结束。在系统并发度增加时,性能会急剧衰退。
综上所述,关系型数据库的不足,归根结底是设计初衷导致的。它并非分布式的产物,对分布式系统的天生不友好,导致它很难适应互联网的架构模型。面对可以随时弹性扩容的无状态服务,关系型数据库已经略显笨重。
二、未达预期的NoSQL
随着关系型数据库的不足之处暴露得越来越明显,NoSQL的出现成为了有益补充。不过NoSQL并非为了取代关系型数据库,而是指Not Only SQL,提供了在SQL之外的另一种选择。
NoSQL有很多种分类,大致包括键值数据库、文档数据库、列族数据库以及图数据库等,用于解决各异的场景。
1、键值数据库
键值数据库的代表是Redis。它在很多场景下都作为缓存使用,但Redis也同样提供落盘功能。面对通过主键查询的场景,Redis的效率非常高,但对于内容的查询,则无能为力。
Redis提供了集群的能力,可以将数据分散至不同的节点,有效的分散了单一节点的访问量瓶颈。如果在内存中无法加载Redis的全部数据而导致落盘,Redis的性能将有所下降,因此在数据量较大的情况下,将Redis的数据根据主键进行分片是不错的解决方案。
Redis通过MULTI、EXEC、DISCARD以及WATCH命令提供事务功能。Redis事务提供一次性的、按顺序的、且不可中断的执行命令的机制。但即使事务中的部分命令执行失败也无法回滚,因此Redis的事务与数据库领域中的事务并非是一一对应的关系。
2、文档数据库
文档数据库的代表是MongoDB。文档模型与面向对象的数据表达方式更加接近,它拥有自由度极高的Schema模型,可以方便的与JSON数据映射。
文档数据库的设计理念与关系型数据库完全不同,它没有静态定义的表结构,而是可以灵活在文档中随意增减属性以及嵌入子文档和数组。因此面向文档数据库设计应用程序,应是以对象本身为主,而不是优先考虑数据库表结构如何定义。这种设计使得开发工程师在修改程序逻辑时十分方便,无需考虑数据库表结构的变更导致的锁表等问题。
MongoDB的查询维度十分灵活,可以根据需要查找的内容建立索引以提升效率。此外,MongoDB在分布式的表现上也远强于关系型数据库,它可以将数据自动分片,并且能够透明化分片之间的负载均衡和失效转移。它还内置GridFS,支持大数据集的存储。
但是MongoDB无法像关系型数据库那样支持ACID事务,而是使用最终一致性事务,因此不建议将MongoDB用于非常关键的如订单、交易、账务等业务系统,而是用于论坛等对数据事务要求级别低一些的业务系统中。
3、列族数据库
列族数据库的代表是位于Hadoop大数据体系中的HBase。它是专门用于处理海量数据的分布式数据库。
HBase通过行主键和列族来确定一条记录,每个列族中的属性是不固定的,这一点与文档数据库类似。HBase同样能够自动切分数据,使得数据存储自动具有水平扩展的能力。HBase的数据存储在HDFS这样的分布式文件系统中,对于海量数据的支持是最好的。
HBase采用LSM Tree (Log-Structured Merge-Tree)。它将对数据的更改放在内存中,达到指定的阈值后再将更改归并后批量写入磁盘,将单个写操作转换为批量写操作,幅大提升写入速度。但在读取数据时,HBase则需要分别查找内存和磁盘中的数据,对性能产生一定影响。因此Hbase更加适合写多读少的应用。另外,Hbase同样不支持ACID事务,并且只能通过行键来查询数据。
图数据库是用于处理图关系的数据库,用于特殊场景,因此这里便不再介绍。
总的来说,NoSQL数据库的种类繁多,分别适合用于不同的场景。我们通过下表简单对比一下前文介绍的三种类型NoSQL数据库:
虽然各种NoSQL的使用场景有很大差别,但它们大多很好地支持了分布式数据库所需要的分片和数据迁移等功能,在海量数据和大并发的支持方面,强于传统的关系型数据库。
NoSQL数据库虽然可以提供良好的扩展性和灵活性,但它们的不足却是十分明显的:
不同的NoSQL数据库都有自己的查询语言,相比于SQL,制定应用程序标准接口难上加难。并且NoSQL也无法提供ACID的事务的操作,因此很多企业无法放心的将NoSQL应用于核心业务系统中。
正如NoSQL的定义所说,它们仅仅是基于SQL的关系型数据库的有益补充,而非关系型数据库的替代者。
三、冉冉升起的NewSQL
由于SQL和ACID事务实在太过于深入人心,而分布式数据库的需求又前所未有的旺盛,因此另一种数据库,NewSQL就应运而生了。
NewSQL是对各种具有分布式可扩展的数据库的简称,它继承了NoSQL对海量数据的处理能力,同时还保持了传统关系型数据库对SQL和ACID事务的支持。NewSQL的关注重点在于混合式(Hybrid)数据库,它们更倾向于找寻不再区分OLTP与OLAP查询的多模式数据库架设方案。
在2016年,Andrew Pavlo与Matthew Aslett发布了一篇论文:《What’s Really New with NewSQL?》,在文章他们将NewSQL划分为3个大类:新架构(New Architecture)、透明化分片中间件(Transparent Sharding Middleware)和云数据库(Database-as-a-Service)。
论文参考链接:
https://db.cs.cmu.edu/papers/2016/pavlo-newsql-sigmodrec2016.pdf
1、新架构
这一类NewSQL是全新的面向分布式的架构设计的数据库系统。
它们一般使用share-nothing的架构,支持多节点并发控制、高度容错的自动化数据副本复制、流控以及分布式查询处理等特征。
由于它们是天生面向分布式多节点而设计的系统,因此对于查询优化和节点间的通信协议等处理的更加出色。举例来说,NewSQL的数据库的多数据节点间可以直接通信,而无需依赖中心节点。
除了Google的Spanner,其他类似的数据库都需要自行管理数据在磁盘和内存中的存储与分布。这意味着该类型的数据库系统负责将查询发送到数据节点,而不是将数据复制到请求节点以减少网络传输。
由于采用了全新的架构设计和存储引擎,并未充分经过时间验证,所以企业的技术选型者们格外的谨慎。同时,又因为有运维新一代NewSQL经验的工程师数量也较少,所以相比于关系型数据库,当前的使用者还相对小众。很多企业目前都会尝试跟进全新架构的NewSQL,但尚未迁移核心系统。
最典型的新架构类型的产品是Google的Spanner以及国产数据库TiDB。
2、透明化分片中间件
透明化分片数据库中间件允许应用将数据分片写入多数据节点,但数据节点仍然采用面向单数据节点的关系型数据库。透明化分片中间件使用中心组件用来路由数据操作请求、协调事务、管理数据分布及复制数据副本。整个集群对外是一个逻辑实例,应用往往无需改动即可平滑使用。
透明化分片数据库中间件的核心优势是兼容性,它可以成本较低地在系统现有的单机关系型数据库与分片中间件之间切换,而无需开发者做任何代码上的改动。它们旨在充分合理地在分布式的场景下利用传统关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。
这样既可利用传统关系型数据库的稳定性和兼容性,又可在其基础之上增加分布式场景的处理。在原有基础上增量而非颠覆是这类NewSQL产品的核心理念。由于开源及流行度的原因,基于MySQL协议的数据库中间件是最为普遍的。
由于基于单数据节点的传统关系型数据库是面向磁盘设计的,对于基于内存的存储管理及并发控制,不如重新设计的面向分布式的新架构NewSQL那样,能够更加高效的利用。另外,SQL解析、查询计划优化等工作在中间件和数据库中将会重复工作,使得整体运行效率略逊于全新设计的NewSQL。
在国内的大中型互联网公司中,这类NewSQL十分流行,每个公司都基本有自己的数据库中间件。但由于和公司内部的业务系统耦合较重,成熟的开源产品较少,我们之后将讨论到的Sharding-Sphere生态圈中的Sharding-Proxy即属于这类NewSQL产品。
3、云数据库
最后一种类型的NewSQL,是由云计算公司所提供的云数据库产品。云数据库的使用方无需自行维护数据库及其硬件,而是全部数据托管至云平台所提供的服务。使用方通过数据库的URL连接至云端数据库,并通过API或操作仪表盘去操作和监控系统即可。
云数据库使用成本最低,工程师完全无需考虑数据库的任何细节问题。对中小型公司来说是理想的解决方案,但对于拥有巨大数据体量的公司来说,采用前两种NewSQL的开源或自研方案更加合适。
亚马逊所提供的Aurora即为这类NewSQL的典型应用。
总的来看,NewSQL虽然尚未成熟,但确是面向未来的正确尝试。三种类型NewSQL数据库的关注点各不相同,新架构类型数据库的关注点是彻底的革新;透明化分片数据库中间件的关注点是增量;而云数据库则更加关注屏蔽用户使用细节。
虽然不同类型各有千秋,但它们的核心功能是类似的。无论哪一种NewSQL,混合式(Hybrid)数据库将是未来的发展方向,当OLTP与OLAP不再区分,将会极大地降低开发成本。
原文发布时间为:2018-10-30
本文作者:张亮