Назад | Перейти на главную страницу

MongoDB останавливается на скорости 100 операций записи в секунду, но тест показывает 54000 операций записи в секунду.

Я использую MongoDB (v3.4 Community Edition) на экземпляре AWS EC2 m4.large. Я его установил согласно этому MongoDB учебник. Я не изменял конфигурацию MongoDB. Я не настраивал ни один набор реплик или осколок. У меня есть API Джерси, который взаимодействует с MongoDB, используя org.mongodb.morphia (v1.3.2) Драйвер Java.

Я создал нагрузочный тест с использованием SoapUI, в котором я делаю 100 вызовов API, которые, в свою очередь, создают 100 операций записи (один документ создается в одной коллекции для каждой операции записи) для MongoDB. Провожу тест 24 часа. В конце я вижу, что мой веб-сервер пытается связаться с сервером Mongo, но время ожидания соединения истекает, а центральный процессор работает на 100%. Я делаю вывод, что сервер MongoDB задыхается.

Затем я попробовал это сравнительный анализ, по-прежнему с базой данных, размещенной на m4.large. 50000000 записей были созданы за 923,133 секунды, то есть 54113 вставок в секунду. Это более чем в 500 раз быстрее!

Если MongoDB работает так хорошо, почему он задыхается при 100 вставках в секунду при прохождении через драйвер JAVA? Драйвер Java работает медленно? Я неправильно использую драйвер Java? Размер моего инстанса EC2 слишком мал? Поможет ли добавление репликации (наборы RAID и Replica)?

Я новичок в хостинге MongoDB и очень ценю вашу помощь в обучении.

Обновить:

Конфигурация нагрузочного теста:

Клиент: SoapUI (v5.3), веб-сервер: Tomcat 8, Java: v1.8, MongoDB: v3.4. Я использую все свои серверы в AWS в регионе Мумбаи. Я размещаю веб-сервер и сервер MongoDB на одном экземпляре EC2 (m4.large), и я запускаю клиент на машине Windows (t2.micro).

После дальнейшего расследования я думаю, что узкое место находится в моем коде. я использовал Монгостат утилита, чтобы увидеть, как ведет себя mongodb. Я обнаружил, что при запуске есть два соединения. Количество подключений увеличивается до 102, как только я начинаю нагрузочный тест (количество подключений никогда не превышает 102 даже при 1000 запросов в секунду, а MongoDB закрывает их через долгое время). Нагрузка составляет 100 запросов в секунду. Вот гифка, которая показывает это поведение.

Я нашел несколько вопросов с похожей проблемой, но ответы мало что показали. Я позаботился о предложениях. Вот несколько примеров,

https://stackoverflow.com/questions/21580147/mongo-connection-leak-with-morphia

https://stackoverflow.com/questions/31469656/spring-data-mongodb-not-closing-mongodb-connections

Код Java:

Создание соединения: Я использую одно соединение для своего приложения, как рекомендовано MongoDB. Реализация паттерна Singleton.

public class DatabaseConnection {

    private static volatile MongoClient instance;
    private static String cloudhost="localhost";

    private DatabaseConnection() { }

    public synchronized static MongoClient getMongoClient() {
        if (instance == null ) {
            synchronized (DatabaseConnection.class) {
                if (instance == null) {
                    ServerAddress addr = new ServerAddress(cloudhost, 27017);
                    List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
                    MongoCredential credentia = MongoCredential.createCredential(
                        "test", "test", "test".toCharArray());
                    credentialsList.add(credentia);
                    instance = new MongoClient(addr, credentialsList); 

                }
            }
        }
        return instance;
    }
}

Пример класса объекта доступа к данным:

import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.dao.BasicDAO;

import Sample;

public class SampleDao extends BasicDAO<Sample, String>{

    public SampleDao(Class<Sample> entityClass, Datastore ds) {
        super(entityClass, ds);
    }
}

Пример класса репозитория: Этот класс отвечает за взаимодействие с БД и сохранение документа

public class SampleRepository {

    private SampleDao sampleDao;

    public SampleRepository ()
    {
        try 
        {
            MongoClient mongoClient = DatabaseConnection.getMongoClient();
            Datastore ds = new Morphia().map(Pour.class)
                    .createDatastore(mongoClient, "test");
            sampleDao = new SampleDao(Sample.class,ds);
        } 
        catch (Exception e) 
        {
            logger.error("Error while creating SampleDao", e);
        }
    }

    public String createSample (Sample sample)
    {
        try
        {
            Sample2Repository repo = new Sample2Repository ();
            Sample2 sample2 = repo.getSample2(sample.getSampleId());
            Sample.setSample2Id(sample2.getId());

            retur sampleDao.save(sample).getId().toString();
        }
        catch (Exception e)
        {
            logger.error("Error while creating sample.", e);
            return null;
        }
    }
}

Образец документа: Я не думаю, что мои документы больше по размеру, чтобы создавать проблемы для MongoDB. Во время нагрузочного тестирования других запросов не было. Была запущена только операция CreateSample.

{
    "sample2Id":"593e346cfeaa9e62d1706bb5"
    , "sample3Id" : "593e4159729f5d04db7b6da2"
    , "actualTime":"21/06/2017 09:18:00"
    , "uploadTime":"21/06/2017 09:18:00"
}