Erlang如何在CouchDB中访问像BTree这样的巨大共享数据结构

时间:2014-08-06 21:43:36

标签: erlang couchdb actor

在CouchDB中,存在巨大的BTree数据结构和多个进程(每个请求一个)。

Erlang进程无法共享状态 - 因此似乎应该有专用进程负责访问BTree并通过消息与其他进程通信。但效率低下 - 因为只有一个进程可以访问数据。

那么在Erland中如何处理这种情况,以及如何在CouchDB的特定情况下处理它?<​​/ p>

1 个答案:

答案 0 :(得分:2)

这是个好问题。如果你想要一个权威的答案 问一个关于couchdb内部问题的最好的地方是couchdb mailing list它们非常快,其中一个核心开发者可能会给你一个更好的答案。我会尽量回答这个问题,因为我可以记住我可能错了:)

第一条线索由couchdb配置文件提供。以shell模式启动couchdb

couchdb -i

将浏览器指向

http://localhost:5984/_utils/config.html

您会发现daemon部分下方有一个键值对

index_server {couch_index_server, start_link, []}

AHA!所以索引由服务器提供。什么样的服务器?我们将不得不深入研究code: -

这是gen_server。 couchdb视图的所有操作都由此gen_server处理。 gen_server是客户端服务器模型的erlang通用实现。它默认是并发的。所以你的观察是正确的。对视图的所有请求都是在gen_server的帮助下管理的不同进程。

index_server定义了三个ets表。您可以通过键入

来验证这一点 我们之前开始的erlang shell中的

ets:i()你应该看到: -

 couchdb_indexes_by_db couchdb_indexes_by_db bag     1      320      couch_index_server
 couchdb_indexes_by_pid couchdb_indexes_by_pid set   1      316      couch_index_server
 couchdb_indexes_by_sig couchdb_indexes_by_sig set   1      316      couch_index_server

当index_server获得callget_index时,它会将Waiters列表添加到ets couchdb_indexes_by_sig。或者,如果进程请求它,它只需发送带有索引位置的reply

当index_server获得callasync_open时,它会简单地遍历Waiters列表并向其发送reply及其索引位置

类似地,在索引上调用reset_indexes和其他操作,再次发送带有索引位置的回复。

首次创建索引时,couchdb调用async_open为所有等待进程提供索引。之后,每个进程都可以访问索引。

这里需要注意的一点是,除了使索引可用于其他进程(例如对couch_mr_view_util.erl)之外,索引服务器不会执行任何特殊操作。在这方面它充当gateway.Index写操作由couch_index.erl,couch-index_updater.erl和couch_index_compactor.erl处理,其中(不出所料)都是gen_servers!

首次创建视图时,只有一个进程可以访问它。 query_server进程(默认情况下为couchjs)。构建视图后,可以以并发方式读取和更新视图。实际的视图查询由couch_mr_view处理,该文件作为familliar http api向我们公开。