写点什么

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

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

关注

评论

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

Android 开发经验分享:挺重要的网络基础,android实现选择题模式

android 程序员 移动开发

Android 黑科技保活实现原理揭秘,精心整理

android 程序员 移动开发

Android---Fragment-的过去、现状与未来,android网络层框架设计实战

android 程序员 移动开发

Android 开发市场是盛是衰?你应该知晓,android实战项目

android 程序员 移动开发

Android 插桩入门,腾讯T2大牛手把手教你

android 程序员 移动开发

Android 组件化实战,kotlin协程实现原理

android 程序员 移动开发

Android 高工面试必考题(二),android开发艺术探索pdf百度云

android 程序员 移动开发

Android 开发必备知识点及面试题汇总(Android+Java,斩获offer

android 程序员 移动开发

Android 开发必备知识点整理,34岁程序员年薪50w

android 程序员 移动开发

Android 开发面试心得:BAT大厂Android面试题整理,面试8家大厂后终于拿到Offer

android 程序员 移动开发

android 快速开发(三)巧用公共标题栏,音视频编解码开发

android 程序员 移动开发

Android 开发之深入浅出 NavigationUI,2020-2021阿里巴巴安卓面试真题解析

android 程序员 移动开发

Android 技术的下半场,kotlin开源

android 程序员 移动开发

Android 约束布局(ConstraintLayout)1,最详细的解释小白也能听懂

android 程序员 移动开发

Android 面试官:这些经验要记录好,面试途中会遇到,做了6年的Android

android 程序员 移动开发

Android&Java面试题大全—金九银十面试必备【上,大厂Android面试真题精选

android 程序员 移动开发

Android 组件通信中有哪些不为人知的细节?,面试题分享

android 程序员 移动开发

Android 获取子 View 的位置及坐标的方式(1),Android入门视频教程

android 程序员 移动开发

Android 面试主题集合整理,kotlin协程原理

android 程序员 移动开发

Android 开发行业真的不行了嘛?,深入讲解Android

android 程序员 移动开发

Android 架构组件的最新进展 (上篇),flutter登录界面设计

android 程序员 移动开发

Android 高频面试必问之Java基础,安卓framework开发

android 程序员 移动开发

android 快速开发(三)巧用公共标题栏(1),android开发从入门到精通

android 程序员 移动开发

Android 性能监控系列一(原理篇),闭关60天学懂NDK+Flutter

android 程序员 移动开发

Android 技术的下半场(1),android开发书籍下载

android 程序员 移动开发

Android 自定义 View 之 LeavesLoading,移动开发工程师考试

android 程序员 移动开发

Android 进阶之 MVP,高级安卓工程师面试题

android 程序员 移动开发

Android-10分区存储介绍及百度APP适配实践,三年经验月薪50k我是怎么做到的

android 程序员 移动开发

Android 无缝换肤深入了解与使用,android快速开发

android 程序员 移动开发

Android 网络框架之Retrofit源码解析,android嵌入式开发及实训答案

android 程序员 移动开发

Android---用力过猛!为了组件化改造学习十几家大厂的技术博客

android 程序员 移动开发

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