couchdb - 是否可以防止在 couchdb 中获取远程设计文档

标签 couchdb replication

更新

正如 @AkshatJiwanSharma 所建议的那样,我在本地复制时尝试了一些方法。很有启发!我已经重命名了这个问题,因为问题不是设计文档被复制,事实上它没有被复制,但是它是通过 HTTP GET 获取的,作为初始复制“协商”阶段的一部分.

我已将原始问题移至底部以使新问题更清晰。新问题是:

在启动与远程源的复制时,获取整个设计文档(即整个远程应用程序)似乎效率低下(特别是在 CouchApps 的情况下)。这可以避免吗?

在我们的案例中,在高延迟链路(低于 7.2Kbps)和相对较大的设计文档 (3MB) 上,问题尤其严重。

远程目标

我首先尝试使用“远程”目标,将复制目标设置为 http://127.0.0.1:5984/emr_replica

[Fri, 08 Aug 2014 08:36:20 GMT] [info] [<0.18947.7>] Document `88fa1b1a1315d27ded663466c6003578` triggered replication `e8e66a554d198b88b6263a572a072fd3+continuous`
[Fri, 08 Aug 2014 08:36:20 GMT] [info] [<0.18946.7>] starting new replication `e8e66a554d198b88b6263a572a072fd3+continuous` at <0.18947.7> (`emr_demo` -> `http://127.0.0.1:5984/emr_replica/`)
[Fri, 08 Aug 2014 08:36:20 GMT] [info] [<0.18928.7>] 127.0.0.1 - - POST /emr_replica/_revs_diff 200
[Fri, 08 Aug 2014 08:36:20 GMT] [info] [<0.18915.7>] y.y.y.y - - GET /_utils/_sidebar.html 200
[Fri, 08 Aug 2014 08:36:20 GMT] [info] [<0.18916.7>] y.y.y.y - - GET /_replicator/88fa1b1a1315d27ded663466c6003578?revs_info=true 200 

在这种情况下,似乎无法获取设计文档。

远程源

然后像这样将源设置为“远程”

{
   "_id": "88fa1b1a1315d27ded663466c6003a4a",
   "_rev": "3-b6408e98acafe729da0153c35d9df113",
   "source": "http://127.0.0.1:5984/emr_demo",
   "target": "emr_replica",
   "continuous": true,
   "filter": "emr/user_data",
   "owner": "jun"
}

然后,服务器在开始复制之前获取远程设计文档 (GET/emr_demo/_design/emr 200)。

[Fri, 08 Aug 2014 08:42:17 GMT] [info] [<0.19687.7>] Document `88fa1b1a1315d27ded663466c6003a4a` triggered replication `bd8f6288970bca974dba36dbc6e5353b+continuous`
[Fri, 08 Aug 2014 08:42:17 GMT] [info] [<0.19686.7>] starting new replication `bd8f6288970bca974dba36dbc6e5353b+continuous` at <0.19687.7> (`http://127.0.0.1:5984/emr_demo/` -> `emr_replica`)
[Fri, 08 Aug 2014 08:42:17 GMT] [info] [<0.19648.7>] 127.0.0.1 - - HEAD /emr_demo/ 200
[Fri, 08 Aug 2014 08:42:17 GMT] [info] [<0.19648.7>] 127.0.0.1 - - GET /emr_demo/_design/emr 200
[Fri, 08 Aug 2014 08:42:18 GMT] [info] [<0.19656.7>] 127.0.0.1 - - GET /emr_demo/5cc2db69a32a84091b96c244273fda0e?revs=true&open_revs=%5B%221-ef8967557f2e99eb137f963daccddb3f%22%5D&latest=true 200

进一步的测试表明,设计文档的获取仅执行一次。进一步的复制(包括重新启动服务器后)仅使用适当的过滤器获取更改:

[Fri, 08 Aug 2014 09:06:36 GMT] [info] [<0.520.0>] Document `88fa1b1a1315d27ded663466c6003a4a` triggered replication `bd8f6288970bca974dba36dbc6e5353b+continuous`
[Fri, 08 Aug 2014 09:06:36 GMT] [info] [<0.519.0>] starting new replication `bd8f6288970bca974dba36dbc6e5353b+continuous` at <0.520.0> (`http://127.0.0.1:5984/emr_demo/` -> `emr_replica`)
[Fri, 08 Aug 2014 09:06:36 GMT] [info] [<0.335.0>] 127.0.0.1 - - GET /emr_demo/_changes?filter=emr%2Fuser_data&feed=continuous&style=all_docs&since=1607&heartbeat=1666 200
[Fri, 08 Aug 2014 09:06:36 GMT] [info] [<0.334.0>] 127.0.0.1 - - GET /emr_demo/5cc2db69a32a84091b96c24427560310?atts_since=%5B%2218-b613d3160bd09c45ac07a5485c9c7bce%22%5D&revs=true&open_revs=%5B%2219-d50438143337a3a0af5ed8ceb75b42f5%22%5D&latest=true 200

