【问题标题】:Is it possible to prevent fetching of remote design document in couchdb是否可以防止在 couchdb 中获取远程设计文档
【发布时间】:2014-04-14 05:55:35
【问题描述】:

更新

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

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

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

在我们的案例中,在具有相对较大的设计文档 (3MB) 的高延迟链接(小于 7.2Kbps)上尤其成问题。

远程目标

我首先尝试使用“远程”目标,将复制目标设置为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;
}

希望有人能帮忙!

【问题讨论】:

  • 你能添加你的user_data函数吗?
  • 这个问题你解决了吗?我也因错误 {error,req_timedout} 而失败
  • 不,我还没有找到解决方案。我正在添加赏金。也许你可以投票赞成这个问题?
  • 如果你不是管理员,你就不会复制设计文档...
  • @AkshatJiwanSharma 进一步调查表明,设计文档的传输问题不是文档被复制,而是在源远程时作为复制初始设置的一部分传输。因此,我对问题进行了重组以强调这一点。

标签: couchdb replication


【解决方案1】:

建议

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

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

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

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

【讨论】:

  • 精彩演绎+1。
  • 这听起来就像问题所在,您的解决方法很棒。我会尽快去实施并报告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2012-09-15
  • 2014-01-14
  • 2012-09-12
  • 2021-06-04
相关资源
最近更新 更多