AICon议程上新60%,阿里国际、360智脑、科大讯飞、蔚来汽车分享大模型探索与实践 了解详情
写点什么

开发者 Hasen 谈为什么选择 CouchDB

  • 2012-09-06
  • 本文字数:2385 字

    阅读完需:约 8 分钟

Hasen 是一名熟知分布式技术、Go 语言的开发者,他最近在自己的博客上发布了一篇文章,谈到为什么要选择 CouchDB 作为自己的数据库。

我一直痛恨 SQL,所以我总是对 NoSQL 运动充满兴趣。

我知道 2 个基于 JSON 的 NoSQL 数据库:MongoDB 和 CouchDB。

我曾试着学习 MongoDB,当时我也在学习 NodeJS——巨大的错误,浪费我很多时间。不管怎么说,MongoDB 的 API 不错,但是我不喜欢它的查询语言, 跟 SQL 差不多,拖沓、冗长、僵化难懂。最后我实在没法用 MongoDB 做出什么像样的东西,因为我试着用它跟 Node 一起,可我在 NodeJS 上门的体验实在不怎么样。究其原因,是因为 NodeJS 的设计,因此我没用起来 MongoDB 不是 MongoDB 的问题,而是 NodeJS 的问题。

学习 CouchDB,也是因为 Hasen 的一个舍友跟他提起的,他从看 CouchDB 的官方手册开始: http://guide.couchdb.org/

打动 Hasen 的,是 CouchDB 的如下特性:

首先,它是纯 JSON 文档存储。也就是说所有的文档都是 JSON,而且可以有任意数量的字段,你也可以随意向现有文档中加入新字段。没有 schema,因此不需要管理迁移问题。

其次,它的“视图”系统。CouchDB 中的视图可以创建第二索引,而且是执行查询的惟一方式(不是通过文档的 _id 来加载它)。视图基本上是 map 函数的缓存结果。

举个例子,比如你在一个所有者和一堆物品之间有多对一的关系,每件物品都会在一个字段中保存所有者 id。该如何按照所有者查询物品列表?你可以创建一个视图,匹配 owner_id 和 item_id,使用 owner_id 查询该试图。这也就是说,对于任何查询,都要先创建一个视图。不能像 SQL 数据库或是 MongoDB 那样随意查询。这可能有好有坏,要看你的心情。我个人认为挺好的,因为这让索引变得简单。

我在传统 SQL 数据库中见到不少如下问题:有时候,一个极其庞杂的查询成为瓶颈,对性能产生极坏影响。有时候你需要抽丝剥茧,看看问题到底在哪里;有时候,你会发现是查询写得太烂了;有时候,你只要往某个表中加个索引即可。

这种悲剧我可不想碰见。

因此,视图系统的好处在于:强迫你把查询变简单,而且易于分析。

第三,CouchDB 的架构在某种意义上是“分布式”的,与 git 的分布方式很类似。当然,总要从一个数据库示例开始,但是如果要加入其他数据库节点,CouchDB 的设计让自己很容易做到分布式。

像 Git,是因为所有节点都是“master”节点,没有“slave”节点;跟 Git 一样,没有哪个 repo 比其他 ripo 更重要。

同步是由一个节点向其他节点推送变化完成的,这很类似于 Git 的 repo 推送、拉取变更的过程。在 CouchDB 中,这种推送叫“复制(replication)”。它会把所有的“新”文档和现有文档的“新版本”推送出去。CouchDB 中有修订版本概念。改变一个文档,CouchDB 会在内部增加一个新的修订版本保存起来,不删除或覆盖已有修订版本。不过,CouchDB 不保证任何旧文档会一直保存,它们被看成“垃圾”并会在以后回收。

不过,这种分布式特性有其代价:数据在不同节点间不一定总是一致的,可能有些节点数据过期,但如果经常复制,可以确保数据节点的最终一致性。

从整体上看,我不认为这是个大问题,而是一个特性,任何基于 web 服务的底层架构设计都应该以其为基础。

Hasen 指出:web 服务和应用都面临扩展性方面的问题,而且即使是一些简单的交互多媒体页面,也会让服务器承受很大压力。他接下来对比了单机视频游戏和 Web 服务在这方面的不同:

首先,web 开发人员多使用动态解释语言,比如 Python 和 Ruby,这些语言的设计目的不是为了运行高性能服务。

其次,视频游戏一次只需要处理一个大型复杂任务。而在 web 服务中,需要把一个相对简单的任务同时做几十万遍,而且是在一个机器上。当然,这么做很愚蠢,要加入更多机器节点,把负载分到这些节点上,各个节点之间不需要通信,每个节点可以处理分配给自己的任务。做不到这几点,就不是分布系统了。

不过,目前的数据库都不是我们应该需要的数据库:只有一个 master,这就是瓶颈。即使只需要向一个 master 数据库写入,可以从其他节点读,仍然有瓶颈。

Hasen 认为这不是正确的分布式做法,要想解决每秒处理几十万个简单的页面请求,架构上必须做到水平扩展:应该可以加入更多节点,而且每个节点都可以自行决策。

