Erlang如何访问CouchDB中的BTree等大型共享数据结构



在CouchDB中有巨大的b树数据结构和多个进程(每个请求一个)。

Erlang进程不能共享状态——所以似乎应该有专门的进程负责访问BTree并通过消息与其他进程通信。但是这将是低效的——因为只有一个进程可以访问数据。

那么在Erland中如何处理这些情况,在CouchDB中如何处理这些情况呢?

问得好。如果你想要一个权威的答案问关于couchdb内部的问题最好的地方是couchdb邮件列表,他们非常快,其中一个核心开发人员可能会给你一个更好的答案。我将尽我所能回答这个问题,只是记住我可能是错的:)

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

couchdb -i

将浏览器指向

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

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

index_server {couch_index_server, start_link, []}

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

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

index_server定义了三个et表。您可以通过输入

来验证这一点在我们之前开始的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)之外,没有做任何特殊的事情。在这方面,它起到了门户的作用。索引写操作由couch_index处理。话务量,couch-index_updater。Erl和couch_index_compactor。哦,这些都是gen_server !

当视图第一次被创建时,只有一个进程可以访问它。query_server进程(默认为couchjs)。在构建视图之后,可以以并发的方式读取和更新视图。视图的实际查询由couch_mr_view处理,它作为我们熟悉的http api公开给我们。

最新更新