原文链接:https://dzone.com/articles/forging-a-nosql-database
作者:Chris Balnave
RavenDB 已经存在了十多年,目前已被数千名客户使用,包括丰田和威瑞森等财富 500 强公司,但它并不总是一帆风顺。与任何其他软件一样,RavenDB 也经历了成长的痛苦,尤其是在该公司仅由少数开发人员组成的早期。
用户反馈在我们的发展中一直发挥着重要作用。 RavenDB 的许多功能都是应大众需求而添加的,我们的客户以我们无法想象的方式使用我们的软件,帮助我们发现了无数的错误。
即使是负面反馈也帮助我们成长。我们十分感谢我们的批评者,RavenDB 的许多弱点已经变成了优势。
数据备份和恢复功能
当 Octopus 切换到 RavenDB 时,反馈(2012 年)非常积极。他们唯一的抱怨是备份系统中的操作系统兼容性。该系统当时相当简陋,还有很大的改进空间。
备份现在以用户定义的时间间隔自动执行,并且无论操作系统如何都可以恢复。还有其他灾难恢复选项可以保护您的数据,我们稍后会介绍。
改进数据库可用性、文档和学习资源
Octopus 团队发现 RavenDB 非常固执己见,并且以神秘的方式工作。很容易出错,几乎没有指导或解释的方式,而且文档也很缺乏。更糟糕的是,大多数公司都没有 RavenDB 专家来处理出现的问题。
缺乏经验/专业知识对任何新技术都是一个挑战,与长期占主导地位的关系型数据库相比,NoSQL 数据库仍然(相对)新。解决方案是使软件直观,易于学习和使用。
在发布这些帖子时,我们并没有做好这方面的工作,而且保罗的批评并不是独一无二的。为了回应用户的反馈,我们全力以赴扭转局面。
我们创建了 RavenDB 工作室:一个 GUI,可让您监控数据库的所有方面并通过指向和单击来执行大多数功能。

我们添加了大量文档,目前有几名员工全职工作,添加和更新内容。我们的 CEO Oren Eini(也称为 Ayende)写了一整本(免费)书,名为 Inside RavenDB 4.0,它提供了对 RavenDB 及其底层设计理念的全面解释。我们还创建了一个训练营计划来帮助新用户入门,因此不乏优质的学习材料。
更新“默认安全”方法
Octopus 团队的大部分困惑和沮丧是由 RavenDB 的“默认安全”政策引起的。这是一种旨在防止开发人员用糟糕的代码“伤害自己”的设计理念。
每个会话的查询是有限的,结果集是有限的,虽然限制是合理的,但它们并没有表现出来。超出限制不会导致错误或通知用户:请求只会安静地失败。这导致代码在开发中的工作方式与在生产中的工作方式不同,没有明确的原因。
来自多个来源的负面反馈导致了对我们“默认安全”方法的审查。
结果集最初限制为 128 个,但现在不受限制。现在由用户负责编码并使用分页来保持结果集较小并避免性能损失。
每个会话的查询限制为 30 个,因为超过此数量,您实际上是在对自己执行 DOS 攻击。惰性请求允许您将多个调用合并为 1,因此要达到 30 将需要一些非常不寻常(或只是很糟糕)的代码。您现在可以针对那些不寻常的情况调整此限制(默认为 30)。
由于难以为索引保留内存,MapReduce 结果限制为每个映射项 15 个。此后,我们取消了该限制,但如果从单个文档中生成超过 1024 个结果,用户现在将收到性能通知。
简而言之,得益于用户的反馈,RavenDB 比以前少了很多固执己见,并且功能更符合用户的期望。
在讨论 Paul 的其他批评之前,我们需要解释自他发帖以来 RavenDB 所经历的最大根本性变化。
RavenDB 4.0:一个巨大的飞跃
客户在早期使用 RavenDB 时遇到的许多问题根本无法通过小补丁来解决。我们需要大规模更新来彻底检修 RavenDB 的核心系统,而 4.0 是我们的机会。
我们公司为 4.0 做了大量的准备工作:一年内开发人员的数量翻了一番,并且 80% 的代码库是从头开始重写的。
然后,RavenDB 蓬勃发展。

