Helpers - компьютеры, интернет, программирование

MongoDB - вызовы find () иногда застревают - тайм-аут

Мы используем MongoDb для сохранения и извлечения данных.

Все вызовы, которые помещают данные в коллекции, работают нормально и через общий метод.

Все вызовы, которые извлекают данные из коллекций, иногда работают нормально и выполняются с помощью общего метода.

Но иногда, только для одной из коллекции, вызовы застревают навсегда, потребляя ресурсы ЦП. Я должен вручную убивать потоки, иначе он потребляет весь мой процессор.

Соединение с Монго

MongoClient mongo = new MongoClient(hostName , Integer.valueOf(port));
DB mongoDb = mongo.getDB(dbName);

Код для загрузки

DBCollection collection = mongoDb.getCollection(collectionName);
DBObject dbObject = new BasicDBObject("_id" , key);
DBCursor cursor = collection.find(dbObject);

Хотя я выяснил коллекцию, для которой это вызывает проблемы, но как я могу улучшить это, поскольку это происходит для этой конкретной коллекции и иногда.

ИЗМЕНИТЬ

Код для сохранения

DBCollection collection = mongoDb.getCollection(collectionName);
DBObject query = new BasicDBObject("_id" , key);
DBObject update = new BasicDBObject();
update.put("$set" , JSON.parse(value));
collection.update(query , update , true , false);

Массовая запись/коллекция

DB mongoDb = controllerFactory.getMongoDB();
        DBCollection collection = mongoDb.getCollection(collectionName);

        BulkWriteOperation bulkWriteOperation = collection.initializeUnorderedBulkOperation();

        Map<String, Object> dataMap = (Map<String, Object>) JSON.parse(value);

        for (Entry<String, Object> entrySet : dataMap.entrySet()) {
            BulkWriteRequestBuilder bulkWriteRequestBuilder = bulkWriteOperation.find(new BasicDBObject("_id" ,
                    entrySet.getKey()));

            DBObject update = new BasicDBObject();
            update.put("$set" , entrySet.getValue());

            bulkWriteRequestBuilder.upsert().update(update);
        }

Как я могу установить тайм-аут для вызовов выборки ..??


  • сколько документов в этой конкретной коллекции? Пожалуйста, попробуйте запустить .explain() с вашим запросом, который проверяет, как выполняется запрос, независимо от того, использует ли он индекс или нет. 18.05.2016
  • @Astro около 50 документов 18.05.2016
  • Вы пробовали с классами MongoDatabase и MongoCollection? Это предлагаемый метод, который они предлагают, вместо DBCollection и DBObject. 18.05.2016
  • @Lefteris008 Lefteris008 нет, я не пробовал с этими классами, не могли бы вы привести пример для того же. 18.05.2016
  • @ankur-singhal: Еще один способ — запустить запрос на стороне сервера с помощью оболочки mongo, чтобы проверить, не работает ли он медленно на самом сервере. Далее вы можете использовать .explain(), чтобы узнать больше об этом. 18.05.2016

Ответы:


1

Другой подход заключается в использовании предложенного метода для драйвера MongoDB 3.2. Имейте в виду, что вам необходимо обновить библиотеки .jar (если вы этого не сделали) до последней версии.

public final MongoClient connectToClient(String hostName, String port) {
    try {
        MongoClient client = new MongoClient(hostName, Integer.valueOf(port));
        return client;
    } catch(MongoClientException e) {
        System.err.println("Cannot connect to Client.");
        return null;
    }
}

