介绍
传统的关系型数据库适用于垂直伸缩(scale-up)的架构。换句话说,为了处理更多的负载,你需要换个更强大的计算机。在几年前,这意味着要想支持水平伸缩(scale-out)的架构,大家就得放弃SQL,或者采用分区、Active-Passive复制等技巧。在灵活、富有逻辑的数据库上实现真正的ACID编程模型是不太可能的。正是这种局势引发了NewSQL运动,NuoDB的出现也是为了解决这个问题。
NuoDB是针对云伸缩设计的关系型数据库。怎么理解呢?NuoDB是一种真正的SQL服务:它拥有ACID事务的所有属性,支持标准的SQL语言,具备真正的关系型逻辑。而且从一开始,NuoDB的设计就能让它以云服务伸缩的方式进行伸缩。
这里不再对“云伸缩”进行定义。如果你真的感兴趣,可以到我们的技术博客上了解什么是云伸缩,文章里有详细的定义。简单来说,就是你需要一个水平伸缩的模型,不过我觉得它还应该是敏捷、易用、可自动化、安全、高可用的。本文就是从这个观点出发的。
需要注意的是,NuoDB“只是”个软件。这意味着无论是在笔记本电脑上,还是在私有云抑或公有云上,NuoDB都运行在Linux、Mac、Windows或Solaris上。你可以在Amazon Web Services或Google Compute Engine里使用NuoDB,或是把它和OpenStack集成起来,也可以在笔记本电脑上作为本地Windows服务运行。NuoDB很灵活,你可以随便测试、开发,然后以你自己的方式部署到任意地方。
本文将介绍NuoDB是什么,怎样的架构能让它应对现今的一些挑战,以及它能帮你解决什么问题。看完本文,你就能了解NuoDB的关键概念和架构的不同之处了。你也能理解一些实际部署和管理的功能,对自己的NuoDB数据库进行伸缩。
三层架构
了解NuoDB最简单的方式就是了解它的三层架构。NuoDB包括管理层、事务层和存储层。我们后面再介绍管理层,先看看事务层和存储层。
要想让关系型系统可伸缩,把事务和存储分割开是关键之所在。传统的SQL数据库都会对硬盘上的数据表示(页)和内存里的B树结构进行同步。这种紧耦合是有效的,但对IOPS(每秒I/O操作次数)的影响非常大,因此很难水平伸缩。把这些角色分离开的架构可以水平伸缩,几乎不会影响磁盘吞吐量等数据。
NuoDB的持久化和事务处理是完全独立的两个任务,这意味着你可以对这些层分别伸缩、分别处理故障。对事务吞吐量进行水平伸缩?不用增加磁盘就可以做到。想拥有独立的归档,防止数据中心出现故障?达到目标的同时也不会影响事务性能。这种分离不仅有利于系统的伸缩,也更利于随需伸缩、根据你的需求进行调配。
事务层负责原子性、一致性和隔离性,但并不关心持久性。这也说明事务层位于内存中,它运行速度快,任何内容都可以失败,在任何时候关闭都不会丢失数据或一致性。事务层也是个缓存层(特别是能随需缓存,我们一会儿介绍),你不需要在NuoDB数据库之上添加其他的缓存逻辑。
显而易见,存储层负责ACID中的D(持久性)。存储层始终处于活跃状态,并和所有数据保持一致。它负责在提交的时候持久化数据,事务在缓存中命中失败的情况下访问数据。
需要注意的是,NuoDB里的“提交”是可调节的。你可以在某种程度上牺牲性能和高可用性,因为它们处于不同的层。要理解调节提交协议的做法和原因,我需要解释一下这些层究竟是什么样的。
对等协调
这两个数据库层由多个进程组成,这些进程可以跨任意数量的主机运行。每个单独可执行的进程都以事务引擎(Transaction Engine,TE)或存储管理器(Storage Manager,SM)两种模式的其中之一运行。所有的进程都是对等的,没有单独的协调器或故障点,也没有主机特定的配置。默认情况下,所有对等的进程都会通过加密的会话互相认证和通讯。
每个TE都负责接受SQL客户端的连接,并处理查询。缓存保存在TE的进程空间里。SM和TE通过简单的对等协调协议互相通讯。当TE在本地缓存命中失败的时候,它可以从任意对等进程里获取所需的对象,这通常意味着,如果有另一个TE的缓存里有这个对象,就去那个TE里取,这比SM从持久存储里查询数据要快多了。
这个简单、灵活的进程模型简化了启动、水平伸缩和迁移。举例来说,假设你想要一个尽可能简单的NuoDB数据库。你在同一台主机上启动了单独的TE和SM。这时你就有了一个运行的、完全ACID的数据库,但它们都在同一台主机上。你可以在笔记本电脑上这样测试,但这么做就不太适用于真正的部署环境了。
接下来你可以在第二台主机上安装软件,发消息让它启动一个新的TE。新的TE会和已有的进程互相验证,把一些根元素加载到自己的缓存里,然后报告说自己已经做好了准备、能处理事务负载了。从发消息到TE准备好开始工作,整个过程花费的时间通常都不会超过一百毫秒。在两个独立的主机上运行TE就可以让数据库的事务吞吐量翻一番,也能增加故障的恢复能力。
美中不足的是我们只处理了持久性的一个方面。接下来,你可以搭建第三台主机,发送消息让它启动第二个SM。第二个SM会自动和运行的系统同步,准备好之后就可以积极参与数据库的处理了。至此,数据库持久性的另一个方面也就处理好了。一样很简单。
最后,让我们看看如何在不同的主机上搭建第一个TE和SM。你可以猜到,联机第四台主机,在这台新主机上启动一个TE或者一个SM,当它准备好之后关闭原先的TE或SM(无论你在新主机上启动的是什么)。你完成的是数据库组件的实时迁移,不会损失可用性。因为整个服务没有关闭过。这也配置出一个完全冗余的数据库,因为任何主机都可能失败,但你仍然有一份完整的数据归档,并能进行事务处理。
所有的工作都完成得轻松、迅速,因为NuoDB建立在一个基于进程、对等的简单模型之上。此外,也因为有简单的随需缓存Schema,以及真正被缓存和分享的数据格式。但数据格式并不是真正的SQL结构。我们称它为原子(Atom)。