如果你只有一个 master 节点,你的分布式就做得有问题。

即使你必须保证 user-id 的全局唯一性,也可以以分布式方式实现。

Hasen 对 Riak 也很欣赏,认为 Riak 的分布式实现很简单,也容易掌握。不过他还是选择了 CouchDB:

对我来说,Riak 的问题是它没有 CouchDB 那样的“视图”。Riak 中可以做 map-reduce 类似操作,但是太影响性能了,在 CouchDB 中,视图是预先计算好的 map-reduce 查询,而且效率很高。

Riak 超出 CouchDB 的,是 Riak 内置集群支持。在 CouchDB 中,没有。……虽然这可能是 Riak 相对 CouchDB 的短处,但是我还是认为视图的好处超过这一点。

而且,还有 BigCouch 项目,它的分布式实现非常出色。

因此,如果要扩展到几十万用户,我可以选用 BigCouch。也许将来 BigCouch 会合并到 CouchDB 中。我也可以自己实现集群和分布式。

Hasen 的文章最初发表后,有人留言指出 MongoDB 也支持水平扩展,是以自动分片(automatic sharding)方式。

对此,Hasen 的回复是:

使用 CouchDB,你也可以分片或是分区。实际上,使用 CouchDB 更简单,因为用了一致性哈希。在 Couch 中做分区的问题是:如果查询一个视图,必须查询所有的分区。考虑到我上面说的“每个节点必须在本地自己完成计算”,这听起来不怎么样。

不过,要记住复制功能。你可以在北美有一个分布集群,在欧洲、亚洲各有一个分区集群。这些集群可以在任何时候保证互相复制。因此,视图查询在每个集群内部的本地化的,这正是分布式精神之所在。

在我目前看来,MongoDB 还做不到这一点。

InfoQ 的读者们,你们是否有 MongoDB 和 CouchDB 的使用经验?对于 Hasen 的观点,你们同意吗?

2012-09-06 22:515031
用户头像

发布了 479 篇内容, 共 157.8 次阅读, 收获喜欢 49 次。

关注

评论

发布
暂无评论
发现更多内容

携手共创开源新格局|2023开放原子全球开源峰会将于6月11日在京隆重开幕

开放原子开源基金会

大数据 开源 开放原子开源基金会 开放原子全球开源峰会 开放原子

喜报!云智慧王海虎荣获中国信通院突出贡献专家奖

云智慧AIOps社区

大前端 低代码 数据可视化

艾媒金榜|2023年中国信创数据库企业TOP15

亚信AntDB数据库

数据库 AntDB AntDB数据库

了不起的互联网老男孩,在创业路上不掉队

HarmonyOS SDK

HMS Core

市场规模超百亿 低代码与传统IT开发有何不同

力软低代码开发平台

微服务系列之微服务架构

Disaster

微服务

软件测试/测试开发丨学习笔记之接口自动化测试

测试人

程序员 软件测试 自动化测试 接口测试 测试开发

让初学者读懂代码的入门书

博文视点Broadview

全球化企业应如何统筹规划财务共享中心?

用友BIP

财务共享

微服务之异步消息通信

Disaster

微服务

微服务之服务容错

Disaster

微服务

GaussDB(DWS)迁移实践丨row_number输出结果不一致

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 企业号 5 月 PK 榜

财务共享服务中心建设流程是什么样的?

用友BIP

财务共享

惊!掌握通义千问的关键,从这些必知内容开始!

加入高科技仿生人

人工智能 低代码 ChatGPT 数字转型 通义千问

微服务之流量控制

Disaster

微服务

“Fabarta 数据血缘治理解决方案”荣获“2023 鑫智奖”双料奖项

Fabarta

数据挖掘 数据分析 数据治理 图智能 血缘治理

AIGC背后的技术分析 | 通过EBG学习概念cup

TiAmo

机器学习 AIGC 解释学习

软件测试/测试开发丨学习笔记之用户端App自动化测试

测试人

程序员 软件测试 自动化测试 测试开发 app自动化测试

微服务系列之远程服务调用

Disaster

微服务

数字化转型,低代码开发真的靠谱?

引迈信息

低代码 数字化 JNPF

通义千问预体验,如何让 AI 模型应用“奔跑”在函数计算上?

Serverless Devs

文件传输只是第一步,文件同步和备份的关键是

镭速

深度解析如何通过财务共享建设助推企业数智化转型

用友BIP

财务共享

微服务系列之单体架构

Disaster

微服务

微服务系列之初探“微服务架构”

Disaster

微服务

软件测试 | 软件危机的几个体现

测吧(北京)科技有限公司

测试

Musl libc 库成功适配到 openEuler Embedded,推动欧拉嵌入式生态发展

openEuler

Linux 操作系统 嵌入式 openEuler risc-v

微服务之事务处理

Disaster

微服务

23种设计模式详解

Disaster

设计模式

spring系列之IOC容器结构

Disaster

spring ioc

开发者Hasen谈为什么选择CouchDB_语言 & 开发_郑柯_InfoQ精选文章