之前的问题

我们正在尝试在非常高的延迟链接(缓慢、频繁的断开连接,...)上使用 couchdb 复制。我们希望避免重复繁重的设计文档。我们有一个过滤器,当使用以下curl命令时,设计文档不会像预期的那样出现:

curl http://x.x.x.x:5984/emr/_changes?filter=emr/user_data

我们的复制文档是:

{
   "_id": "e0e38be8cc0b11356dfb03bc8400074d",
   "_rev": "1-d77117f03d63099e1e505b9f9de3371d",
   "source": "http://x.x.x.x:5984/emr",
   "target": "emr",
   "continuous": true,
   "filter": "emr/user_data",
   "create_target": true,
   "owner": "jun"
}

我们在调试时已停用身份验证。当使用现有数据库并删除create_target时,会出现同样的问题。

源服务器输出以下内容:

[Mon, 10 Mar 2014 21:22:03 GMT] [info] [<0.135.0>] Retrying HEAD request to http://x.x.x.x:5984/emr/ in 0.25 seconds due to error {conn_failed,{error,etimedout}}
[Mon, 10 Mar 2014 21:23:47 GMT] [info] [<0.135.0>] Retrying GET request to http://x.x.x.x:5984/emr/_design/emr in 0.25 seconds due to error req_timedout
[Mon, 10 Mar 2014 21:24:14 GMT] [error] [<0.135.0>] Replicator, request GET to "http://x.x.x.x:5984/emr/_design/emr" failed due to error {error,req_timedout}
[Mon, 10 Mar 2014 21:24:14 GMT] [error] [<0.135.0>] Replication manager, error processing document `e0e38be8cc0b11356dfb03bc8400074d`: Couldn't open document `_design/emr` from source database `http://x.x.x.x:5984/emr/`: {'EXIT',{http_request_failed,"GET","http://x.x.x.x:5984/emr/_design/emr",
                         {error,{error,req_timedout}}}}

使用 tcpdump 时,很明显复制失败,因为复制管理器尝试下载繁重的设计文档 ( http://x.x.x.x:5984/emr/_design/emr )。

仅供引用,复制器的配置是:

replicator  connection_timeout          5000    
            db                          _replicator 
            http_connections            1   
            max_replication_retry_count 3   
            retries_per_request         1   
            socket_options              [{keepalive, true}, {nodelay, true}]    
            ssl_certificate_max_depth   3   
            verify_ssl_certificates     false   
            worker_batch_size           1   
            worker_processes            1

编辑:user_data 函数(当通过上面的curl 运行时正确隐藏设计文档)是:

exports.user_data = function(doc, req) {
    if (doc.collection == "visits" || doc.collection == "patients" || doc.collection == "reports") {
        return true;
    }
    return false;
}

希望有人能帮忙!

最佳答案

建议

尝试在另一个小型专用设计文档中定义过滤器函数,看看是否可以解决您的问题。

// replicator document:
{
   "_id": "e0e38be8cc0b11356dfb03bc8400074d",
   "_rev": "1-d77117f03d63099e1e505b9f9de3371d",
   "source": "http://x.x.x.x:5984/emr",
   "target": "emr",
   "continuous": true,
   "filter": "small-design-doc/user_data",
   "create_target": true,
   "owner": "jun"
}

// _design/small-design-doc
// -- will be replicated, but is quite small:
{
  "_id": "_design/small-design-doc",
  "_rev": "1-...",
  "filters": {
    "user_data": "function(doc, req) { ... }"
  }
}

说明

According to a current snapshot of the source code ,看起来复制器正在尝试从源数据库中获取设计文档 (_design/emr),因为过滤器函数是在那里定义的 (emr/user_data)。

如果您在另一个设计文档中指定过滤函数,复制器应在执行复制之前尝试下载该文档。因此,您无法完全避免下载任何设计文档,但您可以选择哪个

顺便说一句,这是一个很好的问题。并且进行了非常彻底的调查!

关于couchdb - 是否可以防止在 couchdb 中获取远程设计文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22311868/

相关文章:

ubuntu - PouchDB - 尝试连接到 CouchDB 时为 "Database encountered an unknown error"

添加 cache.manifest 时,AngularJS/PouchDB 应用程序停止同步到 CouchDB

mysql - 需要使我的 Mysql Slave 成为只读服务器

在 R 中复制 Stata 边距

javascript - JavaScript 中的 Node js/MongoDB 副本集数组

Redis 复制和客户端输出缓冲区限制

couchdb - 如何重命名 CouchDB 数据库?

python - 如何通过 yum 安装 python 包而不需要所有依赖项

javascript - 如何在 map 函数中使用 require() ?

mysql - 使用逗号分隔数据时避免数据复制