1.文档存储数据库
一个承载着CouchDB服务器主机的数据库,以文档方式存储。每一个文档在数据库中都有惟一的名称,CouchDB提供一个RESTful HTTP API来读取和更新(添加、编辑、删除)数据库文档。编程
文档是CouchDB中的主要数据单元,由任意数量的字段和附件组成。文档还包括数据库系统维护的元数据。文档字段是惟一命名的,而且包含不一样类型的值(文本、数字、布尔值、列表等),而且没有对文本大小或元素数量的设置限制。安全
CouchDB文档更新模型是无锁且乐观的。文档编辑是经过客户机应用程序加载文档、应用更改并将它们保存回数据库来完成的。若是另外一个编辑相同文档的客户端首先保存其更改,则客户端在保存时将得到编辑冲突错误。要解决更新冲突,能够打开最新的文档版本,从新应用编辑并再次尝试更新。服务器
单个文档更新(添加、编辑、删除)要么所有更新,要么什么也不更新, 文档更新要么彻底成功,要么彻底失败。数据库从不包含部分保存或部编辑的文档。网络
2. 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability) 并发
CouchDB文件被设计为可以保证系统具备全部原子性、一致性、隔离性、持久性(ACID)属性。在磁盘上,CouchDB从不覆盖提交的数据或相关结构,确保数据库文件始终处于一致的状态。这是一种“仅崩溃”的设计,CouchDB服务器不会经历关闭过程,而是简单地终止。编程语言
文档更新(添加、编辑、删除)是序列化的,但并发写的二进制 除外。数据库读取永远不会被锁住,也永远没必要等待写入或其余读取者。任何数量的客户端均可以在不被锁定或被并发更新中断的状况下读取文档,即便是在同一文档上。(我的理解这里多是脏读的形式)CouchDB读取操做使用多版本并发控制(MVCC)模型,其中每一个客户端从读取操做的开始到结束均可以看到数据库的一致快照。这意味着CouchDB能够在每一个文档的基础上保证事务语义。分布式
文档经过它们的名称(文档ID)和序列ID在B-tree树中创建索引。对数据库实例的每次更新都会生成一个新的序列号。序列id稍后用于增量地查找数据库中的更改。当保存或删除文档时,这些B-tree索引将同时更新。索引更新老是发生在文件的末尾(仅追加更新)。函数
文档的优点在于,数据已经被方便地打包用于存储,而不是在大多数数据库系统中分散到多个表和行中。当文档被提交到磁盘时,文档字段和元数据被打包到缓冲区中,一个文档接着一个文档(有助于之后高效地构建视图)。布局
更新CouchDB文档时,全部数据和相关索引都被刷新到磁盘,事务提交老是使数据库处于彻底一致的状态。提交分两步进行:
在第1步操做系统崩溃或电源故障的状况下,从新启动时只会忘记部分刷新的更新。若是在第2步(提交头文件)中发生这样的崩溃,将保留先前相同头文件的存活副本,以确保先前提交的全部数据的一致性。除了头部区域外,没有必要在崩溃或电源故障后进行一致性检查或修复。
3.压缩
偶尔的压缩能够回收被浪费的空间。按照计划,或者当数据库文件超过必定数量的浪费空间时,压缩过程将全部活动数据克隆到一个新文件中,而后丢弃旧文件。数据库始终保持在线状态,全部更新和读取均可以成功完成。只有在复制了全部数据并将全部用户转移到新文件时,才会删除旧数据库文件。
我的感受,这里应该使用了不少技术来保障一致性,若是是在拷贝过程当中文档进行了更新,官方文档没有给出来具体的解决方案。
4. 视图
ACID属性只处理存储和更新,可是咱们还须要可以以有趣和有用的方式显示数据。与必须当心地将数据分解为表的SQL数据库不一样,CouchDB中的数据存储在半结构化文档中。CouchDB文档是灵活的,每一个文档都有本身的隐式结构,这减轻了双向复制表模式及其包含的数据的最困难的问题和陷阱。
可是,除了充当一个奇特的文件服务器以外,用于数据存储和共享的简单文档模型对于构建真正的应用程序来讲过于简单——它不能完成咱们想要和指望的足够多的事情。咱们但愿经过许多不一样的方式来切分和查看咱们的数据。如今须要的是一种方法来过滤、组织和报告还没有分解为表的数据。
4.1 视图模式
为了解决将结构添加回非结构化和半结构化数据的问题,CouchDB集成了一个视图模型。视图是将文档聚合和造成数据库报表的方法,是按需构建的,用于聚合、链接和造成数据库报表文档。由于视图是动态构建的,而且不影响底层文档,因此您能够拥有相同数据的任意多个不一样视图表示。
视图定义严格来讲是虚拟的,只显示当前数据库实例中的文档,使它们与所显示的数据分离,并与复制兼容。CouchDB视图是在特殊的设计文档中定义的,能够像常规文档同样跨数据库实例进行复制,这样不只能够在CouchDB中复制数据,还能够复制整个应用程序设计。
4.2 JavaScript视图功能
图是使用JavaScript函数定义的,这些函数在map-reduce系统中充当映射部分。视图函数接受CouchDB文档做为参数,而后执行所需的任何计算,以肯定将经过视图提供的数据(若是有的话)。它能够基于单个文档向视图添加多行,也能够彻底不添加行。
4.3 View 索引
视图是数据库实际文档内容的动态表示,CouchDB使建立有用的数据视图变得很容易。可是,生成包含数十万或数百万文档的数据库视图须要时间和资源,系统不该该每次都从头开始。
为了保持视图查询的速度,视图引擎维护其视图的索引,并增量地更新它们以反映数据库中的更改。CouchDB的核心设计主要围绕高效、增量地建立视图及其索引进行优化。
视图及其函数定义在特殊的“设计”文档中,文档中能够包含任意数量的唯一命名的视图函数。当用户打开一个视图并自动更新其索引时,同一设计文档中的全部视图都被索引为单个组。
视图生成器使用数据库序列ID来肯定视图组是否与数据库彻底同步。若是没有,视图引擎将检查自上次刷新以来更改的全部数据库文档(按打包顺序排列)。文档按在磁盘文件中出现的顺序读取,从而下降磁盘磁头查找的频率和成本。
视图能够在刷新的同时,同时读取和查询。若是客户机正在缓慢地将大视图的内容读取出来,则能够同时为另外一个客户机打开和刷新相同的视图,而不会阻塞第一个客户机。对于任何数量的并发客户机阅读器都是如此,它们能够在为其余客户机并发刷新索引时读取和查询视图,而不会给阅读器带来问题。
当视图引擎经过您的“map”和“reduce”函数处理文档时,若是存在它们的前一行值,那么它们将从视图索引中删除。若是文档是由视图函数选择的,那么函数结果将做为新行插入视图。
当将视图索引更改写入磁盘时,更新老是附加在文件末尾,这既能够减小磁盘提交期间的磁头查找时间,又能够确保崩溃和电源故障不会致使索引损坏。若是在更新视图索引时发生崩溃,则不完整的索引更新只会丢失,并从其先前提交的状态增量地从新构建。
5.安全和校验
为了保护那些能够阅读和更新的文档,CouchDB有一个简单的阅读器访问和更新验证模型,能够扩展该模型来实现定制的安全模型。
5.1管理员访问
CouchDB数据库实例具备管理员账户。管理员账户能够建立其余管理员账户并更新设计文档。设计文档是包含视图定义和其余特殊公式的特殊文档,以及常规字段和blob。
5.2 更新校验
因为文档是写到磁盘上的,所以能够经过JavaScript函数动态地验证它们,以实现安全性和数据验证。当文档经过全部公式验证条件时,容许继续更新。若是验证失败,更新将停止,用户客户机将得到错误响应。用户凭证和更新后的文档都做为验证公式的输入,能够经过验证用户更新文档的权限来实现自定义安全模型。基本的author only update文档模型实现起来很简单,其中验证文档更新以检查用户是否列在现有文档的author字段中。更动态的模型也是可能的,好比检查一个单独的用户账户配置文件的权限设置。更新验证对实时使用和复制的更新都是强制的,以确保共享、分布式系统中的安全性和数据验证。
6. 分布式更新和复制
CouchDB是一个基于对等的分布式数据库系统。它允许用户和服务器在断开链接时访问和更新相同的共享数据。而后能够在之后双向复制这些更改。CouchDB文档存储、视图和安全模型被设计为协同工做,以使真正的双向复制高效可靠。文档和设计均可以复制,从而容许将完整的数据库应用程序(包括应用程序设计、逻辑和数据)复制到笔记本电脑上脱机使用,或者复制到远程办公室的服务器上,在远程办公室中,链接速度慢或不可靠会使共享数据变得困难。复制过程是增量的。在数据库级别,复制只检查自上次复制以来更新的文档。若是复制在任何步骤失败,例如因为网络问题或崩溃,下一个复制将在最后一个检查点从新启动。能够建立和维护部分副本。复制能够经过JavaScript函数进行过滤,以便只复制特定的文档或知足特定条件的文档。这容许用户离线使用大型共享数据库应用程序的子集,同时保持与应用程序和该数据子集的正常交互。
6.1 冲突
冲突检测和管理是对任何分布式文本编辑系统都是关键问题。CouchDB存储系统将编辑冲突视为一种常见状态,而不是异常状态。冲突处理模型简单、无损,同时保留了单一的文档语义,容许分散的冲突解决。
CouchDB容许数据库中同时存在任意数量的冲突文档,每一个数据库实例决定哪一个文档是赢家,哪一个文档是冲突。只有获胜的文档才能出如今视图中,而失败的冲突仍然能够访问,并保留在数据库中,直到在数据库压缩过程当中删除或清除。由于冲突文档仍然是常规文档,因此它们像常规文档同样复制,而且遵循相同的安全性和验证规则。
当分布式编辑冲突发生时,每一个数据库副本都看到相同的获胜修订,而且每一个副本都有机会解决冲突。解决冲突能够手工完成,或者根据数据的性质和冲突由自动化代理完成。该系统在维护单个文档数据库语义的同时,使分散的冲突解决成为可能。
即便多个断开链接的用户或代理试图解决相同的冲突,冲突管理仍将继续工做。若是解决的冲突致使更多的冲突,系统将以相同的方式容纳它们,在每台机器上肯定相同的赢家,并维护单个文档语义。
6.2 应用程序
仅使用基本复制模型,许多传统的单服务器数据库应用程序几乎不须要额外的工做就能够实现分布式。CouchDB复制被设计为能够当即用于基本的数据库应用程序,同时还能够扩展用于更复杂和功能更全面的用途。只需不多的数据库工做,就能够构建具备细粒度安全性和完整修订历史的分布式文档管理应用程序。能够实现对文档的更新来利用增量字段和blob复制,在增量字段和blob复制中,复制的更新几乎与实际的编辑差别(diffs)同样高效和增量。
7. 实施
CouchDB构建在Erlang OTP平台上,这是一种功能强大的并发编程语言和开发平台。Erlang是为实时电信应用程序开发的,特别强调可靠性和可用性。
不管是在语法仍是语义上,Erlang都与C或Java等传统编程语言很是不一样。Erlang使用轻量级进程和消息传递实现并发,它没有共享的状态线程,全部数据都是不可变的。Erlang的健壮性和并发性很是适合数据库服务器。
CouchDB在概念模型和实际的Erlang实现中是为无锁并发性设计的。减小瓶颈和避免锁定可使整个系统在重负载下正常工做。CouchDB能够容纳许多客户机,它们能够复制更改、打开和更新文档,以及查询同时为其余客户机刷新索引的视图,而不须要锁。
对于更高的可用性和更多的并发用户,CouchDB是为无共享集群而设计的。在一个无共享的集群中,每台机器都是独立的,并与集群伙伴复制数据,从而容许各个服务器在零停机时间内发生故障。因为在从新启动时不须要一致性扫描和修复,若是因为数据中心断电致使整个集群失败,例如,从新启动后整个CouchDB分布式系统当即可用。
CouchDB从一开始就使用分布式文档数据库系统的一致视图构建。与将分布式特性固定在相同的遗留模型和数据库之上的繁琐尝试不一样,它是通过仔细推敲的设计、工程和集成的结果。文档、视图、安全性和复制模型、特殊用途的查询语言、高效而健壮的磁盘布局以及Erlang平台的并发性和可靠性,都被当心地集成为一个可靠而高效的系统。