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个文档,然后执行批处理
- 在单独的线程上批处理它们(上述两种线程的组合)