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

时间:2014-03-10 21:37:16

标签: 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)。

FYI复制器的配置是:

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函数(如上所述在卷曲时正确隐藏设计文档)是:

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

希望有人可以提供帮助!

1 个答案:

答案 0 :(得分:3)

建议

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

// 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)。

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

顺便提一下很棒的问题。并且进行了彻底的调查!