public final MongoDatabase connectToDB(String databaseName) {
    try {
        MongoDatabase db = client.getDatabase(databaseName);
        return db;
    } catch(Exception e) {
        System.err.println("Error in connecting to database " + databaseName);
        return null;
    }

public final void closeConnection(MongoClient client) {
    client.close();
}

public final void findDoc(MongoDatabase db, String collectionName) {
    MongoCollection<Document> collection = db.getCollection(collectionName);
    try {
        FindIterable<Document> iterable = collection
                .find(new Document("_id", key));
        Document doc = iterable.first();
        //For an Int64 field named 'special_id'
        long specialId = doc.getLong("special_id");
    } catch(MongoException e) {
        System.err.println("Error in retrieving document.");
    } catch(NullPointerException e) {
        System.err.println("Document with _id " + key + " does not exist.");
    }
}

public final void insertToDB(MongoDatabase db, String collectioName) {
    try {
        db.getCollection(collectionName).insertOne(new Document()
            .append("special_id", 5)
            //Append anything
        );
    catch(MongoException e) {
        System.err.println("Error in inserting new document.");
    }
}

public final void updateDoc(MongoDatabase db, String collectionName, long id) {
    MongoCollection<Document> collection = db.getCollection(collectionName);
    try {
        collection.updateOne(new Document("_id", id),
                             new Document("$set", 
                                     new Document("special_id", 
                                             7)));
    catch(MongoException e) {
        System.err.println("Error in updating new document.");
    }
}

public static void main(String[] args) {
    String hostName = "myHost";
    String port = "myPort";
    String databaseName = "myDB";
    String collectionName = "myCollection";
    MongoClient client = connectToClient(hostName, port);
    if(client != null) {
        MongoDatabase db = connectToDB(databaseName);
        if(db != null) {
            findDoc(db, collectionName);
        }
        client.closeConnection();
    }
}

EDIT: как предлагали другие, проверьте из командной строки, не слишком ли медленная процедура поиска документа по его идентификатору. Тогда, возможно, это проблема с вашим жестким диском. Предполагается, что _id будет проиндексирован, но, к лучшему или к худшему, заново создайте индекс для поля _id.

18.05.2016
  • Я работаю над вашим решением, мне нужно изменить код для вызовов записи и массовой записи. я отредактировал свой вопрос 18.05.2016
  • @ankur-singhal Я по ошибке добавил блок finally, который закрывает клиент при подключении к базе данных, удалите его и поместите в блок catch. 18.05.2016
  • мне нужно изменить для операции записи и массовой записи, пожалуйста, помогите. 18.05.2016
  • @ankur-singhal Я полностью изменил свой код, разделив все на новые методы и создав новый insertToDB, как вы просили. 18.05.2016
  • Спасибо, я слежу за вашим ответом, не могли бы вы помочь мне с массовым обновлением 18.05.2016
  • Давайте продолжим обсуждение в чате. 18.05.2016
  • @ankur-singhal Я бы с удовольствием, но у меня есть работа, и я буду недоступен в ближайшие несколько часов. Пожалуйста, проверьте ответ на этот вопрос ; вы должны обновить все, чтобы соответствовать драйверу Jave 3.2. Кроме того, имейте в виду, что это не решение, мы пытаемся определить, сохраняется ли проблема при использовании нового драйвера. Вы можете изменить все, и проблема все еще может быть здесь. 18.05.2016
  • я закончил кодирование, просто чтобы узнать, что мы работаем на mongodb 2.2, и мы не можем обновить его, так как он поддерживает и другие приложения. Есть ли возможность установить тайм-аут при чтении из mongo. 18.05.2016
  • @ankur-singhal Поскольку это быстроразвивающийся выпуск, MongoDB 2.2 является старой версией; возможно, проблема, о которой вы говорите, - это ошибка, которая была исправлена ​​​​в более поздних версиях. Но поскольку ваш код основан на этой версии библиотеки, вы мало что можете сделать, кроме тайм-аутов. 18.05.2016
  • точно, я не могу установить тайм-аут, как я могу это сделать в приведенном выше коде 18.05.2016

  • 2

    Ответы, опубликованные другими, великолепны, но не решили мою цель. На самом деле проблема была в самом моем существующем коде, мой cursor ждал в цикле while бесконечное время.

    Я пропустил несколько проверок, которые были решены сейчас.

    20.05.2016

    3

    Просто некоторые возможные объяснения/мысли.

    В общем, «запрос по id» должен быть быстрым, поскольку _id должен всегда индексироваться. Фрагмент кода выглядит правильно, так что, вероятно, причина в самом монго. Это приводит меня к нескольким предложениям:

    Попробуйте подключиться к монго прямо из командной строки и оттуда запустить «найти». Скорее всего, вы все еще сможете наблюдать периодическую медлительность.

    В таком случае:

    • Возможно, дело в дисках (может быть, этот конкретный сервер развернут на медленном диске или, по крайней мере, есть корреляция с некоторой медлительностью доступа к диску).

    • Возможно, у вас сегментированная конфигурация, и один сегмент работает медленнее, чем другие.

    • Возможно, это проблема с сетью, которая возникает время от времени. Если вы запускаете mongo локально/в промежуточной среде env. с той же коллекцией это воспроизводится?

    • Возможно (хотя я с трудом в это верю) запрос выполняется неоптимальным образом. В этом случае вы можете использовать «объяснить ()», как кто-то уже предложил здесь.

    • Если у вас есть набор реплик, выясните, что такое [Предпочтение чтения]. Кто знает, может быть, вы предпочитаете получать этот идентификатор с неоптимального сервера.

    18.05.2016
  • он просто развернут на одном узле, без шардинга, без реплик, только для одной из коллекций я наблюдаю эту проблему, и это тоже не всегда 18.05.2016
  • Новые материалы

    Интуитивное понимание тензоров в машинном обучении
    Тензор является важной концепцией во многих научных областях, таких как математика, физика, обработка сигналов и компьютерное зрение, и это лишь некоторые из них. В математике тензор — это..

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

    Почему объяснимость так важна прямо сейчас?
    По мере того, как системы искусственного интеллекта и инструменты на основе машинного обучения распространяются в нашей повседневной жизни, как практики, так и критики все чаще заявляют о..

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..