最后,我们可以实现用户期待已久的改进。
现在有了这个背景,让我们回到保罗和章鱼。上面列表中的最后一项与 Paul 关于 ESENT 相关的索引错误和性能不佳的评论有关。
数据库索引和 Voron 存储引擎
我们对 ESENT 也不满意,但我们坚持下去。它是易碎的、敏感的,只能在 Windows 上运行,不幸的是,它是所有 RavenDB 存储和索引的基础。
4.0 是我们取得突破的地方。我们从 .NET Framework 切换到 .NET Core 以超越 Windows,并引入了我们自己的定制数据存储引擎:Voron。
Voron 比 ESENT 更稳定可靠,并且针对我们的数据库模型进行了高度优化。它的引入导致速度增加了几个数量级。在这个理想的基础上重建索引,它成为了 RavenDB 的亮点之一。
澄清最终一致性
关于索引的主题;在他的文章“我会再次使用 RavenDB 吗?”中,Jeremy Miller 谈到了最终一致性的问题。每当数据发生变化时,在更新关联(现在是陈旧的)索引以与原始数据保持一致之前,都会有一个等待。如果您查询尚未更新的索引,您可能会收到过期信息。
在 RavenDB 中,必须针对索引执行查询。您无法查询原始数据。这条规则是出于性能考虑,因为查询索引要快得多,但是过时的索引呢?
我们实际上并没有让索引长时间保持陈旧(它们在 5 毫秒后更新),并且在大多数情况下,它们不会出现任何问题。然而,在一致性至关重要的情况下,RavenDB 有答案——您可以检查过时的读取或让查询等待索引更新。
虽然我们没有改变最终一致性的方法,但我们通过介绍性和学习材料使其更加清晰。
MapReduce 定制
在他的帖子“从 RavenDB 迁移到 Cassandra”中,Aaron Stannard 对 RavenDB 实现 MapReduce 的方式提出了质疑,提出了以下两个抱怨:
RavenDB 的 MapReduce 系统需要重新聚合,“这在低容量时效果很好,但以与数据增长相反的比例进行扩展。”
这有点令人困惑。 RavenDB 执行增量聚合并且从未需要重新聚合。因此,无论数据增长如何,性能都非常出色。
MapReduce 管道过于简单,这使他们无法执行更深入的自定义查询。
这种批评是有道理的,我们通过打开用户定制的大门来回应。现在,您可以轻松地将自己的代码添加到 RavenDB 的 map/reduce 管道,并让它为所欲为。
实际上,我们为整个 MapReduce 系统感到非常自豪,因此我们专门创建了一个完整的网络研讨会。
分片发生了什么?
Aaron 还对 RavenDB 的分片系统提出了一些非常有效的批评:
“Raven 的分片系统实际上更像是客户端级别的 hack,它将您的网络拓扑与您的数据结合起来,这是一个非常糟糕的设计选择…”
我们决定放弃对分片的客户端模拟,现在正努力在我们的下一个主要更新中引入真正的分片:6.0 版。
引入内存测试
Jeremy Miller 提出的另一个问题是 RavenDB 缺乏内存测试。当时,这是我们功能集中的一个缺口,我们填补了一个绰绰有余的解决方案。
与其他系统一样,RavenDB 现在为数据库测试提供了完全内存模式。它速度极快,您可以使用 1 行代码进行设置,并且可以将其用于 CI/CD 管道中的自动化测试。
与其他系统不同,内存版本的行为与您的数据库在生产中的行为相同,确保您的结果始终有效。
在 Microsoft 的实体框架文档中:

数据库高可用和容灾
在他的帖子“Octopus Deploy 3.0 的初步想法——从 RavenDB 回到 SQL Server”中,Ian Paullin 谈到了他的组织缺乏使用 RavenDB 的 HA/DR 解决方案。
这些都是严重的问题,我们相应地处理了它们。

正如注释所说,集群提供了很好的容错能力。他们没有提到的是,RavenDB 使集群非常易于设置和管理。
RavenDB 最好在至少 3 个节点的集群上运行,这样如果一个或两个节点发生故障,您的数据库仍将保持正常运行。自动复制和分配故障转移可保护您的数据,而负载平衡和并发读写等功能可提供显着的性能优势。
RavenDB 还使用散列来监视数据损坏。您可以更换受影响的硬盘并将数据库复制回该节点。
如果您没有将数据复制到另一个节点或进行备份,Voron 恢复工具仍然可以帮助您将其取回。
更多编程语言支持
在他的文章“关于 MongoDB 与传统 SQL 和 RavenDB 的思考”中,John Culviner 指出 RavenDB “存在错误和低于标准的 CLI/查询 API(除非您使用 C#)。”
这在当时是一个有效的批评。在开发早期,我们主要关注 C#,而对其他语言的支持则落后。
我们一直收到很多关于这个问题的反馈,我们一直在努力适应。在撰写本文时,我们有 C#、Java、Node.js、Python、Ruby 和 Go 的客户端。
后4.0时代
4.0 发布后,负面文章和评论更难找到。最重要的批评来自长期用户 Alex Klause 在他题为“RavenDB:两年的痛苦和欢乐”的帖子中。亚历克斯有很多好话要说,但也有一些批评夹杂其中。
他的第一个批评是缺乏文档和社区。 RavenDB 确实没有最大的社区,尽管自本文发表以来它已经显着增长。我们通过在我们的社区论坛上提供广泛的支持、通过向客户提供的支持包以及提供全面的文档和学习材料来抵消这一点。
下一个问题是不可原谅的(快速修复的)错误数量。
对 Alex 来说不幸的是,他在我们有史以来最大的一组更改之前不久就开始使用 RavenDB。在他使用 RavenDB (v3.5 - v4.2) 的那段时间里,一组旧的 bug 正在等待被压扁,只是在 4.0 中被一个等待被发现的全新的 bug 所取代。那是一段疯狂的时光,从那以后事情已经平静了很多。如今,错误已不常见。
分析 RavenDB
正如 Alex 所指出的,并且现在仍然如此,RavenDB 没有一个专用的分析器。相反,它现在有多个分析工具,您可以在工作室中找到和使用所有这些工具。

使用这些工具,您可以在我们直观且美观的 GUI 中监控和调试数据库操作的几乎所有方面。
Raven 查询语言 (RQL)
Oren 还解答了有关 RQL 的评论,对 RQL 的良好理解需要一个很好的解释,并且如前所述,我们当时缺乏学习资源。现在可以在奥伦的书中找到一个很好的解释。




