1.2. 为什么选择 CouchDB?¶
Apache CouchDB 是新一代数据库管理系统之一。本主题解释了为什么需要新的系统以及构建 CouchDB 的动机。
作为 CouchDB 开发人员,我们自然对使用 CouchDB 感到非常兴奋。在本主题中,我们将与您分享我们热情的理由。我们将向您展示 CouchDB 的无模式文档模型如何更适合常见应用程序,内置查询引擎如何成为使用和处理数据的强大方式,以及 CouchDB 的设计如何有利于模块化和可扩展性。
1.2.1. 放松¶
如果用一个词来形容 CouchDB,那就是“放松”。它是 CouchDB 官方标志的副标题,当您启动 CouchDB 时,您会看到
Apache CouchDB has started. Time to relax.
为什么放松很重要?过去五年,开发人员的生产力大约翻了一番。推动这一增长的主要原因是更强大、更易于使用的工具。以 Ruby on Rails 为例。它是一个极其复杂的框架,但很容易上手。Rails 的成功故事源于其核心设计理念,即易用性。这是 CouchDB 放松的一个原因:学习 CouchDB 并理解其核心概念对于大多数做过 Web 开发的人来说应该感觉很自然。而且它仍然很容易向非技术人员解释。
当有创意的人试图构建专门的解决方案时,不要妨碍他们,这本身就是一个核心功能,也是 CouchDB 努力做好的事情之一。我们发现现有的工具在开发或生产过程中过于繁琐,因此决定专注于使 CouchDB 易于使用,甚至令人愉悦。
CouchDB 用户放松的另一个领域是生产环境。如果您有一个正在运行的应用程序,CouchDB 会尽力避免给您带来麻烦。其内部架构具有容错性,故障发生在受控环境中,并得到优雅地处理。单个问题不会级联到整个服务器系统,而是隔离在单个请求中。
CouchDB 的核心概念简单(但功能强大)且易于理解。运维团队(如果您有团队;否则,就是您)不必担心随机行为和无法追踪的错误。如果出现任何问题,您可以轻松找出问题所在,但这种情况很少见。
CouchDB 还旨在优雅地处理不同的流量。例如,如果一个网站遇到流量突然激增,CouchDB 通常会吸收大量并发请求而不会崩溃。每个请求可能需要更多时间,但所有请求都会得到响应。当流量激增结束时,CouchDB 将恢复正常速度。
放松的第三个领域是扩展和缩减应用程序的基础硬件。这通常被称为扩展。CouchDB 对程序员施加了一组限制。乍一看,CouchDB 似乎很死板,但有些功能是故意省略的,原因很简单,如果 CouchDB 支持这些功能,它将允许程序员创建无法处理扩展或缩减的应用程序。
注意
CouchDB 不允许您做会给您带来麻烦的事情。这有时意味着您需要忘记在当前或过去工作中可能学到的最佳实践。
1.2.2. 一种不同的数据建模方式¶
我们相信 CouchDB 将彻底改变您构建基于文档的应用程序的方式。CouchDB 将直观的文档存储模型与强大的查询引擎相结合,其方式非常简单,您可能会忍不住问:“为什么以前没有人构建过这样的东西?”
Django 可能是为 Web 而构建的,但 CouchDB 是由 Web 构建的。我从未见过如此完全拥抱 HTTP 背后哲学的软件。CouchDB 使 Django 看起来过时,就像 Django 使 ASP 过时一样。
—Jacob Kaplan-Moss,Django 开发人员
CouchDB 的设计借鉴了 Web 架构以及资源、方法和表示的概念。它通过强大的方式来查询、映射、组合和过滤您的数据来增强这一点。加上容错性、极高的可扩展性和增量复制,CouchDB 为文档数据库定义了一个最佳位置。
1.2.3. 更适合常见应用¶
我们编写软件来改善我们和他人的生活。通常这涉及到获取一些平凡的信息,例如联系人、发票或收据,并使用计算机应用程序对其进行操作。CouchDB 非常适合此类常见应用程序,因为它将不断发展、自包含的文档的自然概念作为其数据模型的核心。
1.2.3.1. 自包含数据¶
发票包含有关单笔交易的所有相关信息,即卖方、买方、日期以及销售的商品或服务的清单。如 图 1. 自包含文档 所示,这份纸张上没有指向其他纸张的抽象引用,这些纸张包含卖方的姓名和地址。会计师喜欢将所有信息集中在一个地方的简单性。如果可以选择,程序员也会喜欢这一点。
然而,使用引用正是我们在关系数据库中建模数据的方式!每个发票都存储在一个表中,作为一个行,该行引用其他表中的其他行,一个行用于卖方信息,一个行用于买方,一个行用于每个计费的商品,以及更多行用于描述商品详细信息、制造商详细信息等等。
这不是为了贬低关系模型,关系模型具有广泛的适用性,并且由于许多原因非常有用。但是,希望这能说明有时您的模型可能无法以现实世界中出现的方式“适合”您的数据。
让我们看一下简单的联系人数据库,以说明一种不同的数据建模方式,这种方式更接近于其现实世界对应物——一堆名片。就像我们的发票示例一样,名片包含所有重要信息,就在卡片上。我们称之为“自包含”数据,它是理解像 CouchDB 这样的文档数据库的重要概念。
1.2.3.2. 语法和语义¶
大多数名片包含大致相同的信息——某人的身份、隶属关系和一些联系信息。虽然这些信息的具体形式可能在不同的名片之间有所不同,但传达的总体信息保持一致,我们很容易将其识别为名片。从这个意义上说,我们可以将名片描述为一种现实世界文档。
Jan 的名片可能包含电话号码,但不包含传真号码,而 J. Chris 的名片则包含电话号码和传真号码。Jan 不必通过在名片上写下“传真:无”这样荒谬的内容来明确表示他没有传真机。相反,只需省略传真号码就意味着他没有传真机。
我们可以看到,相同类型(例如名片)的现实世界文档在语义(它们承载的信息类型)上往往非常相似,但在语法(这些信息是如何结构化的)上却可能差异很大。作为人类,我们自然能够处理这种变化。
虽然传统的关联数据库要求您提前建模数据,但 CouchDB 的无模式设计通过一种强大的方式来解除您的负担,即事后聚合您的数据,就像我们对现实世界文档所做的那样。我们将深入探讨如何使用这种底层存储范式来设计应用程序。
1.2.4. 大型系统的构建块¶
CouchDB 本身就是一个有用的存储系统。您可以使用 CouchDB 提供的工具构建许多应用程序。但 CouchDB 的设计考虑了更大的图景。它的组件可以用作构建块,以略微不同的方式解决大型和更复杂系统的存储问题。
无论您需要一个速度极快但不太关心可靠性(例如日志记录)的系统,还是一个保证在两个或多个物理上分离的位置存储数据以确保可靠性,但您愿意接受性能下降的系统,CouchDB 都允许您构建这些系统。
您可以调整许多旋钮来使系统在一个领域工作得更好,但这样做会影响另一个领域。一个例子是 最终一致性 中讨论的 CAP 定理。为了让您了解其他影响存储系统的因素,请参阅 图 2 和 图 3。
通过减少给定系统的延迟(这不仅适用于存储系统),您会影响并发和吞吐量能力。
当您想要横向扩展时,需要处理三个不同的问题:扩展读取请求、写入请求和数据。与所有这三个问题以及图 2和图 3中显示的项目正交的是许多其他属性,例如可靠性或简单性。您可以绘制许多这样的图表,显示不同的功能或属性如何朝不同的方向拉动,从而塑造它们所描述的系统。
CouchDB 非常灵活,并为您提供了足够的构建块来创建适合您特定问题的系统。这并不是说 CouchDB 可以弯曲以解决任何问题——CouchDB 不是万能药——但在数据存储领域,它可以帮助您走很远。
1.2.5. CouchDB 复制¶
CouchDB 复制是这些构建块之一。它的基本功能是同步两个或多个 CouchDB 数据库。这听起来可能很简单,但简单性是复制能够解决许多问题的关键:可靠地在多台机器之间同步数据库以进行冗余数据存储;将数据分发到共享命中集群的请求总数的子集的 CouchDB 实例集群(负载均衡);以及在物理上相距遥远的位置之间分发数据,例如纽约的一个办公室和东京的另一个办公室。
CouchDB 复制使用所有客户端使用的相同 REST API。HTTP 无处不在且广为人知。复制是增量的;也就是说,如果在复制过程中出现任何问题,例如网络连接断开,它将在下次运行时从上次中断的地方继续。它还只传输同步数据库所需的數據。
CouchDB 做出的一个核心假设是,事情可能会出错,例如网络连接问题,并且它被设计用于优雅的错误恢复,而不是假设一切都会好起来。复制系统的增量设计表明了这一点。关于“可能出错的事情”的想法体现在分布式计算谬误中
网络是可靠的。
延迟为零。
带宽是无限的。
网络是安全的。
拓扑结构不会改变。
只有一个管理员。
传输成本为零。
网络是同质的。
现有的工具通常试图隐藏网络存在的事实,以及任何或所有上述条件对于特定系统都不存在。这通常会导致在出现问题时出现致命错误情况。相反,CouchDB 不会试图隐藏网络;它只是优雅地处理错误,并在需要您采取行动时通知您。
1.2.6. 本地数据为王¶
CouchDB 从 Web 中汲取了许多经验教训,但有一件事可以改进:延迟。无论何时您必须等待应用程序响应或网站呈现,您几乎总是要等待网络连接,而该连接在您当时的需要下并不像您希望的那样快。等待几秒钟而不是几毫秒会极大地影响用户体验,从而影响用户满意度。
您在脱机时该怎么办?这种情况经常发生——您的 DSL 或有线电视提供商出现问题,或者您的 iPhone、G1 或黑莓没有信号,没有连接就意味着无法获取您的数据。
CouchDB 也可以解决这种情况,这就是扩展再次重要的原因。这次是缩小规模。想象一下,CouchDB 安装在手机和其他移动设备上,这些设备可以在连接到网络时与中央托管的 CouchDB 同步数据。同步不受用户界面约束(例如亚秒级响应时间)的限制。它更容易调整以实现高带宽和高延迟,而不是低带宽和非常低的延迟。然后,移动应用程序可以使用本地 CouchDB 来获取数据,由于不需要远程网络连接,因此默认情况下延迟很低。
您真的可以在手机上使用 CouchDB 吗?Erlang(CouchDB 的实现语言)被设计为在比当今手机小得多、功能更弱的嵌入式设备上运行。
1.2.7. 总结¶
下一份文档最终一致性将进一步探讨 CouchDB 的分布式性质。我们应该已经为您提供了足够的线索来激发您的兴趣。让我们开始吧!