本文来自大佬的投稿,作者:张剑。
摘要
我们生活在分布式计算的黄金时代。公有云平台几乎能够按需提供无限的计算和存储资源。同时,SaaS模型将企业级系统带给了无法负担成本和相关系统复杂性的用户。传统的数仓系统正在努力的适应新的环境,但是首先,它是为固定资源而设计,从而没办法利用云的弹性能力。另外,传统的数仓依赖复杂的ETL流水线和物理调优,这个是和云的半结构数据和快速解决工作问题的新形式所需要的弹性和快速不一致的。
我们决定进行根本性的重新设计。我们的任务是去建立云上的企业级数据仓库的解决方案。就是Snowflake弹性数据仓库,简称Snowflake。Snowflake是一种多租户、事务性、安全、高度可扩展的弹性系统,具备完整的SQL支持和半结构化和schema-less数据模式支持。Snowflake在亚马逊云上提供现付即用的服务。用户只需将数据导入云上,就可以立即利用他们熟悉的工具和界面进行管理和查询。从年底,Snowflake开始计划实施,到年6月,Snowflake已经可以大体可用。现在,Snowflake被越来越多的大大小小的组织用于生产。这个系统每天运行几百万次查询在几PB的数据上。
本文主要介绍Snowflake的设计、多集群共享数据的结构和Snowflake的关键特性:极致的弹性和可用性、半结构化和schema-less的数据支持、时间旅行、端到端的安全性,最后是一些经验总结和对未来工作的展望。
第1节介绍
云技术的出现标志着软件的发展将从本地服务器上的交付和运行转移到由亚马逊、谷歌或微软等平台提供商提供的共享数据中心和软件即服务的解决方案。云的共享基础设施保证了规模经济,极高的可扩展性和可用性,现收现付成本模式,以便适应不可预测的使用需求。但是,只有当软件本身能够在商品资源池(云)上弹性伸缩时,才能获得这些优势。传统的数据仓库解决方案先于云,被设计成在小型静态集群上运行,这些集群由性能良好的机器组成,这使得传统的数仓在体系结构上不适合云。
但不仅平台发生了变化,数据也发生了变化。过去的情况是,数据仓库中的大多数数据都来自组织内部的数据源事务化:事务系统、企业资源规划(ERP)应用程序、客户关系管理(CRM)应用程序等。数据的结构、数量和速率都是可预测和可知道的。但随着云技术的发展,大量且快速增长的数据来源于不那么可控或外部的来源:应用程序日志、web应用程序、移动设备、社交媒体、传感器数据(物联网)。除了不断增长的数据量,这些数据经常以schema-less、半结构化的格式存储。传统的数据仓库解决方案正在努力处理与这种新的数据。这些解决方案非常依赖于ETL管道和物理调优,但管道和物理调优是假定来自内部的可预测、不易移动且易于分类的数据。
为了应对这些缺点,部分数仓社区已经转向Hadoop或Spark等大数据平台。尽管这些工具对于数据中心规模的处理任务来说是不可或缺的,开源社区也在不断地进行重大改进,如StingerInitiative(号称让Hive提速倍),但它们仍然缺乏现有数仓的效率和功能。但最重要的是,他们需要大量的努力来推广和使用。
我们相信,有很大部分的案例和工作可以从云的经济性、弹性和服务方面获益。但传统的数据仓库技术或大数据平台都不能很好地为它们提供服务。所以我们决定专门为云构建一个全新的数据仓库系统。该系统被称为Snowflake弹性数据仓库,或叫“Snowflake”。与云数据管理领域的许多其他系统不同,Snowflake并不是基于Hadoop、PostgreSQL之类的,处理引擎和其他大部分组件都是从新开发的。
Snowflake的关键特点如下:
纯粹的SaaS服务体验。用户不需要购买机器、雇佣数据库管理员或安装软件。用户要么已经在云中拥有数据,要么上传数据。然后,他们可以使用Snowflake的图形界面或ODBC等标准化接口立即操作和查询数据。与其他数据库即服务(DBaaS)产品不同,Snowflake的服务覆盖了整个用户体验。用户无需调优,无需物理设计,无需存储整理任务。
关系型。Snowflake几乎完整的支持了ANSI的SQL和ACID的事务。大部分的用户几乎无需改动或者很小的改动就能迁移已经存在的工作内容。
半结构化。Snowflake提供了用于遍历、展平和嵌套半结构化数据的内置函数和SQL扩展,并支持JSON和Avro等流行格式。自动模式发现和列式存储使得对schema较少的半结构化数据的操作几乎与对普通关系数据的操作一样快,而无需用户额外的操作。
弹性。存储和计算资源可以独立无缝地扩展,而不影响数据可用性或并发查询的性能。
高可用。Snowflake能够容忍节点,集群,甚至全部的数据中心失败。在软件和硬件更新的时候不会下线。
持续性。Snowflake的设计具有极高的持续性,可防止意外数据丢失:克隆、下线和跨区域备份。
经济节约。Snowflake具有很高的计算效率,所有的表数据都被压缩。用户只为他们实际使用的存储和计算资源付费。
安全。所有数据包括临时文件和网络流量都是端到端加密的。没有用户数据暴露在云平台上。此外,用户能够基于角色在SQL级别执行级别细粒度的访问控制。
Snowflake现在运行在亚马逊云上面,但是未来我们也会支持其他云平台。在写这篇文档的同时,Snowflake被大大小小的组织用于生产。每天运行几百万次查询在几PB的数据上。
论文结构如下:第2节解释了Snowflake背后的关键设计:存储和计算的分离。第3节介绍了由此产生的多集群共享数据体系结构。第4节重点介绍了不同的特性:连续可用性、半结构化和schema-less数据、时间旅行和克隆以及端到端安全性。第5节讨论了相关工作。第6节总结了经验教训,并对正在进行的工作进行了展望。
第2节存储与计算
Shared-nothing结构已经成为高性能数据仓库的主流体系结构,主要原因有两个:可扩展性和商用硬件。在Shared-nothing结构中,每个查询处理器节点都有自己的本地磁盘。表是跨节点水平分区的,每个节点只负责其本地磁盘上的行。这种设计可以很好地扩展星型模式查询,因为将一个小的(广播的)维度表与一个大的(分区的)事实表连接起来只需要很少的带宽。而且,由于共享数据结构或硬件资源几乎没有争用,因此不需要昂贵的定制硬件。
在纯粹的Shared-nothing结构中,每个节点都有相同的功能并在相同的硬件上运行。这种方法的结果是很容易理解的具有良好优点的优雅的软件设计。不过,纯粹的Shared-nothing结构有一个重要的缺点:它将计算资源和存储资源紧密耦合,这在某些场景中会导致问题。
异构工作负载。虽然硬件是同样的,但工作负载通常不是。对于大容量加载(高I/O带宽,轻计算)来说,理想的系统配置不适合复杂查询(低I/O带宽,重计算),反之亦然。因此,硬件配置需要在平均利用率较低的情况下进行权衡。
节点关系变化。如果一些节点发生更改,或者是由于节点故障,或者是用户调整系统大小,则大量数据需要重新shuffle。由于相同的节点同时负责数据shuffle和查询,因此会对性能由显著的影响,从而限制了灵活性和可用性。
在线升级。虽然通过副本机制可以在一定程度上减轻节点关系变化更改的影响,但软件和硬件升级最终会影响系统中的每个节点。原则上是可能的,一个又一个节点在没有任何系统停机的情况下进行升级。但是由于所有节点都是紧密耦合的,并且都是同质的,这使得实现在线升级变得非常困难。
在内部部署环境中,通常可以容忍这些问题。工作负载可能是异构的,但是如果只有一个小的、固定的资源池可以运行,那就没有办法了。同样,节点升级很少,节点故障和系统扩容也很少。
云的情况大不相同。像亚马逊EC2这样的平台具有许多不同的节点类型。它们只需简单将数据移动到正确类型的节点,同时,节点故障更为频繁,性能可能会发生巨大变化,甚至在相同类型的节点之间也是如此。因此,节点关系的改变不是偶然,而是常态。最后,有强烈的需求需要在线升级和弹性扩展。在线升级大大缩短了软件开发周期,提高了可用性。弹性伸缩进一步提高了可用性,并允许用户将资源消耗与他们的即时需求相匹配。
因为这样那样的原因,Snowflake做了存储和计算分离。存储和计算由两个松耦合、独立可扩展的服务来处理。计算是通过Snowflake的(专有的)shared-nothing引擎提供的。存储是通过亚马逊S3提供的,其实任何类型的对象存储都可以(Azure对象存储,Google云存储)。同时,为了减少计算节点和存储节点之间的网络流量,每个计算节点在本地磁盘上缓存了一些表的数据。
存储和计算分离的另一个好处是,本地磁盘空间不用存储整个数据,这些数据可能非常大,而且大部分是冷数据(很少访问)。本地磁盘专门用于临时数据和缓存,两者都是热数据(建议使用高性能存储设备,如ssd)。因此,缓存了热数据,性能就接近甚至超过纯shared-nothing结构的性能。我们称这种新的体系结构为multi-cluster、shared-data结构。
第3节结构
Snowflake是给企业提供现成的服务。除了提供高可用性和操作性之外,企业使用就意味着高可用性。为此,Snowflake是一个面向服务的体系结构,由高度容错和独立可扩展的服务组成。这些服务通过RESTful接口进行通信,分为三个体系结构层:
数据存储。该层使用amazons3存储表数据和查询结果。
虚拟仓库。系统的“肌肉”。该层通过弹性的虚拟集群(称为虚拟仓库),执行查询。
云服务。系统的“大脑”。这一层是管理虚拟仓库、查询、事务和围绕虚拟仓库的所有元数据的服务的集合,包含数据库元信息、访问控制信息、加密密钥、使用情况统计等。
图1展示了Snowflake三个架构层及其主要组件。
图1:multi-cluster、shared-data架构
第3.1小节数据存储
AWS被选为Snowflake的初始平台主要有两个原因。首先,AWS是云平台市场上最成熟的产品。其次(与第一点相关),AWS提供了最大的潜在用户资源。
接下来的选择是使用S3还是基于HDFS或类似的技术开发我们自己的存储服务。我们花了一些时间对S3进行了测试,发现虽然它的性能可能有些不同,但它的可用性、高可用性和强大的持续性有可靠的保证。因此,我们没有开发自己的存储服务,而是决定将精力投入到虚拟仓库层的本地缓存和数据倾斜处理技术上。
与本地存储相比,S3虽然具有更高的访问延迟,每个I/O请求都有更高的CPU开销,特别是在使用HTTPS连接的情况下。但是,S3是一个对象存储,具有一个相对简单的基于HTTP的PUT/GET/DELETE接口。对象(即文件)只能完全写入。甚至不可能将数据附加到文件的末尾。文件的确切大小需要在PUT请求中前就确定。并且,S3支持对部分(范围)文件的GET请求。
这些属性对Snowflake的表文件格式和并发控制方案有很大的影响(参见第3.3.2节)。表被水平地划分成大的、不可变的文件,这些文件相当于传统数据库系统中的块或页。在每个文件中,每个属性或列的值都被分组在一起并进行了大量压缩,这是一种普遍采取的方案,在文献[2]中称为PAX或hybridcolumnar。每个表文件都有一个表头,其中包含文件中每列的偏移量,以及其他元数据。因为S3允许对部分文件执行GET请求,所以查询只需要下载文件头和它们需要的列。
Snowflake不仅在表数据上使用S3。当本地磁盘空间耗尽时,它还使用S3存储由查询(例如,大量连接)生成的临时数据,以及大型查询结果。将temp数据溢出到S3,系统可以计算任意大的查询,而不会出现内存不足或磁盘不足的错误。将查询结果存储在S3中,实现了客户端交互新方式并简化查询处理,因为它消除了对传统数据库系统中的服务端游标的需要。
元数据,例如catalog信息,由S3文件、统计信息、锁、事务日志等组成,存储在可伸缩的事务KV存储中,这也是云服务的一部分。
第3.2小节虚拟仓库
虚拟仓库层由EC2实例集群组成。每个这样的集群通过一个称为虚拟仓库(VW)的抽象呈现给用户。构成虚拟仓库的单个EC2实例称为工作节点。用户不直接与工作节点交互。事实上,用户不需要关心哪个或者多少个工作节点组成了一个虚拟仓库。虚拟仓库按照大家所熟悉的“T恤尺寸”从X-Small到XX-Large不等来标识规模大小。这样的抽象展示允许我们独立于底层云平台来发展服务和定价。
第3.2.1小节弹性与隔离
VM层是纯计算资源,可以按照需求创建、销毁或者在任意时刻改变大小。创建或者销毁一个VM对数据库状态没有任何影响。当没有查询时候,用户可以关闭所有的VM资源。这种弹性容许用户独立于数据层,按照需求动态地伸缩他们的计算资源。
每个查询只在一个VW上运行。工作节点不会在VW之间共享,从而使查询具有强大性能隔离。(也就是说,我们将工作节点共享视为未来工作的一个重要领域,因为对于性能隔离不太重要的用例,它将实现更高的利用率和更低的成本。)
提交新查询时,相应VW中的每个worker节点(或者如果优化器检测到一个小查询,则为节点的子集)生成一个新的worker进程。每个工作进程只在其查询时间内工作。worker进程本身,即使有update语句,不会对外部可见造成影响,因为表文件是不可变的,参见第3.3.2节。因此,worker故障很容易被控制,并且通过重试来解决。不过,Snowflake目前不支持部分重试,因此非常大的、长时间运行的查询是一个值得