相比之下,自然界中较软的金属之一--铁,可以被改造成无尽的应用:最锋利的刀片、最高的摩天大楼、最先进的汽车, 巨大的轮船,而且很快,如果埃隆-马斯克是对的,就会有最有效的电动车电池。
换句话说,铁之所以有令人难以置信的用处,是因为它既是刚性的又是柔性的。
同样,数据库只有在既严格又灵活的情况下才对今天的实时分析有用。
传统的数据库,由于其完全灵活的结构,是很脆的。无模式的NoSQL数据库也是如此,它们能够摄取大量的数据,但在从这些数据中提取复杂的见解方面却很差。
用户个性化,自动库存管理,智能运维和其他实时用例要求数据库严格执行模式,并拥有根据数据本身自动重新定义这些模式的灵活性。这满足了现代分析的三个关键要求:
- 支持采集数据的规模和速度
- 支持灵活的模式,可以立即适应流式数据的多样性
- 支持快速、复杂的SQL查询,需要严格的结构或模式
昨天的模式:坚硬而脆弱
经典的模式是关系型数据库表:实体的行,例如人,以及这些实体的不同属性(年龄或性别)的列。通常存储在SQL语句中,模式还定义了数据库中所有的表以及它们之间的关系。
传统上,模式是严格执行的。不符合预定属性或数据类型的输入数据会被数据库自动拒绝,在其位置上存储一个空值或完全跳过整个记录。改变模式是很困难的,也是很少做的。公司小心翼翼地设计他们的ETL数据管道,以便与他们的模式保持一致(反之亦然)。
在过去,预先创建和严格执行模式有很好的理由。SQL查询更容易编写。它们的运行速度也快了很多。最重要的是,严格的模式可以防止由不良或不匹配的数据造成的查询错误。
然而,严格的、一成不变的模式在今天有着巨大的弊端。首先,现在的数据来源和类型比90年代多得多。他们中的许多人不能轻易地适应相同的模式结构。最值得注意的是实时事件流。流媒体和时间序列数据通常以经常变化的半结构化格式到达。随着这些格式的改变,模式也必须改变。
其次,随着业务条件的变化,公司不断需要分析新的数据源,运行不同类型的分析--或者简单地更新其数据类型或标签。
这里有一个例子。当我在Fackbook的数据基础设施团队的时候,我们参与了一项雄心勃勃的计划,名为"花蜜项目 "的用户群正在爆炸性增长。"花蜜项目 "试图用一套标准的属性来记录每个用户的行为。在全球范围内实现这一模式的标准化,将使我们能够在全球范围内分析趋势并发现异常情况。经过许多内部辩论,我们的团队同意在Hadoop中使用一个名为time_spent的列中的时间戳来存储每个用户事件,该列的分辨率为一秒。
在 "花蜜项目 "首次亮相后,我们向一组新的应用程序开发人员展示了它。他们问的第一个问题是"你能把列的花费时间从秒改为毫秒吗?"换句话说,他们随口要求我们在Nectar项目推出后重建其模式的一个基本方面。
ETL管道可以使你所有的数据源都在同一个传说中的屋顶下(这就是T,代表数据转换的意思)。然而,ETL管道的设置、操作以及随着数据来源和类型的变化而进行的手动更新都很耗时和昂贵。
灵活性的尝试
严格的、一成不变的模式破坏了灵活性,而今天所有的公司都需要这种灵活性。一些数据库制造商通过使用户更容易手动修改他们的模式来应对这个问题。不过,这也是一个沉重的代价。
使用SQL ALTER-TABLE命令改变模式需要大量的时间和处理能力,使你的数据库长时间处于离线状态。而且,一旦模式被更新,就很有可能在无意中破坏你的数据,使你的数据管道瘫痪。
以 PostgreSQL,是流行的交易型数据库,许多公司也用它来做简单的分析。为了正确摄取当今快速变化的事件流,PostgreSQL必须通过SQL中的手动ALTER-TABLE命令来改变其模式。这将锁定数据库表,并在ALTER-TABLE完成的时间内冻结所有查询和交易。据说,无论你的PostgreSQL表有多大,ALTER-TABLE都需要很长的时间。它还需要大量的CPU,并造成数据错误和下游应用中断的风险。
NewSQL数据库也面临同样的问题。 CockroachDB 承诺在线改变Schema具有零停机时间。然而,Cockroach警告说不要一次做超过一个模式的改变。它也强烈警告不要在交易中改变模式。就像PostgreSQL一样,CockroachDB的所有模式改变都必须由用户手动完成。因此,CockroachDB的模式远没有表面上那么灵活。而且,数据错误和数据停机的风险也同样存在。
NoSQL来拯救?
其他制造商发布的NoSQL数据库大大放松了模式,或者完全放弃了模式。
这种激进的设计选择使NoSQL数据库--文档数据库、键值存储、面向列的数据库和图形数据库--非常适合将各种类型的海量数据存储在一起,无论是结构化、半结构化还是多态化的数据。
Data lakes建立在NoSQL数据库(如Hadoop)上的数据湖是混合类型的扩展数据存储库的最好例子。NoSQL数据库在检索大量数据和运行简单查询方面也很迅速。
然而,轻量级/非轻量级模式数据库确实存在弊端。
虽然查找和简单的查询可以是快速和简单的,但复杂的嵌套的和必须返回精确答案的查询往往运行缓慢,而且难以创建。这是由于缺乏SQL支持,以及他们倾向于对索引和其他查询优化的支持不力。复杂的查询甚至更有可能超时而不返回结果,这是因为NoSQL的过于宽松的数据一致性模型。修复和重新运行查询是一件浪费时间的麻烦事。而当涉及到云计算和开发人员时,这意味着浪费金钱。
以作为Hadoop堆栈一部分的Hive分析数据库为例。Hive确实支持灵活的模式,但很粗略。当它遇到不适合整齐地放入现有表格和数据库的半结构化数据时,它只是将数据存储为一个 JSON-like blob,这可以保持数据的完整性。然而,在查询时,Blobs需要首先被反序列化,这是一个缓慢而低效的过程。
或者采取亚马逊DynamoDB为例,它使用的是无模式的键值存储。DynamoDB在读取特定记录时速度超快。多记录查询往往要慢得多,尽管建立二级索引可以帮助。更大的问题是,DynamoDB不支持任何JOIN或任何其他复杂查询。
严格和灵活模式的正确方法
然而,有一个成功的数据库公式,它融合了NoSQL的灵活可扩展性和SQL的准确性和可靠性,同时又加入了云原生基础设施的低操作简单性。
Rockset是一个建立在RocksDB键值存储之上的实时分析平台。像其他NoSQL数据库一样,Rockset具有高度的可扩展性、灵活性和快速写入数据的能力。但与SQL关系型数据库一样,Rockset也有严格的模式优势。强数据类型和高度的数据一致性,再加上我们的自动和高效的 Converged Indexing这些优势与我们的自动和高效的数据库相结合,确保你的复杂的SQL查询是快速的。
Rockset自动生成Schema通过检查数据的字段和数据类型,因为它是存储的。而且Rockset可以处理扔给它的任何类型的数据,包括。
- 具有深度嵌套数组和对象的JSON数据,以及混合数据类型和稀疏字段
- 实时事件流,随着时间的推移不断增加新的字段
- 来自新数据源的新数据类型
支持无模式摄入和融合索引,使Rockset能够通过消除对上游数据转换的需求来减少数据延迟。
Rockset还有其他优化功能,以减少存储成本和加速查询。对于每条记录的每一个字段,Rockset都会存储数据类型。这最大限度地提高了查询性能和减少了错误。而且,我们通过一个叫做字段互换的功能有效地做到了这一点,与无模式的基于JSON的文档数据库相比,例如,所需的存储量最多可减少30%。
Rockset使用了一种叫做类型提升的东西来减少查询的处理时间。具有相同类型的相邻项目可以将其类型信息提升到适用于整个项目集,而不是存储在列表中的每一个单独的项目。这使得矢量的CPU指令能够快速处理整个项目集。这个实现--连同我们的 Converged Index™--使Rockset查询能够像具有刚性模式的数据库一样快速运行,而不会产生额外的计算。
一些NoSQL数据库的制造商声称只有他们能支持灵活的模式。 这不是真的,而且是Rockset等现代产品正在打破的一个神话。