数据存储是一个话题,往往在出现问题(数据消失)或事情进展顺利(客户过多)时才被充分理解。由于数据库可以被视为带有 API 的黑匣子,其内部运作常常被忽视。它们通常被视为神奇的东西,只需提供数据就能接收,需要时就能供应。由于这两个操作是唯一被理解的技术活动,因此它们往往是比较不同技术时唯一呈现的特性。
基准测试通常以每秒操作数来提供,但究竟什么是操作?在数据库领域,这可能意味着很多事情。该操作是事务吗?它是数据索引吗?是从索引中检索吗?它是将数据存储到硬盘等持久介质中,还是用激光将其发射到半人马座阿尔法星?
正是这种歧义在软件行业造成混乱。误解数据库系统的特性和保证可能会导致用户因速度慢或不可用而感到沮丧,这还算好的情况。最坏的情况可能会导致经济损失,甚至因数据丢失而面临牢狱之灾。
数据库一词的范围非常广泛。从技术上讲,任何存储数据以供后续检索的东西都是数据库。即使按照如此宽泛的定义,大多数数据库都具有一些共同的功能。本文将从高层次上列举这些特性。目的是为读者提供一套工具,以便他们能够评估数据库的相对优点。由于这些主题无法在此处详细介绍,因此包含了其他阅读材料的参考文献。这些主题可能是未来文章的主题。
这种以特性驱动的方法应允许读者评估自身需求,并通过匹配相似的特性来比较技术。通过这种视角来看,只有在数据库执行相同的工作并提供相同的保证时,比较基准才是有效的。
在深入探讨数据库的特性之前,让我们先讨论一下为什么您不直接采用所有特性。简短的回答是,每个特性通常都会带来性能成本,即使不是复杂性成本。
数据库执行的大多数功能,以及实现这些功能的算法,都是为了解决硬盘这个性能瓶颈而构建的。如果您要求数据(和元数据)具有持久性,那么您必须以某种方式为此付出代价。
典型服务器(Ivy Bridge 架构)的 SATA(串行 ATA)总线的理论最大带宽为每秒 750 MB。这看起来很高,但与 PCI 3.0 总线(最大带宽为每秒 40 GB)或内存总线(每个通道每秒 14.9 GB,至少有四个通道)相比,SATA 总线在现代服务器中具有最低带宽的数据路径(外围设备除外)。1
除了带宽瓶颈之外,还有延迟需要考虑。数据中心内遇到的最高延迟操作是在硬盘上的随机位置进行寻道。目前,7200 RPM 的硬盘的寻道时间约为 4 毫秒。这意味着它每秒可以找到并读取磁盘上的新位置约 250 次。如果服务器应用程序依赖于在每次请求时在磁盘上查找某些内容,则每个磁盘每秒将被限制为 250 个请求。2
一旦找到某个位置,在该位置进行连续的追加或读取操作就会便宜得多。这被称为顺序读取或写入。自磁性旋转磁盘发明以来,数据存储和检索的算法已经针对这一事实进行了优化。通常,人们将文件操作称为随机或顺序,并理解后者比前者的成本低得多。
SSD(固态硬盘)为磁盘带来了巨大的延迟和吞吐量改进。SSD 上的寻道速度比硬盘快约 60 倍。然而,SSD 也带来了自身的挑战。例如,SSD 内的存储单元具有固定的寿命,也就是说,它们在失效之前只能处理一定次数的写入操作。因此,它们具有专门的固件,可以在磁盘上分散写入、进行垃圾回收以及执行其他簿记操作。因此,它们的性能特征不太可预测(尽管它们可以预测地比硬盘更快)。
由于硬盘驱动器的高延迟和低吞吐量,几乎每个操作系统都找到了一种优化方法,即页面缓存或缓冲区缓存。顾名思义,页面缓存旨在通过将文件内容存储在操作系统内核映射到磁盘的内存页中,从而透明地优化掉磁盘访问的成本。其思想是,磁盘或文件的相同局部部分将在短时间内被多次读取或写入。对于数据库来说,这通常是正确的。
当发生读取时,如果页面缓存的内容与磁盘同步,它将从内存中返回该内容。相反,写入将修改缓存的内容,但不一定会写入硬盘本身。这是为了尽可能消除磁盘访问。
假设写入一条数据记录需要 5 毫秒,并且您必须将 20 条不同的记录写入磁盘,那么在页面缓存中执行这些操作,然后再刷新到磁盘,只需一次磁盘访问的成本,而不是 20 次。考虑到访问机器上的主内存比在磁盘上查找数据快约 40,000 倍,性能节省很快就会累积起来。
每个操作系统都有不同的模型来决定如何将其更改刷新到磁盘,但几乎所有操作系统都与调度程序协同工作,以找到合适的点来静默地将内存中的数据同步到磁盘上。文件和页面也可以手动刷新到磁盘。当您需要保证数据更改是永久性的时,这非常有用。3
请注意,页面缓存是重要的优化来源,但也可能成为危险的来源。如果对页面缓存的写入未刷新到磁盘,并且发生电源、磁盘或内核故障,您将丢失数据。在分析专门利用页面缓存进行持久性操作的数据库解决方案时,请注意这一点。
数据库有数十种分类。数百个商业或免费提供的数据库系统中的每一个都可能属于其中的几个类别。本文跳过分类,而是提供一个框架,通过该框架,可以通过其特性来评估每个数据库。
本文探讨的五个特性类别是:数据模型、API、事务、持久性和索引。
数据模型基本上有三种类别:关系型、键值型和层次型。大多数数据库系统都明确属于其中一个阵营,但可能会提供其他两个类别的特性。
关系模型。 关系型数据库在近代历史上广受欢迎。在 80 年代和 90 年代,数据库的主要要求是节省稀缺且昂贵的资源:硬盘。这是关系型数据库的优势所在。它们允许数据库设计人员通过称为规范化的过程来最大限度地减少数据库内的数据重复。4
然而,最近,磁盘存储的成本已大幅下降,5使得关系型数据库的经济优势不再那么重要。尽管如此,由于其灵活性和易于理解的模型,它们在今天仍然被广泛使用。此外,SQL 作为关系型数据库的通用语言,在程序员中也很普及。
关系型数据库的工作原理是允许创建任意表,这些表将数据组织成列的集合。表的每一行都包含来自每一列的字段。习惯上将数据组织成逻辑上独立的表,然后将这些表相互关联。这允许独立修改更大整体的组成部分。
关系型数据库的一个主要缺点是它们的存储模型不太适合存储或检索大量数据。针对关系表的查询操作通常需要访问多个索引,并连接和排序来自多个表的结果向量。这些复杂的方案对于 1 GB 的数据效果很好,但对于 1 TB 的数据效果不佳。
关系型数据库所做的根本权衡是节省磁盘空间,但代价是更高的 CPU 和磁盘负载。
这种模型的优点很多:它使用最少的磁盘空间;它是一个易于理解的模型和查询语言;它可以支持各种各样的用例;它具有模式强制的数据一致性。
这种模型的缺点是它通常是最慢的;它的模式意味着程序员在迭代更改时需要更高的开销;并且它具有高度的复杂性,有许多调整旋钮。
键值模型。 键值存储从持久存储的早期就已存在。当不需要关系系统的复杂性和开销时,就会使用它们。由于其简单性、高效的存储模型和低运行时开销,它们通常可以比关系型数据库每秒管理多个数量级的操作。最近,它们被用作事件日志收集器。此外,由于其简单性,它们通常作为内部数据存储嵌入到应用程序中。
键值存储通过将键(通常是一块字节)与值(通常是另一块字节)关联来操作。此外,由于记录的大小通常是同质的并且具有重复的数据,因此可以在存储到磁盘之前对其进行大量压缩。这可以大大减少 SATA 总线所需的带宽,从而提供性能提升。
通过巧妙的行和列创建,甚至模式应用,一些键值存储可以提供关系特性的子集,但它们通常提供的用于数据建模的特性远少于关系系统。如果需要多个索引,则通过使用额外的键值查找来模拟它们。
这是一种快速、相当灵活且易于理解的存储模型;但是,它通常没有模式支持,因此没有一致性检查,并且其应用程序逻辑更复杂。
层次模型。 层次或文档数据模型最近才流行起来。它的主要优点是人体工程学。数据以其在应用程序的对象中存储的方式存储和检索自数据库。
层次模型倾向于将所有相关数据存储在单个记录中,该记录具有多个键和值的界定,其中值可能是键和值的其他关联。
在一般情况下,真实世界对象的所有数据都可以在单个记录中找到。这意味着此模型必然会比关系模型使用更多的存储空间,因为它正在复制数据而不是引用数据。它还简化了查询模型,因为只需要从单个表中检索单个记录。
由于存储的数据本质上是异构的,因此压缩可以提供的收益有限,并且通常不使用。
层次数据库通常提供一些关系特性,例如外键引用和多个索引。许多此类数据库不提供任何模式支持,因为数据结构是任意的。
这是最灵活的模型。其任意索引支持轻松访问数据,并且它在应用程序数据结构和磁盘数据结构之间具有最高的保真度。
缺点是,此模型具有最高的磁盘空间使用率,并且在没有模式的情况下,数据布局是任意的,因此没有模式或一致性检查。
API,即应用程序编程接口的缩写,简而言之,就是您和您的程序如何与数据库交互。接口可以从许多不同的维度进行划分,但让我们从两个开始
如果数据库与客户端应用程序在同一进程中(至少部分地)运行,那么通常会有一个函数调用库,该库直接调用数据库引擎中的方法。这种紧密耦合导致尽可能低的延迟和尽可能高的带宽(内存)。然而,它降低了灵活性,因为它意味着一次只有一个客户端应用程序可以访问数据。它还带来额外的风险:如果客户端应用程序崩溃,数据库也会崩溃,因为它们共享同一个进程。
如果数据库在单独的进程中运行,则通常使用基于 TCP/IP 的协议。许多 RDBMS(关系数据库管理系统),以及最近的其他类型的数据库,都支持 ODBC(开放数据库连接)或 JDBC(Java 数据库连接)协议。这简化了客户端应用程序的创建,因为可以利用这些协议的库非常丰富。网络协议确实极大地提高了数据库的灵活性,但与直接内存访问相比,TCP 带来了延迟和带宽损失。
SQL 是一种声明性语言,最初设计为简化关系数据存储和检索的机制。它无处不在,因此,许多开发人员都能流利地使用该语言。这可以帮助数据库的采用。
大多数 NoSQL 数据库吹捧的最大“创新”仅仅是通过删除事务和关系表来实现更快的操作。许多这些数据库开始支持 SQL 作为 API 语言,即使它们没有使用其关系特性。一些 SQL 特性(如查询、过滤和聚合)非常有用。因此,有人说 NoSQL 数据库应该重命名为 NoACID(原子性、一致性、隔离性和持久性),因为它们缺乏事务支持。在 2014 年,许多相同的数据库现在都具有事务支持。如今,NoSQL 可能更准确地称为 NoRelational,但 NoSQL 听起来更好,也足够接近。
SQL 的一个挑战是它必须由数据库引擎解析和编译才能使用。这会带来运行时开销。大多数数据库引擎和客户端 API 通过预编译或在第一次运行时将基于 SQL 的函数调用编译成预处理语句来解决这个问题。然后,保存编译后的版本并用于将来的调用。
SQL 不能有效地描述所有数据关系。例如,层次关系很难在 SQL 中描述。此外,由于 SQL 的声明性,迭代或其他命令式操作无法在核心 SQL 规范中描述。该规范已扩展为包含递归,以解决迭代和层次关系。此外,供应商还提供了他们自己的非标准扩展。然而,对这些扩展的支持并不广泛,对如何利用它们的理解也不广泛。6
在许多情况下,数据库的特性非常稀疏,缺乏索引或聚合等特性,因此根本没有理由支持 SQL 解析和执行引擎的复杂性。键值存储通常属于此类。
根据定义,数据库事务是以连贯且可靠的方式处理的工作单元。最常见的数据库事务方案是 ACID。
许多数据库系统声称支持事务或“轻量级”事务,但它们可能仅提供 ACID 中方便且高效支持的特性。例如,许多分布式数据库提供事务的概念,但没有隔离步骤。这意味着数据正在原地修改,并且其他事务在数据被修改时会看到该数据。如果预期会发生这种情况,您可以解决此问题。否则,结果可能是灾难性的。
让我们简要了解一下 ACID 保证,以及数据库可能为提供这些保证所做的事情。
原子性。 在一个事务中,可能存在多个操作。原子性保证所有操作要么一起成功,要么一起失败。操作可能会因多种原因而失败
• 约束。违反了逻辑约束,例如外键或唯一性。
• 并发。另一个进程完成了对您的进程将要修改的字段的修改,并且继续这样做将违反另一个事务的原子性保证。
• 失败。硬件或软件堆栈中的某些东西发生故障,导致其中一个操作失败。
在繁忙的并发数据库中,故障可能经常发生。如果没有原子性,数据会很快进入不一致的状态。因此,原子性是 ACID 的下一个属性的关键组成部分。
一致性。 此保证意味着在事务处理之前、处理期间和处理之后,数据库的状态对于所有用户都是有效的。数据库可能会对数据本身做出某些保证。诸如可串行化之类的基本保证意味着所有操作将按照它们的应用顺序进行处理。这听起来可能很容易,但是当许多具有许多线程的应用程序同时在系统上运行时,必须采取(昂贵的)步骤来确保这是可能的。
关系型数据库通常会做出更大范围的一致性保证,包括外键约束、对依赖类型的级联操作或可能作为此操作的一部分执行的触发器。就性能而言,这意味着所有这些操作都可能在行和/或页面被锁定以进行编辑时运行,因此在此期间,没有其他客户端能够使用系统的这些部分。它也清楚地影响了请求的往返时间。
隔离性。 事务不会立即发生。它们分步骤发生,并且,如原子性示例所示,如果外部人员看到已完成步骤的一部分,则结果将从“有趣”到“非常糟糕”不等。隔离性是保证这不会发生的保证。它在事务成功完成之前,对其他人隐藏所有操作。
持久性。 持久性确实是一个重要的特性,它简单地承诺,当事务完成时,操作结果将成功持久保存在指定的存储介质(通常是硬盘)上。
ACID 事务通常有六个步骤
1. 将传入的请求记录到持久存储中的事务日志(也称为预写日志)。这将保护数据以防系统故障。在最坏的情况下,此事务将能够在启动时从日志中重新启动。
2. 以不干扰现有操作的方式将新值序列化到索引和表数据结构中。
3. 获取需要修改的所有单元格上的写锁。根据所讨论的操作和数据库,这可能意味着锁定整个表、行或可能的内存页。
4. 将新值移动到位。
5. 将所有更改刷新到磁盘。
6. 在事务日志中记录事务已完成。
事务具有性能影响。与零散地执行操作相比,它们可以提高速度,因为所有磁盘操作都批量处理成一组操作。此外,如果是 ACID,事务是一种并发控制形式。由于它们位于数据本身,因此它们通常比应用程序中自定义构建的并发解决方案更有效。
缺点是,事务不适用于高度并发的应用程序。高度争用的操作将生成过多的重放和中止(这会导致更多的重放)。它们也很复杂——提供事务所需的所有移动部件都会增加更大且更难维护的代码库。
正如之前在此处所述,事务甚至索引在数据库中都是完全可选的。然而,持久性是它们存在的理由。
与磁盘相关的性能成本(以及与页面缓存相关的数据丢失风险)意味着在如何存储和检索数据方面需要权衡。大量高度专业化的数据结构是为不同的访问模型量身定制的,通常,如果一个数据结构在一个领域表现出色,那么它在另一个领域将表现不佳。以顺序方式插入大量传入事件的方案可能不会为随机更新提供出色的性能(或者可能甚至根本不提供该功能)。
在所有可能的存储和检索数据方案中,最广泛的四个类别是:基于行、基于列、仅内存和分布式。
基于行 最常见的存储方案是在本地硬盘上的树或其他紧凑数据结构中逐行存储数据。尽管确切的数据结构和访问模型各不相同,但这种机制相当通用。
在基于行的存储中,行本身在内存中是连续的。这通常意味着存储模型本身针对一次性获取整个数据行区域进行了优化。
有两种常见的用于存储行的数据结构。B+ 树针对随机检索进行了优化,而 LSM(日志结构合并)树针对大容量顺序写入进行了优化。
B+ 树。 B+ 树是一种 B 树风格的索引数据结构,经过优化,您猜对了,可以最大限度地减少磁盘寻道。它是数据库中用于表存储的最常见的存储机制之一。它也是几乎所有现代文件系统的首选数据结构。B+ 树通常是具有高分支因子的搜索树,每个节点都是一个连续的内存块,其中包含多个键。这专门用于最大化仅从磁盘检索一次数据即可比较多个键的概率。7
图 1 显示了基于 B 树的行存储在内存中的布局方式。每个叶节点都有空间容纳四个键,从而减少了每行需要执行的磁盘查找次数。树中的键指向磁盘或内存中的一个区域,该区域存储按列顺序排列的行。另请注意,在每个节点中,并非每个单元格都需要填充;它们可以保持空闲以供将来的值使用。
日志结构。 LSM 树是一种较新的磁盘存储结构,针对大容量顺序写入进行了优化。它旨在处理大量流式事件,例如实时接收 Web 服务器访问日志以供后续分析。
尽管 LSM 树起源于日志风格的事件收集,但它也开始在关系型数据库中使用。然而,它有一个主要的权衡,即您不能在标准数据路径中在 LSM 数据结构中删除或更新。删除和更新作为日志中的新记录记录。读取 LSM 树时,您通常从后往前读取最新版本的数据。
定期地,必须对由于后续删除或更新而过时的记录进行垃圾回收。这通常称为压缩过程。一些 LSM 系统在运行时在单独的线程中进行压缩;其他系统尝试就地增量压缩。8
基于列
基于列的数据存储针对检索同一列的数据区域(而不是数据行)进行了优化。因此,连续的列在内存中是连续存储的。
由于列中的所有数据类型必然相同,因此压缩可以产生巨大的积极影响,从而增加可以通过总线存储和检索的数据量。此外,将数据分成多个文件(每列一个文件)可以利用跨多个磁盘同时进行的并行读取和写入
基于列的数据库的缺点是它们通常不灵活。一个简单的插入或更新需要大量的协调和计算。由于数据通常在列中被紧密地打包(和压缩),因此不容易找到和就地更新数据。
为了帮助保持跨列文件的“行”同步,通常列字段还将包含主键(或行 ID,如果没有键)。这有助于将数据重新组装成行,但会降低存储和检索的效率。
图 2 显示了一个列式数据文件。每种数据类型都以其自己的连续区域布局,其偏移量在主列中指示。列文件通常分批构建和重建,以服务于用于海量数据集的数据仓库应用程序。
仅内存 在许多情况下,持久性根本不是必需的。这对于缓存等系统很常见,这些系统频繁更新,并且除了访问速度之外,没有其他优化。由于缓存中的数据通常是短期的,因此可能不需要持久保存到磁盘。这就是内存数据库的优势所在。在没有存储和从磁盘检索的要求的情况下,可以利用更多种类的复杂树。
分布式 分布式数据库的主题非常广泛,需要一系列文章才能进行适当的介绍。然而,在持久性的上下文中,有一个相关的事实:在数据中心内跨网络复制数据集比将其存储到本地磁盘上更快。
在建立速度和持久性之间的平衡时,分布式数据库可以提供一个有趣的选项。仅将数据存储在本地机器的内存中可能太冒险,因为如果机器崩溃,数据丢失将是完全的。如果您跨多台机器复制数据,那么您完全数据丢失的风险就会降低。由应用程序开发人员来确定机器故障的概率和可接受的风险水平。
当您选择存储到磁盘时,页面缓存很可能会参与其中。直接访问磁盘将过于繁琐,并且会妨碍系统上运行的任何其他应用程序的性能,因为您将不必要地垄断磁盘。
何时将页面缓存刷新到磁盘可能是设计数据库时最重要的一个问题,因为它确切地告诉您数据丢失的风险有多大。
许多数据库声称每秒可以执行数千次操作。这些数据库通常完全在页面缓存中内存映射页面的数据结构上运行。这就是它们实现速度和吞吐量的方式——通过处理内存中的数据结构。它们通过将所有刷新和同步操作推迟到操作系统本身来做到这一点。这意味着由内核来决定何时应将缓存中的数据持久保存到磁盘。它可能会考虑的不仅是数据库,还有系统上运行的所有应用程序。这意味着数据的实际持久性留给了操作系统,而操作系统不了解应用程序域或数据可靠性要求。
如果持久性不是一个强烈的要求,那么推迟到操作系统可能没问题。但在大多数情况下,明确数据库在页面缓存方面的行为非常重要。
对于自动同步的系统
• 如果刷新频率过高,则性能会很差。
• 如果刷新频率过低,则速度会更快,但存在数据丢失的风险。
更好的方法可能是为数据库利用手动同步方案,因为这将提供控制,以匹配应用程序所需的保证。这增加了应用程序的复杂性。对于高度并发的系统,难度级别会增加,因为服务于一个应用程序的磁盘操作可能会过度干扰另一个应用程序。
事务和批量操作等在结束时同步的系统可能是有益的。这将减少磁盘访问次数,但对于数据何时刷新到磁盘有一个非常明确的保证。
数据很少以孤立值的形式存储。它通常是由构成记录的异构字段集合组成。在关系数据库中,这些字段被称为列,并且它们被固定到定义表的模式。
在非关系数据库中,通常仍然会容纳甚至索引异构字段。当您想要通过指定记录中的某个字段来查找表时,该字段需要成为索引的一部分。索引只是一个用于执行随机查找的数据结构,给定指定的字段(或者,在支持的情况下,指定的字段元组)。
由于 B 树也是一种磁盘上的数据结构,因此它是大多数查找索引的首选工具,因为它有效地支持硬盘。与存储数据的 B+ 树不同,查找索引针对存储数据引用进行了优化。B 树可以有效地容纳插入操作,而无需为每个操作分配存储单元。它在结构上也往往是扁平的,减少了需要搜索的节点数量,从而减少了潜在的磁盘寻道次数。
然而,还有其他选择。例如,位图索引是一种数据结构,它可以为多个表的连接查询提供高效的支持。
树形索引的增长与索引中的项目数量呈线性关系,搜索时间的增长与树的深度呈对数关系(总深度的对数函数)。
另一方面,位图索引的增长与索引中不同项目的数量有关。顾名思义,它构建一个位图,表示所有相关列的值的成员资格。对位图索引执行多个布尔运算非常快速,并且它们生成新的位图,这些位图可以作为搜索结果有效地缓存。
位图索引的另一个主要创新之处在于它可以被压缩,甚至可以在压缩状态下执行查询操作。这使得存储检索速度更快。它还使位图索引更易于 CPU 缓存,这可以进一步减少延迟。由于其更复杂的更新过程,位图索引倾向于用于读取密集型系统,尤其是那些具有多维查询的系统,例如 OLAP(在线分析处理)立方体。
除非您的唯一数据访问模型是对大型数据区域进行全扫描,否则您可能需要索引。然而,您的数据集利用的每个额外索引都会增加磁盘和 CPU 负载,并增加插入操作的延迟。
如果您的系统是读取密集型的,并且列中数据种类相对较少(称为低基数),则可以利用位图索引。对于其他所有情况,可以使用树形索引。
许多索引需要一个唯一的键来指向记录。如果它是该记录的唯一唯一索引,则称为主键。即使是无模式数据库也经常支持这种索引约束。它可以帮助确保数据一致性,并在加载数据时检测错误。
为了获得性能,有一个基本规则要遵循:尽可能少地索引。几乎每个支持添加索引的数据库都允许您在数据加载后添加索引。因此,请稍后添加它们,一旦您确定需要它们。使用唯一索引可以提供确保数据一致性的双重好处。
如果您的所有数据都是一次性加载的(可能在数据 mart 模型中),那么您可能会从稍后创建索引中获益。这甚至可以产生更高效的索引,因为许多索引会受到由大量插入和更新引起的碎片化的负面影响。
性能和安全性之间的权衡围绕着磁盘展开。如果您选择专门为您的访问模型构建的数据库,您可能会获得两全其美的效果。花时间彻底了解您的访问模型,并了解您需要哪些功能以及为了性能您愿意放弃哪些功能。
如果您不需要保证每次操作的即时持久性,您可以通过利用内存映射的数据结构来延迟将操作持久化到磁盘。了解任何时候您依赖内存来加速操作,都存在数据丢失的风险。如果发生故障,那些待处理的写入操作可能会消失。
无论您的应用程序如何,都要花时间了解您操作系统中的页面缓存。您认为安全的写入操作可能并不安全。缓存也有许多设置用于微调性能。它可以设置为高度谨慎但繁忙,或者无忧无虑且快速。您应该非常清楚您的数据库何时以及如何写入磁盘。如果它遵从操作系统,那么请采取步骤确保它在您的用例中行为正确。
验证您的期望是否与现实相符是值得的。它可能仅仅可以拯救您的数据。
1. LGA; http://en.wikipedia.org/wiki/LGA_2011。
2. 延迟数字; http://www.eecs.berkeley.edu/~rcs/research/interactive_latency.html。
3. 页面缓存; http://www.westnet.com/~gsmith/content/linux-pdflush.htm。
4. 规范化; http://en.wikipedia.org/wiki/Database_normalization。
5. 硬盘成本; http://www.mkomo.com/cost-per-gigabyte-update。
6. SQL; http://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL。
7. B 树; http://www.scholarpedia.org/article/B-tree_and_UB-tree。
8. LSM 树; http://dl.acm.org/citation.cfm?id=230826; 和 http://www.eecs.harvard.edu/~margo/cs165/papers/gp-lsm.pdf。
喜欢或讨厌?请告诉我们
Rick Richardson 是 12Sided Technology 的系统架构师,他在那里帮助重塑市场结构,并为金融界打造下一代交易系统。他的热情在于大规模分布式系统和数据库。他坚信,我们可以通过数据素养让世界变得更美好。
© 2014 1542-7730/14/1100 $10.00
最初发表于 Queue vol. 12, no. 11—
在 数字图书馆 中评论这篇文章
Qian Li, Peter Kraft - 事务和无服务器天生一对
数据库支持的应用程序是无服务器计算令人兴奋的新领域。通过紧密集成应用程序执行和数据管理,事务性无服务器平台实现了许多在现有无服务器平台或基于服务器的部署中不可能实现的新功能。
Pat Helland - 身份的各种名称
新兴的系统和协议都收紧和放松了我们对身份的概念,这很好!它们使完成工作更容易。REST、物联网、大数据和机器学习都围绕着有意保持灵活,有时甚至模棱两可的身份概念。身份概念是我们分布式系统的基本机制的基础,包括互换性、幂等性和不变性。
Raymond Blum, Betsy Beyer - 实现数字永恒
当今的信息时代正在为世界所依赖的数据创造新的用途和新的管理方式。世界正在从熟悉的物理文物转向更接近信息本质的新型表示方式。我们需要流程来确保知识的完整性和可访问性,以保证历史将被了解和真实。
Graham Cormode - 数据速写
您是否曾经感到被源源不断的信息流淹没?似乎大量的新电子邮件和短信需要持续关注,还有电话要接听、文章要阅读、敲门声要回应。将这些碎片拼凑在一起以跟踪重要内容可能是一个真正的挑战。为了应对这一挑战,流数据处理模型越来越受欢迎。其目的不再是捕获、存储和索引每一分钟的事件,而是快速处理每个观察结果,以便创建当前状态的摘要。