写点什么

开发者 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:515312
用户头像

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

关注

评论

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

Vue3源码 | 如何挂载组件元素?

梁龙先森

源码分析 大前端 Vue3

软件工程笔记:学习方法

风翱

软件工程 笔记 3月日更

那些不得不知的缓存知识

Java 缓存 程序员 面试

redis+docker构建主从环境

小铨

redis Docker redis+docker 主从环境

监控系统-zabbix快速入门

小铨

监控 zabbix

MySQL-技术专题-知识点介绍

码界西柚

MySQL

渣硕试水字节跳动,本以为简历都过不了,123+HR面直接拿到意向书

Java 编程 程序员 架构 面试

Kubernetes Ingress 可视化编辑器

倪朋飞

Kubernetes 网络

Go Modules 常见使用陷阱

Rayjun

go modules Go 语言

架构师知识笔记1

felix徐

架构实战营

数据库与缓存的一致性方案演进

邱学喆

缓存 一致性

小鼎机器人系统开发功能及源码

系统开发咨询1357O98O718

MySQL-技术专题-使用规范

码界西柚

MySQL

周小川:数字货币将是下一代货币研究工作的核心

CECBC

数字货币

蚂蚁金服三面Java面试题全解析,这也太难了吧

Java架构之路

Java 程序员 架构 面试 编程语言

字节跳动5面喜提offer!分享给朋友们面试感受

Java架构之路

Java 程序员 架构 面试 编程语言

爽啊,终于又见面了,字节跳动后端社招面试分享

Java架构之路

Java 程序员 架构 面试 编程语言

K8s各节点常用命令

happlyfox

学习 k8s 3月日更

一束光的旅程

脑极体

区块链如何助力中小企业解决融资难题

CECBC

区块链

10年后端开发程序员精心整理「C/C++ Linux服务器」 成长路线(附思维导图)

Linux服务器开发

Linux 后端 C/C++ Linux服务器开发 Linux后台开发

Wireshark数据包分析学习笔记Day24

穿过生命散发芬芳

Wireshark 数据包分析 3月日更

区块链通证经济——资产流动性的变革

CECBC

资产流动性

管理者如何才能不亲力亲为?

石云升

项目管理 28天写作 职场经验 管理经验 3月日更

使用雪花 id 或 uuid 作为 MySQL 主键,被老板怼了一顿!

Java小咖秀

MySQL 数据库 雪花算法 uuid 雪花id

mysql实现主主数据库(双机热备)

大奎

Kubernetes 弃用 Docker 后如何切换到 Containerd

倪朋飞

Docker Kubernetes 微服务

火爆全网!2021年最新发布Java面试清单(九大技术点)

比伯

Java 程序员 架构 程序人生 架构师

AWS CDK的那些事

小铨

AWS AWS CDK

Java-技术专题-Synchronized和lock区别

码界西柚

Java

Java-技术专题-ConcurrentHashMap读操作分析

码界西柚

Java ConcurrentHashMap

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