MongoDB Java API 3.0 关闭游标
MongoDB Java API 3.0 closing cursor
我的 MongoDB Java 驱动程序 3.0 版本出现问题。对多个集合(updateOne、find)执行多个操作后,出现 Command failed with error 8: '24: Too many open files'
错误。我在代码中经常执行的典型操作如下:
private Document findFirst(int i) {
FindIterable<Document> cursor = collection.find(new Document("_id", i)).limit(1);
Document exists = null;
for (Document doc : cursor) {
exists = doc;
break;
}
return exists;
}
Document exists = findFirst(integer);
return exists != null ? new MongoDBDocument(collection,exists) : null;
并且,当我查找 ID 时,"session" 未关闭:
Set<Integer> s = new HashSet<>();
for (Document k : collection.find().projection(new Document("_id",1))) { //Fully scan the collection
s.add(Integer.valueOf((String)k.get("_id")));
}
return s;
因此,我看到在较早的 API 中,查找操作的结果返回了一个必须关闭的 DBCursor。在我看来,在当前的实现中,没有游标被关闭。我看到让它工作的唯一方法是每次关闭 MongoClient,但很可能我没有以正确的方式做某事。可能,当我使用 db.getCollection(name)
检索集合时,我必须在对它执行一些操作后以某种方式关闭它:我试图阅读文档但没有任何帮助。
服务器日志返回的详细错误如下:
2016-04-24T13:20:32.839+0200 E STORAGE [conn721] WiredTiger (24) [1461496832:839907][968:0x700000934000], WT_SESSION.create: /data/db/index-1232-7182838846905439482.wt: Too many open files
2016-04-24T13:20:32.840+0200 I COMMAND [conn721] command alledges.$cmd command: createIndexes { createIndexes: "2071853587", indexes: [ { key: { _id: 2071853587 }, name: "_id_2071853587", ns: "alledges.2071853587" } ] } keyUpdates:0 writeConflicts:0 exception: 24: Too many open files code:8 numYields:0 reslen:83 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { W: 1 } } } protocol:op_query 539ms
我哪里错了?提前致谢。
问题出在当前的 WiredTiger 实现上。 运行此配置的服务器解决问题:
mongodb --storageEngine mmapv1
此错误通常与打开的文件描述符过多有关。参见 ulimit references to review and recommended settings. You also need to check the limits imposed on the process itself (not necessarily your system wide setting). See proc-file-system。
关于 WiredTiger,有一个 "sweep" 线程会定期关闭已空闲一段时间的打开表。因为扫描线程基于空闲时间而不是打开文件描述符的数量进行操作,所以 WiredTiger 不会响应在任何特定时间打开大量文件。
要检查的另一件事是如何使用 MongoClient 实例。请注意,MongoClient
透明地执行连接池,通常每个 JVM 进程应该只有一个实例。如果你大量创建这个 class 的实例,你可能会在它们被释放之前获得太多连接(空闲连接)。
关于游标,虽然服务器最终会超时,但是自己关闭游标会更有效率。尤其是当游标还没有完全耗尽并且不再需要时。例如,您可以关闭光标:
MongoCursor<Document> cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
System.out.println(cursor.next().toJson());
}
} finally {
cursor.close();
}
额外提示,您还可以使用 .first()
替换您的 findFirst()
方法,例如:
FindIterable<Document> cursor = collection.find(new Document("_id", i);
return cursor.first()!=null;
我的 MongoDB Java 驱动程序 3.0 版本出现问题。对多个集合(updateOne、find)执行多个操作后,出现 Command failed with error 8: '24: Too many open files'
错误。我在代码中经常执行的典型操作如下:
private Document findFirst(int i) {
FindIterable<Document> cursor = collection.find(new Document("_id", i)).limit(1);
Document exists = null;
for (Document doc : cursor) {
exists = doc;
break;
}
return exists;
}
Document exists = findFirst(integer);
return exists != null ? new MongoDBDocument(collection,exists) : null;
并且,当我查找 ID 时,"session" 未关闭:
Set<Integer> s = new HashSet<>();
for (Document k : collection.find().projection(new Document("_id",1))) { //Fully scan the collection
s.add(Integer.valueOf((String)k.get("_id")));
}
return s;
因此,我看到在较早的 API 中,查找操作的结果返回了一个必须关闭的 DBCursor。在我看来,在当前的实现中,没有游标被关闭。我看到让它工作的唯一方法是每次关闭 MongoClient,但很可能我没有以正确的方式做某事。可能,当我使用 db.getCollection(name)
检索集合时,我必须在对它执行一些操作后以某种方式关闭它:我试图阅读文档但没有任何帮助。
服务器日志返回的详细错误如下:
2016-04-24T13:20:32.839+0200 E STORAGE [conn721] WiredTiger (24) [1461496832:839907][968:0x700000934000], WT_SESSION.create: /data/db/index-1232-7182838846905439482.wt: Too many open files
2016-04-24T13:20:32.840+0200 I COMMAND [conn721] command alledges.$cmd command: createIndexes { createIndexes: "2071853587", indexes: [ { key: { _id: 2071853587 }, name: "_id_2071853587", ns: "alledges.2071853587" } ] } keyUpdates:0 writeConflicts:0 exception: 24: Too many open files code:8 numYields:0 reslen:83 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { W: 1 } } } protocol:op_query 539ms
我哪里错了?提前致谢。
问题出在当前的 WiredTiger 实现上。 运行此配置的服务器解决问题:
mongodb --storageEngine mmapv1
此错误通常与打开的文件描述符过多有关。参见 ulimit references to review and recommended settings. You also need to check the limits imposed on the process itself (not necessarily your system wide setting). See proc-file-system。
关于 WiredTiger,有一个 "sweep" 线程会定期关闭已空闲一段时间的打开表。因为扫描线程基于空闲时间而不是打开文件描述符的数量进行操作,所以 WiredTiger 不会响应在任何特定时间打开大量文件。
要检查的另一件事是如何使用 MongoClient 实例。请注意,MongoClient
透明地执行连接池,通常每个 JVM 进程应该只有一个实例。如果你大量创建这个 class 的实例,你可能会在它们被释放之前获得太多连接(空闲连接)。
关于游标,虽然服务器最终会超时,但是自己关闭游标会更有效率。尤其是当游标还没有完全耗尽并且不再需要时。例如,您可以关闭光标:
MongoCursor<Document> cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
System.out.println(cursor.next().toJson());
}
} finally {
cursor.close();
}
额外提示,您还可以使用 .first()
替换您的 findFirst()
方法,例如:
FindIterable<Document> cursor = collection.find(new Document("_id", i);
return cursor.first()!=null;