十有八九,您从来没有考虑过生成您自己的数据库需要什么。你可能永远不会发现自己处于需要做这类事情的情况。
但是,如果只是作为一种思想练习,请考虑一下这个问题:如果作为一个核心业务需求,您发现需要提供从断开连接的操作捕获数据的功能,以便不同方可以在同一时间(或在重叠时间)进行更新而不发生冲突,该怎么办?如果您的服务要求您几乎一整天都在接收大量的数据,以至于您真的无法在任何时候中断数据摄取,因为担心发现自己已经远远落后于当前状态,几乎没有办法赶上呢?考虑到这一切,有没有商业上可用的数据库可以用来满足这些要求?
正确的。那你会怎样呢?那你会怎么做?我们想要探索这些问题西奥Schlossnagle事实上,他建立了自己的时间序列数据库。作为Circonus的创始人和首席技术官,Schlossnagle有充分的理由进行这项投资。Circonus是一家对数量庞大且呈指数增长的物联网设备进行遥测分析的机构。
贾斯汀SheehyAkamai全球性能和运营首席架构师向Schlossnagle询问了这一努力背后的想法,以及在构建数据库过程中所做的一些关键决策,以及在这一过程中学习到了什么。我谨代表ACM,克里斯McCubbin他是亚马逊网络服务的高级应用科学家,参与了讨论。
贾斯汀SHEEHY:作为曾经做过编写自己的数据库的可疑决定的人,我知道这一点可以被证明是正确的做法,但对大多数公司来说,我认为事实并非如此。这不仅仅是一个商业问题,它还包含了一些有趣的工程层面。西奥,你为什么觉得有必要自己编写时间序列数据库?
西奥SCHLOSSNAGLE:原因有很多。首先,随着时间的推移,几乎所有流入我们遥测分析平台的数据都是以数字的形式出现的。我们见证了数据量和广度的指数级增长。事实上,根据我们的估计,我们已经看到了大约1x10倍的增长12在过去的十年里。显然,计算平台并没有跟上这一趋势。储存成本也没有下降1 × 10倍12.也就是说,我们所经历的数据增长速度已经远远超出了存储和分析所有数据所需的经济现实。
所以,我们决定创建自己的数据库的主要原因与简单的经济有关。基本上,到最后,除了钱,你可以解决任何问题。似乎通过限制问题空间,我们可以得到一个更便宜、更快的解决方案,随着时间的推移,最终会更容易维护。
SHEEHY:你考虑过开源数据库吗?如果是这样,你是否找到了一些看起来几乎足以满足你的目的,但却因为一些有趣的原因而拒绝了它们?另外,我很好奇你在四处寻找时是否发现了什么有趣的创新,或者,就此而言,有什么是你真正想要避免的?
SCHLOSSNAGLE:我深受DynamoDB和Cassandra以及Riak等其他一致哈希数据库的影响。尽管我发现这些设计很鼓舞人心,但我也非常沮丧,因为它们的一致哈希方法往往会限制您对受约束数据集的操作。
我们想要的是一个看起来类似于一致哈希数据库(如DynamoDB或Riak或Cassandra)的拓扑,但我们还想做一些小的调整,我们希望所有的数据类型都是crdt(无冲突复制数据类型)。我们最终建立了一个crdt专用数据库。这从根本上改变了可能发生的事情,特别是在如何向数据库写入数据方面。
还有其他一些细微差别。首先,大多数一致的哈希系统在环中使用vBuckets的概念,例如,您有15个主机和64个虚拟桶,数据放在其中,主机最终协商确定谁拥有哪个桶。
在我们的系统中,我们希望消除这种总体粒度。我们实际上使用SHA-256作为我们的哈希方案,我们使用2256vBuckets。因此,每个数据点的位置由节点和环的位置决定,而不是由vBucket的所有权决定。
这使我们能够进入我们所说的“双面环”。在一个典型的一致哈希环中,您有一组主机,每个主机在环周围都有多个表示。我们所做的是允许环被分成两半,环的前180度——环的第一个π——包含一半的节点,而另一个π包含剩余的节点。
然后,为了将数据分配给节点,我们使用了所谓的“跳过遍历”。基本上,这可以在环上来回翻转pi弧度,从而保证从环的一端交替到另一端,当将环的一半放到一个AZ(可用性区域)上,另一半放到另一个AZ上时——或者放到一个或另一个区域,或者放到一个或另一个云上——这是非常有利的。
THEO SCHLOSSNAGLE:有一种难以置信的强大动力,那就是建立时间序列数据库,用于永远在线的数据摄入,否则——在服务中断或灾难性故障的情况下——你会发现,在恢复服务时,你的状态将远远落后于当前,根本没有办法赶上。
使用crdds的一个有趣的方面——而不是需要一致同意才能取得进展——是它让你,比如说,把戒指的一半放在石油钻塔上,另一半放在Azure云上,然后只要VSAT(非常小孔径终端)链路正常工作,所有东西就能正确同步。这样你就可以拥有所有相同的特性和功能,即使它们是断开的。
SHEEHY:我还对crdt做了一些工作,发现它们很有趣,因为可以由多方(可能在多台计算机上、同时或在重叠的时间内)更新数据类型,而不存在冲突。由于更新是自动解析的,因此不需要传统数据库意义上的隔离来确保每次只有一方能够在给定的数据结构上执行事务。事实上,这可以任意发生,它仍然会被解决。
此外,有不同的方法来解决这个问题,无论是通过交换性还是收敛运算——记住,在过去十多年里,很多研究已经在这方面做了。因此,您可以获得一些共识的好处,而不必禁止多个方面在同一时间对同一数据采取行动。这就是为什么我认为这是一个令人兴奋的研究和实施领域。
CHRIS MCCUBBIN:这是如何应用到最适合时间序列数据库的数据类型和操作的呢?这是否是CRDT迄今为止的研究重点?
SCHLOSSNAGLE:到目前为止,大部分CRDT研究都集中在断开连接的操作上,当然,当您想到时间序列数据库时,首先想到的不是这一点。但CRDT方法的真正优势在于,如果您可以将整个操作集限制为CRDT,那么就可以放弃诸如Paxos、Multi-Paxos、Fast Paxos、Raft、Extended Virtual Synchrony等共识算法,以及其他类似的算法。这并不是在贬低这些算法。只是一旦实现了无需quorum就能取得进展的能力,它们就会带来许多不必要的负担。
这使得crdt对于时间序列数据库具有极大的吸引力,原因有很多。其一,大多数时间序列数据库——尤其是那些像我们的数据量这么大的数据库——从机器而不是人那里获取数据。连接这些机器的网络通常是广泛的,我将其描述为“始终处于运行状态”。这意味着,如果数据库的接收端出现了任何形式的服务中断,那么每停机一次,就会使恢复状态变得更加困难。
因此,如果出现停机,数据库中的quorum丢失了一个小时,那么在服务恢复后,我并不能够立即恢复。首先,我需要处理最后一个小时的数据,因为不管系统的可用性如何,数据库接收端的负担会随着时间的推移不断累积。也就是说,有一种难以置信的强大动力来建立时刻在线的数据摄取的时间序列数据库,因为否则——在服务中断或灾难性故障的情况下——您将发现,在恢复服务时,您的状态将远远落后于当前,根本没有办法赶上。
SHEEHY:这听起来像是,出于深思熟虑的原因,你用一个非常困难的问题换了另一个——我的意思是你从与共识算法相关的问题中走出来了。然而,我了解到,许多所谓的CRDT实现实际上并没有达到这个计费标准。我很好奇,您是如何确信您的数据结构实现真正符合crdt的标准的。
SCHLOSSNAGLE:很多crdt确实很复杂,特别是在它们代表某种复杂的相互关联状态的情况下。一个经典的例子是用于文档编辑、字符串插入之类的crdt。但绝大多数机器生成的数据都属于“只写一次、从不删除、从不更新、只追加”的类型。这是幂等事务产生的数据类型,当设备测量某个特定时间点的东西是什么样子时,就会发生幂等事务。正是机器生成数据中的幂等性元素,让它真正适合于使用简单的crdt。
在我们的例子中,冲突解决是主要目标,因为对于时间序列数据,只能有一个测量值对应于来自特定传感器的特定时间戳。为了确保这一点,我们使用了一个非常简单的体系结构,以确保任何度量的最大绝对值将胜出。如果由于某种原因,一个设备在同一时间点为我们提供两个样本,我们的系统将收敛于最大的绝对值。我们也有一个代计数器,我们在乐队外使用。这一切只是为了提供简单的冲突解决方案。
说了这么多,在一年的时间里,当我们可能有一百万万亿的样本输入时,我们通常不会有任何需要解决冲突的实例,因为这不是机器生成的数据类型。
正如所料,Schlossnagle和他的团队在设计和开发时间序列数据库时并不是从零开始的。相反,他们关注的是可以使用哪些框架,以及可以从哪些库中借鉴。
首先,他们决定了什么是最关键的,以及他们愿意做出什么样的权衡。例如,他们知道他们需要将向前和向后兼容性作为基本需求,因为他们不能承担任何干扰数据摄取的后果。
他们也明白,将数据写入原始设备的实际问题是最难解决的问题之一。因此,他们设计了他们的数据库,只有少数地方,它真正写入磁盘本身。相反,它利用了许多现有的嵌入式数据库技术,系统内的优化路径已经设计好,以利用每一种数据库技术,同时还可以解决它们各自的弱点。
SHEEHY:很明显,您将crdt视为解决最重要的设计约束之一的一种方法:需要提供始终在线的数据摄取。系统上是否还有其他限制因素影响了您的设计?
SCHLOSSNAGLE:我们已经了解到,无论何时,当您有一个跨多个集群运行的系统时,您都不希望有某些节点比其他节点更关键,因为这可能导致操作问题。这里的一个经典问题是Hadoop基础设施中的NameNodes,或者基本上是任何类型的特殊元数据节点,这些节点需要比所有其他节点都更可用。这是我们想要避免的事情,如果只是为了消除单点失败的话。这对我们的设计有很大的启发。
此外,虽然我们关注的是规模经济,因为我们接收了大量的遥测数据,但我想说的是,我们早期没有考虑到的一个挑战是,我们以后如何在所有数据中找到东西。也就是说,如果一年中有一百万万亿的样本进入你的系统,你怎么能从中找到一些东西呢?你怎么才能浏览所有的数据呢?
例如,在物联网领域,如果从100亿个传感器接收测量数据,那么如何通过跨分布式系统的元数据搜索将从某些传感器获得的数据隔离开来?我不认为这通常会构成一个特别困难的计算挑战,但因为这不是我们预先设计的东西,它肯定会在我们的实现过程中带来很多痛苦和折磨。
SHEEHY:你很少听到人们谈论他们如何需要改变他们的方法,这是基于他们所了解到的与他们最初的假设不一致的东西,或者暴露了一些没有被提供的东西——就像你在这里谈论的东西。如果我理解正确的话,您最初没有对一些您认为不那么重要的数据进行探索性查询,后来才意识到它实际上很重要。
SCHLOSSNAGLE:这是一个公平的描述。更具体地说,让我们这么说吧,对于任何基于遥测的时间序列系统,你都将有一串测量值连接到某个传感器上。假设您正在测量服务器上的CPU使用情况。在这种情况下,您将有一个与某些度量相链接的CPU的惟一标识符——是否每秒钟、每分钟或每十分之一秒进行一次,这些度量表示该CPU的实际使用情况。
我们发现,在一个系统中可以有多达1亿甚至10亿这样的字符串,这意味着很难找到一个特定的字符串并探索它。作为一个独立的计算机科学问题,这并不难解决。
使问题复杂化的是,围绕这些字符串的元数据会随着时间不断变化。一个很好的例子与容器技术有关。假设您将cpu使用数据附加到在Kubernetes下运行的容器上,然后决定在一年的时间内每天启动40次。这意味着,在你之前拥有1亿次流的地方,你现在拥有14600倍的流量(365天× 40次发行)——所以,你将面临真正的基数挑战。
SHEEHY:考虑到您的系统一直在运行,一直在接收,而且显然需要保护为客户存储的所有数据,我很好奇您是如何处理版本升级的。当你计划改变系统中根深蒂固的设计元素时,你不可能指望重新启动。我自己也处理过几次这个问题,所以我知道它会在多大程度上影响您的工程选择。
SCHLOSSNAGLE:我认为您将在整个数据库计算中发现许多相似之处。在我们的例子中,因为我们知道完美向前兼容的挑战,我们试图确保版本之间的每次升级都尽可能无缝,这样我们就不需要重新构建整个系统。但更重要的是,我们真的不能承担任何摄入时的服务中断,这意味着我们需要将向前和向后兼容性作为绝对的基本要求。当然,对于任何存储大量数据并拥有广泛用户基础的数据库,您也可以这么说。
Postgres是一个很好的数据库例子,它在这个问题上遇到了很大的挑战,即无论何时为一个30TB的数据库更改磁盘上的表格式,您都可以指望出现某种程度的长时间停机,除非您可以通过复制之类的事情执行一些重要的魔法。尽管如此,我认为Postgres在过去的几年里已经在这方面做得更好了,因为它已经开始意识到数据库会变得多么庞大,以及当人们做出破坏前向兼容性的更改时,这些中断会持续多长时间。
SHEEHY:你需要担心的不仅仅是向前和向后兼容性的存储。这些问题同样适用于系统中运行的所有节点,因为您不能让所有节点在完全相同的时间更改版本。此外,根据我的经验,从工程角度来看,兼容性问题被证明是相当困难的,因为你或多或少一直生活在它之中,而不仅仅是当你需要升级你的存储时。
SCHLOSSNAGLE:这绝不仅仅是关于磁盘格式和功能。协议兼容性也需要考虑在内,特别是关于复制和查询之类的事情。有一些框架,如谷歌Protobuf[协议缓冲区]和gRPC,包括一些改进,提供了这一点。我们使用FlatBuffers,具有讽刺意味的是,它也恰好来自谷歌。所有这些框架都有助于保证未来的兼容性。因此,您可以序列化数据并添加新字段,但长期从业的人仍然能够在不了解所有这些新字段的情况下读取数据。因此,新的用户将能够读取旧数据,即使它缺少这些字段。这无疑有助于减轻许多实现方面的问题。但是设计上的顾虑仍然存在,所以我认为你需要用这种方式来处理它。事实上,我很想了解目前行业中出现的解决如何设计这种向前兼容性挑战的最佳实践。
我的另一个保留意见是,尽管这些框架提供了所有的优势,但它们往往是特定于语言的。如果有一种工具可以在Erlang中发挥良好效果,那么它不太可能对任何在Go中工作的人有多大帮助,就像为Rust编写的工具不一定对必须在C环境中工作的人有多大帮助一样。当您考虑到有很多常用的生产系统语言时,就很容易看出这是如何使事情变得相当棘手的。
SHEEHY:我完全同意,但让我们回到到底是什么推动了你的时间序列数据库。我特别想知道你利用了哪些既存的东西。我们已经讨论了一些关于FlatBuffers的内容,但是我想还有一些其他的软件,甚至硬件,您可以利用它们。
SCHLOSSNAGLE:首先我要说的是,FlatBuffers提供了一个特别好的例子,因为它为序列化和反序列化提供了一个现成的解决方案的重用,这对任何工程师来说都是最不令人感兴趣的任务之一。然而,更重要的是,通过提供一个很好的工具包,FlatBuffers还为网络提供了重要的向后兼容性和端部保证,这是无价的。这也适用于Protobuf和Cap'n Proto。
不过,我要说的是,我们并不是同样迷恋每一个框架。特别是Avro和Thrift,由于它们公然坚持忽略无符号类型,已被证明在实践中非常难以使用。我们最终决定只关注那些真正理解常见系统类型的序列化/反序列化解决方案。
除此之外,我们还依赖于大量的库。事实上,我们使用的大多数数据结构都来自开源库。Concurrency Kit是一个很好的例子,它提供了一组基本的数据结构和原语,这确实有助于生成基于非参与者的、高并发性和高性能的系统。
然后是在磁盘上存储数据的问题,这总是一个有趣的挑战。人们说永远不应该编写自己的数据库的一个原因是,在向磁盘写入数据时,很难确保数据是安全的,并且实际位于您认为的位置。我们设计了我们的系统,这样我们自己就只有几个地方可以写入磁盘。在大多数其他地方,我们依赖现有的嵌入式数据库系统,随着时间的推移,我们已经学会尽可能地使其可插入。今天我们一共使用了四种内部嵌入式数据库技术,其中最流行的两种是LMDB(闪电内存映射数据库)和RocksDB (Facebook上的LevelDB的衍生版本)。
SHEEHY:当您提到将数据直接存储在磁盘上时,我想到了所有已经说过的关于位于文件系统顶部的常见选择如何带来许多冲突,这些冲突可能会妨碍您正确地设计数据库。但是,我知道您有意识地决定使用一种特定类型的文件系统技术。是什么促使你做出了这样的选择?你现在是什么感觉?
SCHLOSSNAGLE:当您在文件系统之上操作时,肯定会付出性能损失。其中大部分与运行数据库时没有帮助的包袱有关。尽管如此,在将数据写入原始设备时,仍然有一些重要的数据完整性问题需要解决。底线是:我可以向原始设备写入内容。我可以在那里同步。我可以再读一遍,确保它是正确的。但当我回头看它的时候,它就不再是正确的了。Bit rot是真实存在的,特别是在处理大规模系统时。如果您要写入1艾字节的数据,我可以保证它不会全部返回。有一些问题是关于你如何处理的。
我们选择使用ZFS实际上是为了及时地交付价值。也就是说,ZFS为我们提供了可增长的存储卷;在操作过程中无缝添加更多磁盘的能力;内置的压缩;快照保护的一些安全保证;校验和检查;以及数据自动恢复的规定。能够一次性获得所有这些信息,因此值得付出使用文件系统的性能代价。
另一方面,当然,无论如何,我们必须自己建造大部分。我们可以通过构建它来获得更好的性能吗?可能吧,因为我们可以省去很多不必要的负担,比如Posix的遵从性,这正是ZFS所提供的。但这可能也需要六七年的产品开发时间。相反,我们能够在一开始就得到我们需要的东西。这是以性能损失为代价的,而我们愿意为此付出代价。
SHEEHY:另一个需要考虑的问题是,ZFS在公众眼中有一段复杂的历史,许多人对它的法律地位有严重的怀疑,我相信你已经考虑到了这一点。在您决定使用ZFS时,您的客户是否遇到了困难?
SCHLOSSNAGLE:成功总是在舆论的法庭上被定义。所以,是的,我得说,ZFS的赌博从一开始就是一个冒险的提议。随着时间的推移,由于在Linux上采用了OpenZFS,它被证明是一个安全的市场选择。尽管如此,我有一种感觉,如果ZFS没有在Linux上很容易地可用,我们将需要重新平台,因为部署ZFS的普遍沉默。
2016年,考虑到我们的大多数客户部署在Linux上,我们就是否可以继续使用ZFS进行了一些严肃的讨论。我们坚持了很久,直到Linux上的OpenZFS出现并使我们的选择合法化。但有一段时间,我们几乎要放弃ZFS。
SHEEHY:我完全理解您的决定,但我仍然不明白您为什么选择采用四种嵌入式数据库技术。我假设它们不位于文件系统之上;而是让他们直接访问设备,对吧?
SCHLOSSNAGLE:不,我们的嵌入式数据库也位于ZFS之上。
SHEEHY:四种嵌入式数据库技术如何证明对您有用?
SCHLOSSNAGLE:从根本上说,答案是:单一的通用技术很少能完美地适合一个问题;总是有妥协。那么,我为什么会犹豫使用LMDB呢?事实证明,在一定范围内写入LMDB比写入日志文件末尾要慢得多,这就是像Rocks这样的LSM[日志结构合并]风格数据库的工作方式。但是,从像RocksDB这样的数据库中读取数据要比从像LMDB这样的B+树数据库中读取数据慢得多。在构建跨越多年数据价值并包含一系列访问模式和用户需求的大型数据库系统时,必须考虑到所有这些权衡和让步。
最终,我们选择优化系统中的各种路径,这样我们就可以利用每种数据库技术的优点,同时克服它们的缺点。例如,正如你所想象的,我们将所有来自外部的数据写入LSM架构(RocksDB)中,因为这不会给我们带来任何固有的性能限制。您只需将数据写入一个文件,并且,只要您能足够快地对数据进行排序,您就可以跟上。不过,考虑到这些数据库可能会随着时间的推移大幅增长,您需要密切关注这一点。我的意思是,如果你有一个30 tb的RocksDB数据库,你将处于一个痛苦的世界。
JUSTIN SHEEHY:无论何时,当你构建一个供他人使用的数据库时,你想让它的可配置性和可调性之间存在着矛盾。
我们有很多技巧来解决这个问题。其中许多都与数据的时间分割有关。我们将有一个Rocks数据库来表示本周的数据。然后,随着这周的结束,我们将打开一个新的数据库。除此之外,在前一周的数据库保持一段时间未修改之后,我们将ETL[提取、转换、加载]到LMDB中的另一种格式,以便更好地服务读取查询—即我们再保险优化它。
最后,我们用来处理ingest的Rocks数据库是一个键值存储,但是这些值以非常面向列的方式存储。我们还把所有这些都粘在一起,这样你就可以从写端读,偶尔也可以写到读端。最后,使用和混合这两种不同的技术使我们能够针对预期的工作负载进行优化。
考虑到Circonus系统需要处理和处理的数据量,优化非常关键。事实上,数据库包含数千个可调参数来实现这一点。然而,要充分利用这些功能,就需要对系统性能的所有方面都具有非凡的可见性。为此,Schlossnagle表示,HDR(高动态范围)对数线性量化直方图被用于随着时间的推移“跟踪一切”,甚至进行实验,以找出如何通过改变某些孤立的调优来优化性能。
但是,团队对系统的构建方式有任何遗憾吗?只是其中一部分。
SHEEHY:每当您构建一个供他人使用的数据库时,您希望如何使其具有可配置性或可调性之间存在矛盾。在这个范围的一端是选择使几乎每一个变量都尽可能为用户所访问。另一个极端是让所有东西都尽可能地交钥匙,这样所有东西都运行得很好,用户很难不小心弄坏东西。显然,光谱不是线性的,但张力是一样的。我很想知道你是怎么解决这个问题的。更重要的是,我想知道你在这个过程中学到了什么,以及你发现你需要做什么调整。
SCHLOSSNAGLE:我自己的经验,在这两方面都做过,表明没有正确的答案。不过,我要说的是,这种自动调优、自配置的软件总是能工作的概念几乎是一个白日梦,除非您的用例碰巧非常简单。即使您选择让每个配置参数或设置都是可调的,实际上也不可能使所有这些调优组合都是有效的。如果你不小心,你真的会毁了你的系统。
然而,我们可能在系统内部有5000到10000个可调参数,我们可以在线配置。事实上,其中绝大多数只是内部记录。通过Tier 2/Tier 3支持,我们能够调查系统,推测可能导致某些特定问题的原因,然后尝试对其进行热补丁。从那里得到的反馈然后通知从那时起软件的默认处理参数。
我们也有一些自我调整系统——主要围绕并发控制、节流、后退等类似的东西——它们或多或少只是测量使用模式,然后相应地进行自我调优。这些局限于那些我们有丰富的实际经验,以前见过模式,因此有必要构建合适的模型的情况。
SHEEHY:我不得不说拥有10000个杠杆似乎确实给了你一个很多的电力。但你的支持人员如何确定该碰哪一个呢?也就是说,你做了什么来提供实时检查功能,人们可以使用理解系统在运行的时候?
SCHLOSSNAGLE:这是我可以谈论很多的东西,因为我们技术中真正有趣的部分之一与我们对高清直方图的使用有关。我们有一个HDR对数线性量化直方图的开源实现,称为circllist,它既非常快,又节省内存。有了它的帮助,我们就能够跟踪每一个IOP(输入/输出操作)、数据库操作、队列中的时间和传递给系统中另一个核心所需的时间的功能边界的性能。这是我们用来追踪的东西一切包括每一个RocksDB或LMDBget ()
或put ()
.每一个延迟都以纳秒为单位进行跟踪。在一个小小的Web控制台中,我们可以查看这些直方图中的任何一个,并观察它们随时间的变化。此外,由于这碰巧是一个时间序列数据库,我们可以将该数据放回数据库中,并将我们的工具与它连接,以获得写入数值数据的99.9百分位延迟的时间序列图。
一旦捕获了您希望排除故障或优化的部件的性能特征,您就有了执行受控实验所需的东西,可以每次更改一个调优。这为您提供了一种方法,通过更改一个参数来收集直接反馈,然后跟踪它如何改变系统的性能,同时还可以在系统的其他部分中查找任何未预料到的回归。我应该补充一点,所有这些都是开源框架的一部分[https://github.com/circonus-labs/libmtev]。
SHEEHY:听起来这对你来说真的很有回报,整个事业带来了令人印象深刻的回报。但我想知道,如果你现在才开始建立你的时间序列数据库,你会用完全不同的方式来做什么吗?
SCHLOSSNAGLE:绝对的!我们会以不同的方式处理很多事情。我们在这里谈论的系统到现在已经有9年的历史了,所以从那时起我们引入了大量的创新,我们可以利用这些创新。另外,在“事后回顾是20/20”的标题下,我希望我选择了一些不同的数据结构,这些数据结构可以更好地从内存数据世界过渡到磁盘数据世界——特别是内存索引和内存缓存,在一定的容量下,您确实希望采用缓存风格的方法,但出于可用性原因,您也希望它位于磁盘上。
你真的想把它看作是半永久的。例如,考虑一下130g内存中的自适应基数索引。事实证明,制造一个130g的零件并非易事。如果我能让这些数据结构无缝地映射到磁盘上的数据结构,那就太好了。当然,这些数据结构在2011年几乎没有什么实际用途,因为如果没有NVMe(非易失性内存Express)等技术的支持,它们的速度会太慢。尽管如此,使这些数据结构独立于内存而指针不变将是一项非常好的投资。事实上,我们现在正处于这个阶段。
也许现在我要做的最大的改变——回顾我们的产品随着时间的推移出现的所有错误——是我不会用C和c++编写它。相反,如果当时拉斯特在,我就会用这个。用这种方式编写系统将是非常棒的,因为Rust通过引入内存的借用检查器和所有权模型,基本上成功地设计了导致软件错误的大多数问题。
但现在,我不得不说,船已经开了;在Rust上重新装备我们的平台和重新教育我们的团队将是一个棘手的问题。尽管如此,我仍然认为这是一个错失的机会,因为我认为基于rust的系统对于我们在过去几年遇到的许多用例会更好地为我们服务。
数字图书馆是由计算机协会出版的。版权所有©2021 ACM, Inc.
没有发现记录