Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB批量读取实现问题,更改流副本集_Mongodb_Mongodb Replica Set_Changestream_Mongodb Replica - Fatal编程技术网

MongoDB批量读取实现问题,更改流副本集

MongoDB批量读取实现问题,更改流副本集,mongodb,mongodb-replica-set,changestream,mongodb-replica,Mongodb,Mongodb Replica Set,Changestream,Mongodb Replica,问题: 推理生成过程是每秒向MongoDB集合写入大约300个推理数据。另一个进程利用MongoDB的变更流特性读回这些推断并进行后处理。当前,调用更改流函数API(mongoc_change_stream_next())时,只返回一个推断数据。因此,总共需要300个这样的调用才能在1秒内获得存储的所有推断数据。但是,每次读取后,需要大约50毫秒的时间来对单个/多个推断数据执行后处理。由于采用单一数据返回模式,引入了15倍的有效延迟。为了解决这个问题,我们正在尝试实现一种与MongoDB的变更流

问题:
推理生成过程是每秒向MongoDB集合写入大约300个推理数据。另一个进程利用MongoDB的变更流特性读回这些推断并进行后处理。当前,调用更改流函数API(mongoc_change_stream_next())时,只返回一个推断数据。因此,总共需要300个这样的调用才能在1秒内获得存储的所有推断数据。但是,每次读取后,需要大约50毫秒的时间来对单个/多个推断数据执行后处理。由于采用单一数据返回模式,引入了15倍的有效延迟。为了解决这个问题,我们正在尝试实现一种与MongoDB的变更流特性一致的批读取机制。我们尝试了不同的选项来实现相同的功能,但在每次更改流API调用之后仍然只获得一个数据。有什么办法解决这个问题吗

平台:
操作系统:Ubuntu 16.04
Mongo-c-driver:1.15.1
Mongo服务器:4.0.12

已试用的选项:
将光标的批次大小设置为大于1

int main(void) {
    const char *uri_string = "mongodb://localhost:27017/replicaSet=set0";
    mongoc_change_stream_t *stream;
    mongoc_collection_t *coll;
    bson_error_t error;
        mongoc_uri_t *uri;
    mongoc_client_t *client;

    /*
    * Add the Mongo DB blocking read and scall the inference parse function with the Json
                 * */
    uri = mongoc_uri_new_with_error (uri_string, &error);
    if (!uri) {
        fprintf (stderr,
        "failed to parse URI: %s\n"
        "error message:       %s\n",
        uri_string,
        error.message);
        return -1;
    }

    client = mongoc_client_new_from_uri (uri);
    if (!client) {
        return -1;
    }

    coll = mongoc_client_get_collection (client,  <DB-NAME>, <collection-name>);
    stream = mongoc_collection_watch (coll, &empty, NULL);
    mongoc_cursor_set_batch_size(stream->cursor, 20);
    while (1){
        while (mongoc_change_stream_next (stream, &doc)) {
            char *as_json = bson_as_relaxed_extended_json (doc, NULL); 
            ............
            ............
            //post processing consuming 50 ms of time
            ............
            ............
        }
        if (mongoc_change_stream_error_document (stream, &error, &err_doc)) {
            if (!bson_empty (err_doc)) {
                fprintf (stderr,
                "Server Error: %s\n",
                bson_as_relaxed_extended_json (err_doc, NULL));
            } else {
                fprintf (stderr, "Client Error: %s\n", error.message);
            }
            break;
        }
    }
    return 0;
}

int main(无效){
常量字符*uri_字符串=”mongodb://localhost:27017/replicaSet=set0";
mongoc_change_stream_t*stream;
mongoc_collection_t*coll;
bson_错误\u t错误;
mongoc_uri_t*uri;
mongoc_客户_t*客户;
/*
*添加Mongo DB blocking read并使用Json扩展推理解析函数
* */
uri=mongoc\u uri\u new\u带有错误(uri\u字符串,&error);
如果(!uri){
fprintf(标准,
“无法分析URI:%s\n”
“错误消息:%s\n”,
uri_字符串,
错误消息);
返回-1;
}
client=mongoc\u client\u new\u from\u uri(uri);
如果(!客户端){
返回-1;
}
coll=mongoc_client_get_collection(client,,);
stream=mongoc\u collection\u watch(coll,&empty,NULL);
mongoc\u光标\u设置\u批次大小(流->光标,20);
而(1){
while(mongoc\u change\u stream\u next(stream和doc)){
char*as_json=bson_as_relaxed_extended_json(doc,NULL);
............
............
//后处理耗时50毫秒
............
............
}
if(mongoc\u变更\u流\u错误\u文档(流、错误和错误文档)){
如果(!bson_为空(err_doc)){
fprintf(标准,
“服务器错误:%s\n”,
bson_as_relaxed_extended_json(err_doc,NULL));
}否则{
fprintf(stderr,“客户端错误:%s\n”,Error.message);
}
打破
}
}
返回0;
}
当前,更改时只返回一个推断数据 调用流函数API(mongoc_change_stream_next())

从技术上讲,并不是只返回一份文档。这是因为迭代底层游标,将每个
bson
设置为下一个文档。因此,即使返回的批大小不止一个,它仍然必须对每个文档进行迭代

你可以试试:

  • 创建单独的线程来并行处理文档,这样就不必为每个文档等待50毫秒或累计等待15秒

  • 循环浏览一批文档,即缓存50个文档,然后执行批处理

  • 在单独的线程上批处理它们(上述两种线程的组合)