Snowflake 弹性数据仓库
摘要
我们生活在分布式计算的黄金时代。 公有云平台现在可以按需提供几乎无限的计算和存储资源。 同时,软件即服务(SaaS)模型为那些以前由于成本和复杂性而无法负担的用户带来了企业级的系统。 而传统的数据仓库系统正在努力适应这种新环境。 一方面,它们是为固定资源而设计的,因此无法利用云的弹性。 另一方面,它们对复杂的ETL管道和物理调整的依赖性与云上的新型半结构化的数据和快速增加的工作负载的灵活性和新鲜度要求不匹配。
我们认为必须进行根本的重新设计。我们的任务是为云构建企业就绪的数据仓库解决方案。结果就是Snowflake ElasticData Warehouse,或者简称为“ Snowflake”。 Snowflake是一个多租户,事务性,安全,高度可扩展的弹性系统,具有完整的SQL支持和针对半结构化和无模式数据的内置扩展。该系统在Amazon云中提供按需付费的服务。用户将其数据上传到云中,并可以使用熟悉的工具和界面立即进行管理和查询。Snowflake始于2012年末,从2015年6月开始普遍商用。如今,Snowflake被越来越多的小型和大型组织在生产环境中使用。该系统每天在数PB规模的数据上运行数百万个查询。在本文中,我们描述了Snowflake的设计及其新颖的多集群共享数据的架构。本文重点介绍了Snowflake的一些关键特性:极高的弹性和可用性,半结构化和无模式的数据,时间旅行和端到端的安全性。它总结了吸取到的经验教训和对正在进行的工作的展望。
1.介绍
云的出现标志着从本地服务器上的软件交付和执行转向由亚马逊、谷歌或微软等平台提供商用托管的共享数据中心和SaaS化解决方案的转变。云所提供的共享的架构提供了规模经济递增、极高的可扩展性和可用性以及按需付费的费用模型,可适应不可预测的使用需求。但是,只有在软件自身能够在作为云的商用资源池中灵活地扩展时,才能获得这些优势。传统的数据仓库解决方案早于云,它们被设计为在行为良好的小型静态集群上运行,这使其在架构上不太合适。
但不仅平台发生了变化。数据也发生了变化。过去的情况是,数据仓库中的大多数数据来自组织内的来源:事务处理系统,企业资源计划(ERP)应用程序,客户关系管理(CRM)应用程序等。数据的结构,数量和速率都是相当可预测的。但是有了云,来自更不可控的以及外部数据源的共享数据:应用程序日志,Web应用程序,移动设备,社交媒体,传感器数据(物联网)便有了一个显著且快速的增长。除了不断增长的数据外,这些数据还经常以无模式,半结构化格式到达[3]。传统的数据仓库解决方案正在努力处理这些新数据。这些解决方案依赖于深层的ETL管道和物理调优,这些调整从根本上假设了来自内部大量数据的可预测、缓慢移动和轻松分类。
为了弥补这些缺陷,数据仓库的一部分社区已经转向“大数据”平台,例如Hadoop或Spark [8,11]。 尽管这些工具对于数据中心规模的处理任务是必不可少的,并且开源社区仍在不断进行重大改进,例如Stinger Initiative [48],但它们仍然缺乏效率和被认可的数据仓库技术的功能集。 但最重要的是,它们需要大量的工程工作才能推出和使用[16]。
我们认为,有大量的用例和工作负载可从云的经济性,弹性和服务方面受益,但传统数据仓库技术或大数据平台都无法很好地利用它们。 因此,我们决定为云构建一个全新的数据仓库系统。 该系统称为Snowflake弹性数据仓库或“ Snowflake”。 与云数据管理领域中的许多其他系统相比,Snowflake不基于Hadoop,PostgreSQL等。 处理引擎和大多数其他零件都是从头开始开发的。
Snowflake的主要功能如下。
纯粹的软件即服务(SaaS)化体验。用户不需要购买机器,雇用数据库管理员或安装软件。 用户可能已经将其数据存储在云中,或者将其上传(或邮寄[14])。然后,他们可以使用Snowflake的图形界面或ODBC等标准化接口立即处理和查询数据。与其他数据库即服务(DBaaS)产品相比,Snowflake的服务范围延伸到了整个用户体验。 用户没有调节旋钮,没有物理设计,也没有存储整理任务。
关系型。Snowflake对ANSI SQL和ACID事务提供全面的支持。 大多数用户几乎不需要更改就可以迁移现有工作负载。
半结构化 Snowflake提供内置函数和SQL扩展,用于遍历,展平和嵌套半结构化数据,并支持JSON和Avro等流行格式。自动模式发现和列式存储使对无模式,半结构化数据的操作几乎与普通关系型数据一样快,而无需用户花费任何精力。
弹性 存储和计算资源可以独立且无缝地扩展,而不会影响数据可用性或并发查询的性能。
高度可用 Snowflake可以容忍节点、群集甚至整个数据中心的故障。在软件或硬件升级期间没有停机时间。
持久性 Snowflake具有极高的持久性,并具有防止意外数据丢失的额外保护措施:克隆,伪删除和跨区域备份。
成本效益 Snowflake具有很高的计算效率,可压缩所有表数据。用户只为存储和计算实际使用的资源付费。
安全 所有数据(包括临时文件和网络流量)均端到端加密。从来没有用户数据暴露给云平台。此外,基于角色的访问控制使用户能够在SQL级别上执行细粒度的访问控制。
Snowflake当前在Amazon云(AWS)上运行,但是我们将来可能会将其移植到其他云平台上。 在撰写本文时,Snowflake每天在数PB级别的数据上执行数百万个查询,为来自不同领域的数量众多的小型和大型组织提供服务。
大纲
本文的结构如下。 第2节介绍了Snowflake背后的关键设计选择:存储和计算的分离。 第3节介绍了最终的多集群共享数据架构。 第4节重点介绍了差异化功能:连续可用性,半结构化和无模式数据,时间旅行和克隆以及端到端安全性。 第五部分讨论了相关的工作。 第六部分在总结论文时分享了经验教训并展望了正在进行的工作。
2.存储与计算
无共享(Shared-nothing)架构已成为高性能数据仓库中的主流系统架构,其主要原因有两个:可伸缩性和商用硬件。在无共享架构中,每个查询处理器节点都有自己的本地磁盘。 表是跨节点水平分区的,每个节点仅负责其本地磁盘上的行。 对于星型模型,此设计可以很好地扩展,因为将较小的(广播的)维表与较大的(分区的)事实表结合在一起所需的带宽很小。 而且,由于对共享数据结构或硬件资源的争用很少,因此无需昂贵的定制硬件[25]。
在纯粹的非共享架构中,每个节点都具有相同的职责,并在相同的硬件上运行。 这种方案造就了易于推理的精美软件,并具有不错的辅助效果。 纯粹的非共享架构却有一个重要的缺点:它将计算资源和存储资源紧密耦合在一起,这在某些情况下会导致问题。
异质的工作负载 虽然硬件是同质的,但是工作负载通常不是。最适合批量加载(高I / O带宽,轻量级计算)的系统配置不适合复杂查询(低I / O带宽,重度计算),反之亦然,因此硬件配置需要在平均利用率较低的情况下进行权衡。
成员资格更改 如果节点集变更,要么由于节点故障要么由于用户选择调整系统大小而造成的;大量的数据需要重新shuffle。由于完全相同的节点负责数据shuffle和查询处理,因此可以观察到明显的性能影响,从而限制了弹性和可用性。
在线升级 虽然可以通过复制在某种程度上减轻小型成员身份更改的影响,但是软件和硬件升级最终会影响系统中的每个节点。原则上可以实现在线升级,以便一个接一个的节点升级而没有任何系统停机,但是由于所有事物都紧紧地耦合在一起并且期望是同质的,因此这变得非常困难。
在本地环境中,通常可以容忍这些问题。 工作负载可能是异构的,但是如果只有一小部分固定的节点池要运行,那么几乎没有人会触碰到这些:节点升级很少,节点故障和系统调整大小也很少。
云中的情况非常不同。 诸如Amazon EC2之类的平台具有许多不同的节点类型[4]。 充分利用它们的好处仅仅是将数据带到正确类型的节点上。 同时,即使在相同类型的节点之间,节点故障也更加频繁,并且性能可能会发生巨大变化[45]。 因此,成员资格变更也不例外,这是正常现象。 最后,有很强的动力去实现在线升级和弹性扩展。 在线升级大大缩短了软件开发周期并提高了可用性。 弹性扩展进一步提高了可用性,并允许用户将资源消耗与他们的瞬时需求相匹配。
由于这些种种原因,Snowflake将存储和计算进行了分离。这两个方面由两个松耦合、独立可伸缩的服务处理。计算是通过Snowflake的(专有)无共享引擎提供的。尽管原则上任何类型的Blob存储都能适配(Azure BlobStorage [18、36],Google Cloud Storage [20]),但存储是通过Amazon S3 [5]提供服务的。为了减少计算节点和存储节点之间的网络流量,每个计算节点都会在本地磁盘上缓存一些表数据。
该解决方案的另一个好处是,本地磁盘空间不花在复制整个基础数据上时间,因为整个基础数据可能很大,而且大多只存储冷数据(很少访问)。取而代之的是本地磁盘仅用于临时数据和高速缓存,这两者都存储热数据(建议使用高性能存储设备,例如SSD)。因此,一旦高速缓存变暖,性能便接近甚至超过了纯无共享系统的性能。我们称这种新颖的架构为多集群共享数据架构。
3. 架构
Snowflake旨在提供企业级服务。除了提供高度的可用性和互操作性之外,企业级就绪还意味着高可用性。为此,Snowflake是一种面向服务的体系结构,由高度容错的和可独立扩展的服务组成。这些服务通过RESTful接口进行通信,分为三层架构:
数据存储 该层使用Amazon S3存储表数据和查询结果。
虚拟仓库 系统的“肌肉”。该层称为虚拟仓库,负责虚拟机所处的弹性集群中的查询执行。
云服务 系统的“大脑”。该层是服务的集合,这些服务管理虚拟仓库、查询、事务以及所有围绕以下内容的元数据:数据库模式、访问控制信息、加密密钥、使用情况统计信息等等。
图1说明了Snowflake的三层架构及其主要组成部分。
3.1 数据存储
Amazon Web Services(AWS)已被选为Snowflake的初始平台,原因有两个。 首先,AWS是云平台市场中最成熟的产品。 其次(与第一点有关),AWS提供了最大的潜在用户池。
接下来的选择是在使用S3或基于HDFS或类似软件开发我们自己的存储服务之间[46]。我们花了一些时间对S3进行了测试,发现它的性能可能会有所降低,但其可用性,高可靠性和强一致性很难被打败。因此,我们没有决定开发自己的存储服务,而是决定将精力投入到虚拟仓库层中的本地缓存和偏斜弹性技术上。
与本地存储相比,S3显然具有更高的访问延迟,并且每个独立的I / O请求相关的CPU开销也更高,尤其是在使用HTTPS连接的情况下。 但更重要的是,S3是具有相对简单的基于HTTP(S)的PUT / GET / DELETE接口的Blob存储。 对象(如文件)只能被完全(覆盖)写入。 甚至不可能将数据追加到文件末尾。 实际上,文件的确切大小需要在PUT请求中预先声明。 但是,S3确实支持通过GET请求获取单个文件的部分(范围)内容。
这些属性对Snowflake的表文件格式和并发控制方案有很大影响(请参阅第3.3.2节)。 表被水平分区为大的、不可变的文件,这些文件等效于传统数据库系统中的块或页面。 在每个文件中,每个属性或列的值被分组在一起并进行深度压缩,这是文献中称为PAX或“混合列”的著名方案[2]。 每个表文件都有一个头部,其中除了其他元数据外,还包含文件中每个列的偏移量。 由于S3允许基于文件范围上发起GET请求,因此查询只需要下载文件头和它们感兴趣的列。
Snowflake不仅将S3用于表数据。 一旦本地磁盘空间用完,它还使用S3存储由查询运算符(例如大规模join)生成的临时数据以及大型查询结果。 将临时数据溢出到S3,系统可以计算任意大的查询,而不会出现内存不足或磁盘不足的错误。 在S3中存储查询结果将启用新形式的客户端交互,并简化查询处理,因为它消除了对传统数据库系统中服务器端游标的需求。
诸如目录对象、哪些表由哪些S3文件组成、统计信息、锁、事务日志等元数据信息,存储在可伸缩的事务性键值存储中,该存储是Cloud Services层的一部分。
3.2 虚拟仓库
虚拟仓库层由EC2实例集群组成。 每个这样的集群都通过称为虚拟仓库(VW)的抽象形式提供给其单个用户。组成VW的各个EC2实例称为工作节点。 用户从不直接与工作节点交互。 实际上,用户不知道或不在乎哪个或多少个工作节点组成了VW。 大众却选择了抽象的“ T恤尺寸”,范围从X-Small到XX-Large。这种抽象使我们能够独立于底层云平台来提供服务和定价。
3.2.1弹性和隔离
VW是纯计算资源。它们可以根据需要随时创建,销毁或调整大小。创建或销毁VW不会影响数据库的状态,完全合法(鼓励)用户在没有查询的情况下关闭其所有VW。这种弹性允许用户动态地将他们的计算资源与使用需求进行匹配,而与数据量无关。
每个单独的查询仅在一个VW上运行。工作节点不会跨VM共享,从而对于查询实现了强制的性能隔离。 (话虽如此,我们认识到共享工作节点是未来工作的重要领域,因为在性能隔离不是大问题的情况下,共享工作节点可以提高利用率并降低成本。)
提交新查询时,相应VW中的每个工作节点(如果优化器检测到一个小的查询,则为节点的子集)会产生一个新的工作进程。每个工作进程仅在其查询期间生存。一个工作进程本身(即使是更新语句的一部分)也不会引起外部可见的影响,因为表文件是不可变的,请参见 3.3.2节。因此,工作进程失败很容易得到限制并通过重试得以解决。Snowflake当前不执行部分重试,所以非常大的,长期运行的查询是值得关注和未来工作的领域。
每个用户可以在任何给定时间运行多个VW,并且每个VW依次运行多个并发查询。每个VM都可以访问相同的共享表,而无需复制数据。
共享的无限存储意味着用户可以共享和集成所有数据,这是数据仓库的核心原则之一。同时,用户受益于私有计算机资源,避免了不同工作负载和组织单位的干扰,这是数据集市的目标之一。这种弹性和隔离性使某些新颖的使用策略成为可能。 Snowflake用户通常有多个VW来查询来自不同组织单位的查询,并且经常连续运行,并定期按需启动VW,例如批量加载。
与弹性有关的另一个重要的观察结果是,即使价格大致相同,通常也可以获得更好的性能。例如,在具有4个节点的系统上花费15个小时进行数据加载,而在32个节点上仅花费2个小时。由于一个人需要支付计算时间,因此总成本非常相似-但是用户体验却大不相同。因此,我们认为VM的弹性是Snowflake架构最大的优点和与众不同之处,它表明需要一种新颖的设计来利用云的独特功能。
3.2.2 本地缓存和文件窃取
每个工作节点在本地磁盘上维护表数据的缓存。 缓存是表文件的集合,即该节点过去已访问过的S3对象。准确地说,由于查询仅下载它们需要的列,因此缓存仅保存文件头和单独的文件中的列。
缓存在工作节点维持一个失效时间,并在并发和后续工作进程(即查询)之间共享。 它只看到文件流和列的请求,并且遵循简单的最近最少使用(LRU)替换策略,且对单个查询无感知。 这个简单的方案效果很好,但是我们将来可能会对其进行改进,以更好地匹配不同的工作负载。
为了提高命中率并避免在VW的各个工作节点之间冗余缓存单个表文件,查询优化器使用对表文件名的一致性哈希将输入文件集分配给工作节点[31]。因此,随后访问同一表文件的查询或并发查询将在同一工作节点上执行此操作。
Snowflake中的一致性哈希是惰性的。当工作节点的集合发生更改时(由于节点故障或VW扩缩容),不会立即对数据进行shuffle。相反,Snowflake依赖LRU替换策略来最终重新替换缓存内容。该解决方案分摊了在多个查询上替换缓存内容的成本,因此比预先缓存或需要跨节点立即shuffle大量表数据的纯无共享系统要好得多。由于没有“降级”模式,因此也简化了系统复杂度。
除缓存外,偏斜处理在云数据仓库中尤其重要。由于虚拟化问题或网络争用,某些节点的执行速度可能比其他节点慢得多。比起其他地方,Snowflake在scan级别处理此问题。每当工作进程完成对输入文件集的扫描时,它都会向对等方请求其他文件,这是我们称之为“文件窃取”(file stealing)的技术。如果对等方发现一个请求到达时其输入文件集中还有许多文件,它将通过转移文件所有权的方式予以相应,具体而言,通过基于当前查询的持续时间和范围来转移剩余文件的所有权。然后,请求者直接从S3,而不是从其对等方下载文件。这种设计通过在离散的节点上增加额外的负载来确保文件窃取不会使情况恶化。
3.2.3执行引擎
如果另一个系统可以以相同的时间使用10个节点来执行查询,那么使用1,000个以上的节点几乎没有价值。 因此,虽然可伸缩性是首要的,但每个节点的效率同样重要。 我们希望为用户提供市场上任何数据库即服务产品的最佳性价比,因此,我们决定自己实现最先进的SQL执行引擎。 我们构建的引擎是列式的,向量化的和基于“push”模式的。
列式 由于更有效地利用CPU缓存和SIMD指令,并且有更多的机会被(轻量级)压缩,因此通常认为分析型工作负载的存储和执行要好于“行式”存储和执行。
向量化 执行意味着与MapReduce例如[42]相比,Snowflake避免了中间结果的实现。取而代之的是,数据被以Pipeline的形式,以数千行的列存储格式的批处理方式被处理。这种方法是由Vector-Wise(最初是MonetDB / X100 [15])率先提出的,可节省I / O并大大提高缓存效率。
基于Push 的执行指的是关系运算符将他们的结果推向其下游运算符,而不是等待这些运算符来拉取数据的事实(经典的Volcano模型[27])。 基于Push的执行提高了缓存效率,因为它消除了紧密循环中的控制流逻辑[41]。 它还使Snowflake能够有效地处理DAG形式的计划(正好与树形相反),从而为共享和流水线化中间结果创造了更多机会。
同时,Snowflake中不存在传统查询处理中的许多开销源。 值得注意的是,在执行过程中不需要事务管理。 就引擎而言,查询是针对一组固定的不可变文件执行的。 另外,没有缓冲池。 大多数查询会扫描大量数据。 使用将内存用于表缓冲与操作之间的权衡取舍是很糟糕的。 但是,Snowflake确实允许所有主要运算符(join,group by,sort)溢出到磁盘上,并在耗尽主内存时进行递归。 我们发现,一个纯粹的主内存引擎虽然更精简甚至更快,但对于处理所有有趣的工作负载却过于严格。 分析型工作负载可能有极大的联接或聚合特性。
3.3 云服务
虚拟仓库是短暂的,特定于用户的资源。相比之下,Cloud Services层是大量的多租户。该层的每个服务(访问控制,查询优化器,事务管理器等)都是长期存在的并且在许多用户之间共享的。 多租户可提高利用率并减少管理开销,与传统体系结构相比,这种体系结构可实现更好的规模经济,而传统体系结构中的每个用户都拥有完全私有的系统化实体。
每个服务都可以复制以实现高可用性和可扩展性。 因此,尽管某些正在运行的查询可能会失败(并透明地重新执行),但单个服务节点的失败不会导致数据丢失或可用性降低。
3.3.1 查询管理和优化
用户发出的所有查询都通过云服务层。它处理了查询生命周期的所有早期阶段:解析,对象解析,访问控制和计划优化。
Snowflake的查询优化器遵循典型的Cascades-style方案[28],并采用自顶向下的基于成本的优化方法。用于优化的所有统计信息都会在数据加载和更新时被自动维护。由于Snowflake不使用索引(请参阅第3.3.3节),因此计划搜索空间比某些其他系统小。通过将许多决策推迟到执行时(例如联接的数据分发类型)来进一步缩小计划空间。此设计减少了优化器做出错误决策的数量,从而以降低峰值性能为代价提高了鲁棒性。它还使系统易于使用(性能变得更可预测),这与Snowflake对服务体验的整体关注保持一致。
优化器完成后,将生成的执行计划分配到查询的所有工作节点。执行查询时,云服务层会持续跟踪查询的状态以收集性能计数器并检测节点故障。存储所有查询信息和统计信息,以进行审计和性能分析。用户可以通过Snowflake图形用户界面监视和分析过去和正在进行的查询。
3.3.2 并发控制
如前所述,并发控制完全由云服务层处理。 Snowflake是专为分析型工作负载而设计的,这些工作负载通常由大量读取,批量或点插以及批量更新组成。像该工作负载领域中的大多数系统一样,我们决定通过快照隔离(SI)[17]来实现ACID事务。
在SI下,事务开始时所有读取操作都会看到数据库的一致快照。按照惯例,SI是在多版本并发控制(MVCC)之上实现的,这意味着每个已更改数据库对象的副本会被保留一段时间。
考虑到表文件是不可变的,因此MVCC是自然的选择,这是使用S3进行存储的直接结果。只能通过将文件替换为包含更改的其他文件来实现更新。随之而来的是,对表的写操作(插入,更新,删除,合并)通过添加和删除相对于先前表版本相关的全部文件来产生表的新版本。文件的新增或删除,在元数据中(在全局键值存储中)以允许非常高效地计算属于特定表版本的文件集的形式跟踪文件的添加和删除。
除了用于SI外,Snowflake还使用这些快照来实现时间旅行和高效地克隆数据库对象,有关详细信息,请参见第4.4节。
3.3.3 剪枝
仅限制对与给定查询相关的数据的访问是查询处理的最重要方面之一。从历史上看,数据库中的数据访问是通过使用B +树或类似数据结构形式的索引来限制的。尽管这种方法对事务处理非常有效,但对于Snowflake这样的系统却提出了多个问题。首先,它严重依赖于随机访问,由于存储介质(S3)和数据格式(压缩文件),这是一个问题。其次,维护索引会显着增加数据量和数据加载时间。最后,用户需要显式创建索引-这与Snowflake的纯服务方法大相径庭。即使借助调优顾问,维护索引也可能是一个复杂,昂贵且冒险的过程。
最近,另一种替代技术已在大规模数据处理中获得普及:基于最小-最大的修剪,也称为小型物化聚合[38],区域图[29]和数据跳过[49]。在此,系统维护给定数据块(记录集,文件,块等)的数据分布信息,尤其是该块内的最小值和最大值。根据查询谓词,这些值可用于确定给定查询可能不需要给定的数据块。例如,假设文件f1和f2在某些columnx中分别包含值3..5和4..6。然后,如果查询的谓词x> = 6,我们知道仅需要访问f2。与传统索引不同,此元数据通常比实际数据小几个数量级,从而导致较小的存储开销和快速访问。
修剪完全符合Snowflake的设计原则:它不依赖用户输入;它可以很好地扩展;而且很容易维护。而且,它对于顺序访问大块数据非常有效,并且在加载,查询优化和查询执行时间方面几乎没有增加开销。
Snowflake会为每个单独的表文件保留与修剪相关的元数据。元数据不仅覆盖普通的相关列,而且还覆盖了半结构化数据内部的一系列自动检测列,请参见第4.3.2节。在优化期间,针对查询谓词检查元数据,以减少(“修剪”)输入文件集以执行查询。优化器不仅对简单的基值谓词执行修剪,而且还对更复杂的表达式(例如WEEKDAY(orderdate)IN(6,7))执行修剪。
除此静态修剪外,Snowflake还可以在执行期间进行动态修剪。例如,作为哈希联接处理的一部分,Snowflake收集有关构建侧记录中联接键分布的统计信息。然后将此信息推送到探针侧,并用于过滤并有可能跳过探针侧的整个文件。这是对其他众所周知的技术的补充,例如bloom joins [40]。
4. 高亮特性
Snowflake提供了关系数据仓库所期望的许多功能:全面的SQL支持,ACID事务,标准接口,稳定性和安全性,客户支持,以及(当然)强大的性能和可扩展性。 此外,它还引入了许多其他有价值的功能,这些功能在相关系统中很少见或从未见过。 本节介绍了一些我们认为是技术差异的功能。
4.1 纯软件即服务体验
Snowflake支持标准数据库接口(JDBC,ODBC,Python PEP-0249),并且可以与Tableau,Informatica或Looker等各种第三方工具和服务一起使用。但是,它还提供了仅使用Web浏览器即可与系统进行交互的可能性。 webUI看起来似乎很琐碎,但很快就证明了自己是一个关键的区分因素。 Web UI使得从任何位置和任何环境访问Snowflake都非常容易,从而大大降低了引导和使用系统的复杂性。有了大量数据,它就允许许多用户将Snowflake指向他们的数据并查询,而无需下载任何软件。
可以预期,UI不仅允许执行SQL操作,而且还提供对数据库目录,用户和系统管理,监视,使用信息等的访问。我们不断扩展UI功能,处理在线协作,用户反馈和支持等方面的问题。
但是,我们对易用性和服务体验的关注并不止于用户界面。它扩展到系统体系结构的各个方面。没有故障模式,无用的旋钮,没有物理设计,没有存储整理任务,这些都与数据和查询有关。
4.2 持续可用性
过去,数据仓库解决方案是隐藏的后端系统,与外部世界隔离。 在这样的环境中,计划内(软件升级或管理任务)和计划外(故障)的停机时间通常不会对运营产生重大影响。 但是,随着数据分析对于越来越多的业务变得至关重要,持续可用性成为任何数据仓库的重要诉求。 这种趋势反映了对现代SaaS系统的期望,其中大多数都是始终在线的,面向客户的应用程序,没有(计划的)停机时间。
Snowflake提供满足这些期望的持续可用性。 这方面的两个主要技术特性是故障恢复能力和在线升级。
4.2.1 故障容错
Snowflake可以在架构的所有层级上容忍单个节点和相关节点的故障,如图2所示。如今,Snowflake的数据存储层是S3,它的数据被复制到多个数据中心中,在亚马逊术语中称为“可用区”或AZ。跨可用区的复制使S3可以处理可用区完全故障,并保证99.99%的数据可用性和99.999999999%的持久性。与S3的体系架构一样, Snowflake的元数据存储,也可以跨多个可用区分布和复制。如果一个节点发生故障,其他节点可以接管,而对最终用户没有太大影响。云服务层的其余服务由多个可用区中的无状态节点组成,负载均衡器在它们之间分配用户请求。因此,单节点故障甚至整个可用区故障不会对整个系统造成影响,对于当前连接到故障节点的用户可能会有一些查询失败。这些用户将被重定向到其他节点以进行下一个查询。
相反,虚拟仓库(VW)不在跨可用区分布。此选择是出于性能原因。网络的高吞吐对于分布式查询执行至关重要,并且同一可用区内的网络吞吐量明显更高。如果其中的一个工作节点在查询执行过程中失败,则查询将失败,但是将透明地重新执行该查询,无论是立即替换该节点还是临时减少节点数。为了加快节点更换速度,Snowflake维护了一个小的备用节点池。 (这些节点也用于快速的备用配置。)
如果整个AZ变得不可用,则在该AZ的给定VW上运行的所有查询都将失败,并且用户需要在另一个AZ中主动重新配置该VW。由于全可用区故障确实是灾难性的,并且是极为罕见的事件,因此当前我们接受了这种部分系统不可用的情况,但希望将来能够解决。
4.2.2 在线升级
Snowflake不仅在发生故障时而且在软件升级期间都提供连续的可用性。该系统旨在允许同时部署各种服务的多个版本,包括Cloud Services组件和虚拟仓库。所有服务实际上都是无状态的,这使之成为可能。 所有的状态保存在事务键值存储中,并通过负责元数据版本化和架构演进的映射层进行访问。每当我们更改元数据Schema时,我们都确保与先前版本保持向后兼容。
为了执行软件升级,Snowflake首先将服务的新版本与以前的版本一起部署。然后,将用户帐户逐步切换到新版本,此时由相应用户发出的所有新查询都将定向到新版本。针对先前版本执行的所有查询被允许运行完毕。一旦所有查询和用户都使用完先前的版本,该版本的所有服务都将终止并下线。
图3显示了正在进行的升级过程的快照。Snowflake有两个版本并排运行,版本1(浅色)和版本2(深色)。一个Cloud Services组件有两个版本,控制着两个虚拟仓库(VW),每个VM都有两个版本。负载均衡器将调用定向到Cloud Services的相应版本。一个版本的云服务仅与匹配版本的VM交谈。
如前所述,两个版本的Cloud Services共享相同的元数据存储。此外,不同版本的VW可以共享相同的工作节点及其各自的缓存。因此,升级后无需重新填充缓存。整个过程对用户是透明的,不会造成停机时间或性能下降。
在线升级也对我们的开发速度以及我们如何处理Snowflake的重要bug产生了巨大影响。 在撰写本文时,我们每周一次升级所有服务。 这意味着我们每周都会发布功能和改进。 为了确保升级过程顺利进行,升级和降级都在Snowflake的特殊预生产版本中进行了连续测试。在极少数情况下,我们发现生产版本中存在严重错误(不一定在升级过程中),我们可以很快降级到以前的版本,或进行修复并执行计划外升级。 这个过程并不像听起来那样可怕,因为我们不断地测试和练习升级/降级机制,因此它是高度自动化和强化的。
4.3 半结构化和无结构化的数据
Snowflake使用三种类型的半结构化数据扩展了标准SQL类型系统:VARIANT,ARRAY和OBJECT。类型VARIANT的值可以存储任何原生SQL类型的值(DATE,VARCHAR等),以及值的可变长度ARRAY和类JavaScript的OBJECT,将字符串映射到VARIANT值。后者在文献中也称为文档,产生了文档存储的概念(MongoDB [39],Couchbase [23])。
ARRAY和OBJECT只是比VARIANT有更多的限制。内部表示是相同的:自描述的紧凑二进制序列化,支持快速键值查找以及有效的类型测试,比较和哈希处理。因此,VARIANT列可用作联接键,分组键和排序键,就像其他任何列一样。
VARIANT类型允许Snowflake以ELT(提取负载转换)方式使用,而不是传统的ETL(提取负载转换)方式使用。无需指定文档架构或执行负载转换。用户可以将其输入数据从JSON,Avro或XML格式直接加载到aVARIANT列中; Snow-flake处理解析和类型推断(请参阅第4.3.3节)。此方法在文献中被恰当地称为“稍后模式”,通过将信息生产者与信息消费者和任何中介机构分离,可以进行模式演变。常规ETL管道中数据模式的任何更改都需要组织中多个部门之间的协调,这可能需要几个月的时间才能执行。
ELT和Snowflake的另一个优点是,如果以后需要转换,可以使用并行SQL数据库的全部功能来执行,包括连接,排序,聚合,复杂谓词等操作,这些操作通常丢失或效率低下。传统的ETL工具链。在这一点上,Snowflake还具有具有完整JavaScript语法并与VARIANT数据类型集成的过程用户定义函数(UDF)。对过程UDF的支持进一步增加了可推入Snowflake的ETL任务的数量。
4.3.1关系后操作
对文档最重要的操作是提取数据元素,方法是通过字段名称(forOBJECTs)或偏移量(forARRAYs)。 Snowflake提供功能性SQL表示法和类似JavaScript的路径语法的提取操作。内部编码使提取非常有效。子元素只是括号内的指针。无需复制。提取后通常将结果VARIANT值转换为标准SQL类型。同样,编码使这些转换非常有效。
第二个常见操作是拉平,即将嵌套文档旋转到多行中。 Snowflake使用SQLlateral视图表示展平操作。这种扁平化整理可以是递归的,从而可以将文档的层次结构完全转换为适合SQL处理的关系表。与扁平化相反的操作是聚合。为此,Snowflake引入了一些新的聚合和分析功能,例如ARRAY_AGG和OBJECT_AGG。
4.3.2 柱状存储和处理
对半结构化数据使用序列化(二进制)表示形式是将半结构化数据集成到关系数据库中的常规设计选择。不幸的是,按行表示使得这种数据的存储和处理效率不如柱形关系数据有效,这是将半结构化数据转换为纯关系数据的常见原因。
Cloudera Impala [21](使用Parquet [10])和GoogleDremel [34]证明了半结构化数据的列式存储是可能且有益的。但是,Impala和Dremel(及其外部化BigQuery [44])要求用户提供完整的表架构用于列存储。为了实现模式少序列化表示的灵活性和列关系数据库的性能,Snowflake引入了一种新颖的自动方法来进行类型推断和列存储。
如第3.1节所述,Snowflake以混合列式格式存储数据。存储半结构化数据时,系统会自动对单个表文件中的文档集合进行统计分析,以执行自动类型推断并确定哪些(类型化)路径是常见的。然后使用相同的压缩列格式原始关系数据将相应的列从文档中删除并分别存储。对于这些列,Snowflake甚至会计算出物化的聚集体,以供修剪(请参阅第3.3.3节),以及纯关系数据。
在扫描过程中,可以将各个列重新组装为类型为VARIANT的单个列。但是,大多数查询只对原始文档的列子集感兴趣。在这种情况下,Snowflake将投影和cast表达式向下推入扫描运算符,以便仅访问必要的列并将其直接转换为目标SQL类型。
上面描述的优化是针对每个表文件单独执行的,即使在架构演变下也可以进行有效的存储和提取。但是,它确实在查询优化(尤其是修剪)方面提出了挑战。假设查询具有apath表达式的谓词,并且我们想使用修剪来限制要扫描的文件集。路径和对应的列可能出现在大多数文件中,但是只有足够频繁才能保证某些文件中的元数据。保守的解决方案是简单地扫描所有没有合适元数据的文件。 Snowflake通过对文档中存在的所有路径(不是值!)计算Bloom过滤器来改善此解决方案。这些Bloom过滤器与其他文件元数据一起保存,并在修剪过程中由queryoptimizer进行探测。可以安全地跳过不包含给定查询所需路径的表文件。
4.3.3 乐观转换
由于某些本机SQL类型(尤其是日期/时间值)以通用外部格式(例如JSON或XML)表示为字符串,因此需要在写入时(插入或更新期间)或读取时将这些值从字符串转换为其实际类型。时间(查询期间)。在没有类型化模式或等效提示的情况下,这些字符串转换需要在读取时执行,这在读取为主的工作负载中,效率不如写入期间一次转换。未类型化数据的另一个问题是缺少适合的修剪元数据,这在日期的情况下尤其重要。 (分析工作负载通常在日期列上有范围谓词。)
但是在写时应用自动转换可能会丢失信息。例如,包含数字产品标识符的字段实际上可能不是数字,而是带有有效前导零的字符串。同样,看起来像日期的内容实际上可能是文本消息的内容。 Snowflake通过执行乐观数据转换并在单独的列中保留转换结果和原始字符串(除非存在完全可逆转换)来解决该问题。如果以后查询需要原始字符串,则可以轻松地检索或重建它。因为未使用的列不会被加载和访问,所以任何双重存储对查询性能的影响都是最小的。
4.3.4 性能
为了评估列存储,优化转换以及对半结构化数据的修剪对查询性能的综合影响,我们使用TPC-H-like4数据和查询进行了一组实验。
我们创建了两种类型的数据库模式。首先,是一个常规的,相关的TPC-H模式。其次,“无模式”数据库模式,其中每个表都由typeVARIANT的sin-gle列组成。然后,我们生成了聚类的(分类的)SF100和SF1000数据集(分别为100 GB和1 TB),以纯JSON格式存储数据集(即,日期变成了字符串),然后使用关系型将数据加载到Snowflake中。以及没有模式的数据库模式。未向系统提供有关无模式数据的字段,类型和群集的任何类型的提示,并且没有进行其他调整。然后,我们在无模式数据库的顶部定义了一些视图,以便能够对所有四个数据库运行完全相同的TPC-H查询集。(在撰写本文时,Snowflake并未将视图用于类型推断或其他优化,因此这纯粹是语法上的便利。)
最后,我们使用amedium standardwarehouse5对这四个数据库运行了所有22个TPC-H查询。图4显示了结果。在具有热缓存的三个运行中获得了数字。标准误差不明显,因此从结果中省略。
可以看出,除了两个查询(SF1000上的Q9和Q17)之外,所有其他内容的无模式存储和查询处理开销约为10%。对于这两个查询,我们确定减速的原因是次优的联接顺序,这是由不同值估计中的已知错误引起的。我们将继续改进半结构化数据的元数据收集和查询优化。
总而言之,具有相对稳定和简单模式的半结构化数据的查询性能(即,在实践中发现的大多数机器生成数据)几乎与常规关系数据的查询性能相当,享有列存储的所有优势,列执行和修剪-无需用户费力。
4.4 时间旅行和克隆
在3.3.2节中,我们讨论了Snowflake如何在多版本并发控制(MVCC)之上实现快照隔离(SI)。 通过添加和删除整个文件,对表执行写操作(插入,更新,删除,合并)会生成表的较新版本。
当文件被新版本删除时,它们会保留一段可配置的持续时间(当前最多90天)。文件保留功能使Snowflake可以高效地读取早期版本的表; 也就是说,要在数据库上执行时间旅行。 用户可以使用便利的AT或BEFORE语法从SQL访问此功能。 相对于当前时间或相对于先前的语句(ID引用),时间戳可以是绝对时间戳。
SELECT * FROM my_table AT(TIMESTAMP =>
’Mon, 01 May 2015 16:20:00 -0700’::timestamp);
SELECT * FROM my_table AT(OFFSET => -60*5); -- 5 min ago
SELECT * FROM my_table BEFORE(STATEMENT =>
’8e5d0ca9-005e-44e6-b858-a8f5b37c5726’);
一个查询甚至可以访问同一张表的不同版本。
SELECT new.key, new.value, old.value FROM my_table new
JOIN my_table AT(OFFSET => -86400) old -- 1 day ago
ON new.key = old.key WHERE new.value <> old.value;
基于相同的基础元数据,Snowflake引入了UNDROP关键字,以快速恢复意外删除的表,模式或整个数据库。
DROP DATABASE important_db; -- whoops!
UNDROP DATABASE important_db;
Snowflake还实现了我们称为克隆的功能,该功能通过新的关键字CLONE表示。 克隆表将快速创建具有相同定义和内容的新表,而无需制作表文件的物理副本。 克隆操作只是复制源表的元数据。 克隆后,两个表都引用相同的文件集,但是此后可以独立修改两个表。 克隆功能还支持整体方案或数据库,从而可以实现非常高效的快照。 在进行大量更新之前或执行冗长的探索性数据分析时,快照是一种很好的做法。 CLONE关键字甚至可以与AT和BEEFORE组合使用,从而可以在事后创建此类快照。
CREATE DATABASE recovered_db CLONE important_db BEFORE(
STATEMENT => ’8e5d0ca9-005e-44e6-b858-a8f5b37c5726’);
4.5 安全性
Snowflake旨在保护用户数据免受对架构所有级别(包括云平台)的攻击。 为此,Snowflake实现了两要素身份验证,(客户端)加密的数据导入和导出,安全的数据传输和存储以及针对数据库对象的基于角色的访问控制(RBAC [26])。 始终在通过网络发送数据之前以及将其写入本地磁盘或共享存储之前对数据进行加密(S3)。 因此,Snowflake提供了完整的端到端数据加密和安全性。
4.5.1 密钥层次结构
Snowflake使用强大的AES 256位加密,以及基于AWS CloudHSM [12]的层次结构密钥模型。加密密钥会自动旋转并重新加密(“ rekeyed”),以确保密钥完成完整的NIST 800-57加密密钥管理生命周期[13]。加密和密钥管理对用户完全透明,不需要配置或管理。
如图5所示,Snowflake密钥层次结构具有四个级别:根密钥,帐户密钥,表密钥和文件密钥。(父)密钥的每一层都进行加密,即包装下面的(子)密钥层。每个帐户密钥对应一个用户帐户,每个表密钥对应一个数据库表,每个文件密钥对应一个表文件。
分层密钥模型是一种好的安全做法,因为它们会限制每个密钥保护的数据量。如图5框中的方框所示,每个层都减小了其下层密钥的范围。Snowflake的分层密钥模型可确保其多租户体系结构中的用户数据隔离,因为每个用户帐户都有一个单独的帐户密钥。
4.5.2 关键生命周期
正交于限制每个键保护的数据量,Snowflake还限制了密钥可用的持续时间。加密密钥经历四个阶段:(1)运营前的创建阶段;(2)运营阶段,其中密钥用于加密(发起者使用期限)和解密(收件人使用时期),(3)后-不再使用密钥的操作阶段,以及(4)销毁阶段。阶段1、3和4对实现很重要。第2阶段要求限制发起者的使用期限和接收者的使用期限。仅当密钥不再对任何必需的数据进行加密时,才可以将其移至阶段3和4。Snowflake使用密钥旋转来限制发起者的使用期限,并使用重新密钥来限制接收者的使用期限。
密钥轮换。以固定的时间间隔(例如一个月)创建新版本的密钥。在每个这样的间隔之后,将创建密钥的新版本,并且该密钥的先前版本将“停用”。淘汰的版本仍然可用,但仅用于解密数据。将新的子密钥包装在密钥层次结构中或写入表时,仅使用密钥的最新activeversion来加密数据。
密钥更新是使用新密钥重新加密旧数据的过程。在特定的时间间隔(例如一年)之后,已使用退役密钥加密的数据将使用活动密钥进行重新加密。此密钥更新与密钥旋转正交。密钥旋转可确保将密钥从其活动状态(发起方使用)转移到退回状态(收件人使用),而密钥更新可确保密钥可以从其退回状态转移到被销毁。
图6显示了单个表键的生命周期。假设密钥每月轮换一次,数据每年重新键入一次。表文件1和2是在2014年4月使用密钥1版本1(k1v1)创建的。 2014年5月,将键1旋转到版本2(k1v2),并使用k1v2创建了表文件3。在2014年6月,密钥1旋转到了版本3(k1v3),并且创建了两个更多的表文件。 2014年6月之后,不再对表进行任何插入或更新。2015年4月,k1v1诞生了一年,需要销毁。创建了一个新的密钥,密钥2version 1(k2v1),并且与所有与k1v1相关的文件都使用k2v1进行了密钥替换。在2015年5月,tok1v2发生了同样的情况,并且表文件3使用k2v2重命名。在2015年6月,表文件4和5使用k2v3重命名。
在帐户密钥和表密钥之间,以及在根密钥和帐户密钥之间实现了类似的方案。密钥层次结构的每个级别都要进行密钥旋转和重新密钥化,包括根密钥。帐户密钥和根密钥的密钥旋转和重新密钥不需要对文件进行重新加密。仅直接下一级的密钥需要重新加密。
表键和文件键之间的关系是不同的。文件密钥不由表密钥包装。相反,文件密钥是由表密钥和(唯一)文件名的组合以密码方式派生的。因此,每当表密钥更改时,其所有相关的文件密钥都会更改,因此受影响的表文件需要重新加密。但是,密钥派生的最大好处是,它消除了创建,管理和传递单个密钥的需要。文件密钥。像Snowflake这样的处理数十亿个文件的系统否则必须处理许多GB的文件密钥。
我们之所以选择这种设计,还因为Snowflake的存储与计算分离,可以在不影响用户工作负载的情况下执行重新加密。使用与查询不同的工作程序节点,密钥更新在后台工作。重新命名文件后,Snowflake自动更新数据库表的元数据以指向新加密的文件。所有正在进行的查询完成后,旧文件将被删除。
4.5.3 端到端安全
Snowflake使用AWS CloudHSM作为防篡改,高度安全的方式来生成,存储和使用密钥层次结构的根密钥。 AWS CloudHSM是一组硬件安全模块(HSM),它们连接到AWS中的虚拟专用集群。根密钥永远不会离开HSM设备。使用根密钥的所有加密操作都在HSM本身中执行。因此,如果未授权访问HSM设备,则无法解开下层密钥。 HSM还用于在帐户和表级别生成密钥,包括在密钥旋转和重新密钥生成期间。我们在其高可用性配置中配置了AWS CloudHSM,以最大程度地减少服务中断的可能性。
除数据加密外,Snowflake还通过以下方式保护用户数据:
1.通过S3上的访问策略隔离存储。
2.用户帐户内基于角色的访问控制,用于对数据库对象的细粒度访问控制。
3.加密的数据导入和导出,而cloudprovider(Amazon)从来没有清楚地看到过数据。
4.用于安全访问控制的两因素身份验证和联合身份验证。
总而言之,Snowflake提供了一个根植于AWS CloudHSM中的分层密钥模型,并使用密钥轮换和重新键入密钥来确保加密密钥遵循标准化的生命周期。密钥管理对用户完全透明,无需配置,管理或停机,它是全面安全策略的一部分,可实现全面的端到端加密和安全性。
5. 相关工作
基于云的并行数据库系统。亚马逊拥有许多DBaaS产品,其中Amazon Redshift成为其中的数据仓库产品。从并行数据库系统ParAccel演变而来,Red-shift可以说是第一个作为服务提供的实际数据仓库系统[30]。 Redshift使用经典的无共享架构。因此,在具有可伸缩性的同时,添加或删除计算资源需要重新分配数据。相比之下,Snowflake的多集群共享数据体系结构使用户无需存储即可独立于存储而立即迅速地扩展,缩小甚至暂停计算,而无需移动数据,包括跨隔离的计算资源集成数据的能力。同样,遵循纯服务原则,Snowflake不需要进行物理调整,数据整理,手动收集表统计信息或用户清理表。尽管Redshift可以将诸如JSON之类的半结构化数据作为aVARCHAR接收,但是Snowflake具有对半结构化数据的本地支持,包括重要的优化(如列存储)。
Google的云平台提供了一个称为BigQuery [44]的完全托管的查询服务,这是Dremel [34]的公共实现。 BigQuery服务使用户能够以惊人的速度对数TB的数据进行查询,并在数千个节点之间进行并行处理。 Snowflake的灵感之一就是BigQuery对JSON和nesteddata的支持,我们认为这对于现代分析平台是必需的。但是,尽管BigQuery提供了一种类似SQL的语言,但它与ANSI SQL语法和语义存在一些根本性的差异,因此很难与基于SQL的产品一起使用。此外,BigQuery表是仅追加和重新要求的架构。相比之下,Snowflake提供完整的DML(插入,更新,删除,合并),ACID事务,并且不需要半结构化数据的架构定义。
Microsoft SQL数据仓库(Azure SQL DW)是基于SQL Server及其分析平台系统(APS)设备[38,37]的Azure云平台和服务的最新添加。与Snowflake类似,它将存储与计算分开。可以通过数据仓库单元(DWU)扩展计算资源。并发度是有上限的。对于任何数据仓库,并发执行查询的最大数量为32 [47]。相反,Snowflake允许通过虚拟仓库完全独立地缩放并发工作负载。雪花用户也免除了选择适当的分发密钥和其他管理任务的负担。尽管Azure SQL DW确实通过PolyBase支持对非关系数据的查询[24],但它不具有对半数的内置支持。结构化的数据,可媲美Snowflake的VARIANT类型和相关优化。
文档存储和大数据。由于可伸缩性,简单性和模式性,近年来,诸如MongoDB [39],Couchbase Server [23]和ApacheCassandra [6]等文档存储在应用程序开发人员中越来越受欢迎。他们提供的灵活性。但是,这些系统的简单键值和CRUD(创建,读取,更新和删除)API所带来的挑战之一就是难以表达更复杂的查询。作为回应,我们看到了类似SQL的几种查询语言的出现,例如Couch-base的N1QL [22]或Apache Cassandra的CQL [19]。此外,许多“大数据”引擎现在支持对嵌套数据的查询,例如Apache Hive [9],Apache Spark [11],ApacheDrill [7],Cloudera Impala [21]和Facebook Presto [43]。这表明确实需要基于无模式和半结构化数据的复杂分析,而我们的半结构化数据支持则受到许多此类系统的启发。使用模式推断,乐观转换和列存储,Snowflake将这些系统的灵活性与区域性,面向列的数据库的存储效率和执行速度结合在一起。
6.经验教训和展望
Snowflake于2012年成立时,数据库领域完全专注于Hadoop上的SQL,短时间内出现了十几个系统。当时,朝着完全不同的方向工作,为云构建“经典”数据仓库系统的决定似乎是一种逆势而冒险的举动。经过3年的发展,我们相信这是正确的选择。 Hadoop尚未取代RDBMS;它补充了他们。人们仍然想要一个关系数据库,但是它是一个更高效,更灵活并且更适合于云的数据库。
Snowflake满足了我们的希望,即为云构建的系统可以为用户和作者提供什么。多集群共享数据体系结构的弹性改变了用户处理数据处理任务的方式。SaaS模型不仅使用户易于试用和采用该系统,而且还极大地帮助了我们的开发和测试。通过单一生产版本和在线升级,我们可以发布新功能,提供改进并解决问题,其速度要比传统开发模式下要快得多。
虽然我们希望半结构化扩展将证明有用,但是我们对采用的速度感到惊讶。我们发现了一个非常流行的模型,组织将Hadoop用于两件事:存储JSON,以及将JSON转换为可加载到RDBMS中的格式。通过提供可以按原样高效存储和处理半结构化数据的系统(顶部具有强大的SQL接口),我们发现Snowflake不仅可以替代传统的数据库系统,而且还可以替代Hadoop集群。
当然,这并不是一段轻松的旅程。尽管我们的团队拥有超过100年的数据库开发专业知识,但我们确实在此过程中避免了可避免的错误,包括某些相关运算符的过分简化的早期实现,没有在引擎中尽早合并所有数据类型,而不是尽早地合并了所有数据类型。充分关注资源管理,推迟全面的日期和时间功能性等方面的工作。此外,我们对避免音调旋钮的持续关注也带来了一系列工程挑战,最终带来了许多令人兴奋的技术解决方案。作为结果,今天,Snowflake仅具有一个调整参数:用户想要(并愿意为此付费)多少性能。
尽管Snowflake的性能已经非常具有竞争力,尤其是考虑到无调整方面,但我们知道许多优化尚待时日。尽管有些出乎意料,但核心性能对我们的用户而言几乎不是问题。原因是通过虚拟仓库进行的弹性计算可以提供偶尔需要的性能提升。这使我们将开发工作集中在系统的其他方面。
我们面临的最大技术挑战与系统的SaaS和多租户方面有关。构建可同时支持数百个用户的ametadata层是一项非常具有挑战性和复杂的任务。处理各种类型的节点故障,网络故障和支持服务是一场永无止境的斗争。安全一直并将继续成为一个大话题:保护系统和用户数据免受外部攻击,用户本身以及我们的内部用户攻击。维持每天运行数以百万计的查询的数百个节点的实时系统,同时带来很多满意度,这需要针对开发,操作和支持的高度集成的方法。
7.致谢
Snowflake是太多人的工作在这里列出。我们要感谢整个Snowflake工程团队对产品的贡献,以及他们投入的所有辛勤工作,努力和自豪。 我们还要感谢所有其他“雪花”公司在将这种产品带给用户并共同组建大型公司方面所做的出色工作。 与如此优秀的团队合作,我们不断感到印象深刻和谦卑。
8. REFERENCES
[1] D. J. Abadi, S. R. Madden, and N. Hachem. Column-stores vs.
row-stores: How different are they really? In
Proc. SIGMOD
,
2008.
[2] A. Ailamaki, D. J. DeWitt, M. D. Hill, and M. Skounakis.
Weaving relations for cache performance. In
Proc. VLDB
, 2001.
[3] S. Alsubaiee et al. AsterixDB: A scalable, open source DBMS.
PVLDB
, 7(14):1905–1916, 2014.
[4] Amazon Elastic Compute Cloud (EC2).
aws.amazon.com/ec2/instance-types.
[5] Amazon Simple Storage Service (S3). aws.amazon.com/s3.
[6] Apache Cassandra. cassandra.apache.org.
[7] Apache Drill. drill.apache.org.
[8] Apache Hadoop. hadoop.apache.org.
[9] Apache Hive. hive.apache.org.
[10] Apache Parquet. parquet.apache.org.
[11] Apache Spark. spark.apache.org.
[12] AWS CloudHSM. aws.amazon.com/cloudhsm.
[13] E. Barker.
NIST SP 800-57 – Recommendation for Key
Management – Part 1: General (Revision 4)
, chapter 7. 2016.
[14] J. Barr. AWS Import/Export Snowball – Transfer 1 petabyte
per week using Amazon-owned storage appliances.
aws.amazon.com/blogs/aws/aws-importexport-snowball-
transfer-1-petabyte-per-week-using-amazon-owned-storage-
appliances/, 2015.
[15] P. Boncz, M. Zukowski, and N. Nes. MonetDB/X100:
Hyper-pipelining query execution. In
Proc. CIDR
, 2005.
[16] V. R. Borkar, M. J. Carey, and C. Li. Big data platforms:
What’s next?
ACM Crossroads
, 19(1):44–49, 2012.
[17] M. J. Cahill, U. R
̈
ohm, and A. D. Fekete. Serializable isolation
for snapshot databases. In
Proc. SIGMOD
, 2008.
[18] B. Calder et al. Windows Azure Storage: A highly available
storage service with strong consistency. In
Proc. SOSP
, 2011.
[19] Cassandra Query Language (CQL).
cassandra.apache.org/doc/cql3/CQL.html.
[20] Cloud Storage – Google Cloud Platform.
cloud.google.com/storage.
[21] Cloudera Impala. impala.io.
[22] Couchbase N1QL. couchbase.com/n1ql.
[23] Couchbase Server. couchbase.com.
[24] D. J. DeWitt, A. Halverson, R. Nehme, S. Shankar,
J. Aguilar-Saborit, A. Avanes, M. Flasza, and J. Gramling.
Split query processing in Polybase. In
Proc. SIGMOD
, 2013.
[25] D. J. DeWitt, S. Madden, and M. Stonebraker. How to build a
high-performance data warehouse.
db.csail.mit.edu/madden/high
perf.pdf, 2006.
[26] D. Ferraiolo, D. R. Kuhn, and R. Chandramouli.
Role-based
access control
. Artech House Publishers, 2003.
[27] G. Graefe. Volcano: An extensible and parallel query
evaluation system.
IEEE TKDE
, 6(1), 1994.
[28] G. Graefe. The cascades framework for query optimization.
Data Engineering Bulletin
, 18, 1995.
[29] G. Graefe. Fast loads and fast queries. In
Data Warehousing
and Knowledge Discovery
, volume 5691 of
LNCS
. Springer,
2009.
[30] A. Gupta et al. Amazon Redshift and the case for simpler data
warehouses. In
Proc. SIGMOD
, 2015.
[31] D. Karger, E. Lehman, T. Leighton, R. Panigrahy, M. Levine,
and D. Lewin. Consistent hashing and random trees:
Distributed caching protocols for relieving hot spots on the
world wide web. In
Proc. STOC
, 1997.
[32] J. Krueger, M. Grund, C. Tinnefeld, H. Plattner, A. Zeier, and
F. Faerber. Optimizing write performance for read optimized
databases. In
Proc. DASFAA
, 2010.
[33] S. Manegold, M. L. Kersten, and P. Boncz. Database
architecture evolution: Mammals flourished long before
dinosaurs became extinct.
PVLDB
, 2(2):1648–1653, 2009.
[34] S. Melnik, A. Gubarev, J. J. Long, G. Romer, S. Shivakumar,
M. Tolton, and T. Vassilakis. Dremel: Interactive analysis of
web-scale datasets.
PVLDB
, 3(1-2):330–339, 2010.
[35] Microsoft Analytics Platform System. www.microsoft.com/en-
us/server-cloud/products/analytics-platform-system.
[36] Microsoft Azure Blob Storage.
azure.microsoft.com/en-us/services/storage/blobs.
[37] Microsoft Azure SQL DW.
azure.microsoft.com/en-us/services/sql-data-warehouse.
[38] G. Moerkotte. Small materialized aggregates: A light weight
index structure for data warehousing. In
Proc. VLDB
, 1998.
[39] MongoDB. mongodb.com.
[40] J. K. Mullin. Optimal semijoins for distributed database
systems.
IEEE TSE
, 16(5):558–560, 1990.
[41] T. Neumann. Efficiently compiling efficient query plans for
modern hardware.
PVLDB
, 4(9):539–550, 2011.
[42] A. Pavlo, E. Paulson, A. Rasin, D. J. Abadi, D. J. DeWitt,
S. Madden, and M. Stonebraker. A comparison of approaches
to large-scale data analysis. In
Proc. SIGMOD
, 2009.
[43] Presto. prestodb.io.
[44] K. Sato. An inside look at Google BigQuery.
cloud.google.com/files/BigQueryTechnicalWP.pdf, 2012.
[45] J. Schad, J. Dittrich, and J.-A. Quian ́e-Ruiz. Runtime
measurements in the cloud: Observing, analyzing, and reducing
variance.
PVLDB
, 3(1):460–471, 2010.
[46] K. Shvachko, H. Kuang, S. Radia, and R. Chansler. The
Hadoop distributed file system. In
Proc. MSST
, 2010.
[47] SQL DW Concurrency.
azure.microsoft.com/en-us/documentation/articles/sql-data-
warehouse-develop-concurrency.
[48] Stinger.next: Enterprise SQL at Hadoop scale.
hortonworks.com/innovation/stinger.
[49] L. Sun, M. J. Franklin, S. Krishnan, and R. S. Xin.
Fine-grained partitioning for aggressive data skipping. In
Proc.
SIGMOD
, 2014.
226
本文转自——https://docs.google.com/document/d/1Pi0KQzxUxAMibZnGJQLbHQC_iXybp_s_8w8oL2yJyZw

浙公网安备 33010602011771号