Я использую 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"
}