У меня есть веб-приложение, которое получает сообщения через HTTP-интерфейс, например:
http://server/application?source=123&destination=234&text=hello
Этот запрос содержит идентификатор отправителя, идентификатор получателя и текст сообщения.
Это сообщение следует обрабатывать так:
Дерево будет загружено другими приложениями, к которым я не могу прикоснуться.
Я использую Oracle в качестве резервной базы данных и JPA с Toplink для задач обработки базы данных. Если возможно, я останусь с ними.
Без особой оптимизации я могу достичь пропускной способности ~ 30 запросов / сек в своей среде. Это немного, мне нужно ~ 300 запросов / сек. Итак, я измерил, где находится узкое место в производительности, и обнаружил, что вызовы em.persist() занимают большую часть времени. Если я просто закомментирую эту строку, пропускная способность превысит 1000 запросов / сек.
Я попытался написать небольшое тестовое приложение, которое использовало бы простые вызовы JDBC для сохранения 1 миллиона сообщений в той же базе данных. Я использовал пакетную обработку, то есть я сделал 100 вставок, затем зафиксировал и повторял, пока все записи не были в базе данных. Я измерил пропускную способность ~ 500 запросов / сек в этом сценарии, что соответствовало моим потребностям.
Понятно, что здесь мне нужно оптимизировать производительность вставки. Однако, как я упоминал ранее, я хотел бы продолжать использовать для этого JPA и Toplink, а не чистый JDBC.
Вы знаете, как создавать пакетные вставки с помощью JPA и Toplink? Можете ли вы порекомендовать какой-либо другой метод улучшения производительности JPA-файлов?
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ:
«запросов / сек» здесь означает: общее количество запросов / общее время от начала теста до последней записи, записанной в базу данных.
Я попытался сделать вызовы em.persist() асинхронными, создав очередь в памяти между содержимым сервлета и персистером. Это очень помогло производительности. Однако очередь действительно росла очень быстро, и поскольку приложение будет получать ~ 200 запросов в секунду непрерывно, это не приемлемое решение для меня.
В этом независимом подходе я собирал запросы в течение 100 мс и вызывал em.persist() для всех собранных элементов перед тем, как совершить транзакцию. EntityManagerFactory кэшируется между каждой транзакцией.




Каков ваш показатель «запросов / сек»? Другими словами, что происходит с 31-м запросом? Какой ресурс блокируется? Если это интерфейс / сервлет / веб-часть, можете ли вы запустить em.persist () в другом потоке и немедленно вернуться?
Кроме того, вы каждый раз создаете транзакции? Вы создаете объекты EntityManagerFactory с каждым запросом?
Вы должны отделиться от интерфейса JPA и использовать чистый API TopLink. Вероятно, вы можете поместить сохраняемые объекты в UnitOfWork и зафиксировать UnitOfWork по своему расписанию (синхронно или асинхронно). Обратите внимание, что одна из издержек em.persist () - это неявное клонирование всего графа объекта. TopLink будет работать лучше, если вы сами uow.registerObject () ваши два пользовательских объекта сохраните сами тесты идентичности, которые он должен выполнить в противном случае. В итоге вы получите:
uow=sess.acquireUnitOfWork();
for (job in batch) {
thingyCl=uow.registerObject(new Thingy());
user1Cl=uow.registerObject(user1);
user2Cl=uow.registerObject(user2);
thingyCl.setUsers(user1Cl,user2Cl);
}
uow.commit();
Кстати, это очень старая школа TopLink;)
Обратите внимание, что пакетная обработка очень поможет, потому что пакетная запись и, особенно, пакетная запись с привязкой параметров, будет работать, что в этом простом примере, вероятно, будет иметь очень большое влияние на вашу производительность.
Другие вещи, на которые стоит обратить внимание: размер секвенирования. Большая часть времени, затрачиваемого на запись объектов в TopLink, на самом деле тратится на чтение информации о последовательности из базы данных, особенно с небольшими значениями по умолчанию (у меня, вероятно, было бы несколько сотен или даже больше в качестве размера моей последовательности).
Спасибо, попробую через несколько дней. Что вы имеете в виду под размером секвенирования?