1

У меня есть приложение, которое прослушивает порт для датаграмм UDP. Я использую адаптер входящего канала UDP для прослушивания на этом порту. Мой адаптер канала UDP настроен на использование ThreadPoolTaskExecutor для отправки входящих UDP-дейтаграмм. После адаптера канала UDP я использую прямой канал. Мой канал имеет только одного абонента, то есть активатора услуги.Улучшение производительности доступа к базе данных

Служба добавляет входящие сообщения в синхронизированный список, хранящийся в памяти. Затем у меня есть один поток, который получает содержимое списка каждые 5 секунд и выполняет пакетное обновление базы данных MySQL.

Моя проблема:

  1. Первая основная часть сообщения прибывает. Потоки моего ThreadPoolExecutor получают входящее сообщение от адаптера канала UDP и добавляют их в синхронизированный список. Скажем, 10000 сообщений были получены и вставлены.
  2. Фоновый поток извлекает 10000 сообщений и делает пакетное обновление (JdbcTemplate.update (String []).
  3. На данный момент, фоновый поток ожидает ответ от базы данных. Но сейчас, потому что это занимает много времени в базу данных для выполнения 10000 INSERT, были получены и присутствуют 20000 сообщений.
  4. Фоновый поток получает ответ от базы данных. Затем он извлекает 20000 сообщений и выполняет пакетное обновление (JdbcTemplate.update (String []).
  5. Для выполнения INSERT требуется больше времени для базы данных, и в течение этого времени в список было получено и сохранено 35000 сообщений.

Размер кучи постоянно растет и за определенное время вызывает нарушение памяти.

Я пытаюсь найти решение для улучшения производительности моего приложения.

Благодаря

ответ

3

Хранение 10 000 записей каждые 5 секунд довольно много для любой базы данных.

Вы должны рассмотреть другие варианты

  • Используй другое хранилище данных например хранилище данных NoSQL, или плоский файл.
  • убедитесь, что у вас хорошая производительность записи на ваших дисках, например, с использованием кеша записи.
  • использовать дисковые подсистемы с несколькими дисками или SSD-накопителем.
+0

Задать АБД настроить/перенастроить базу данных или использовать хешированный случайный файл (в конечном счете с двойным путем) в SAN (или на multi di sks configuration) –

2

Предложения

а. Вам действительно нужен один синхронизированный список? Разве у вас нет группы списков, и, допустим, разделите работу между этими списками, скажем, запустив hashCode на ключ данных?

b. Можете ли вы использовать пул потоков потоков, которые читают информацию из списка (я бы, кстати, использовал бы здесь очередь), таким образом, когда один поток «застревает» из-за интенсивной вставки пакета, другие потоки могут читать «задания» «из очереди и выполнять их?

c. Является ли ваша база данных совместно размещенной на той же машине, что и приложение? Это может улучшить производительность

d. Можете ли вы опубликовать свой запрос на вставку? может быть, кто-то может предложить вам способ его оптимизации?

2

Используйте пул соединений с базой данных, так что вам не нужно ждать фиксации в одном потоке. Просто возьмите следующее доступное соединение и выполните параллельные вставки.

+0

Я понимаю ваше решение, но я боюсь, что нагрузка на базу данных будет слишком высокой (как сказал Питер). –

+0

Ну, тогда это архитектурная проблема. Распространяйте свою базу данных на большее количество дисков, чтобы обеспечить возможность параллельной записи на диск через дополнительные каналы контроллера. - Извините, Питер, не видел вашего ответа выше, все хорошие советы – Mike

+0

Последний совет, базы данных часто вас удивляют. Хотя это разумное предположение, вы действительно не знаете, пока не попытаетесь. Производительность - это постоянное решение следующего узкого места. В вашем вопросе спрашивается, как избежать латентности фиксации, параллельная запись - это ответ. База данных, настроенная для ее обработки, является другой проблемой. – Mike

1

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

  • Проверьте советы документации MySQL Вставки скорости в http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html
  • распараллелить процесс вставить
  • Агрегатных сообщения, если это возможно. Вместо того, чтобы хранить все сообщения, вставьте строку с информацией о полученных сообщениях в таймфрейме определенного типа и т. Д.
  • Измените таблицу на отсутствие индексов или внешних ключей, кроме первичного ключа
  • Переключиться на запись в текстовый файл (и импорт, что в течение ночи в LoadData насыпного файла вставить, если вы действительно хотите его в базе данных)
  • Используйте отдельный экземпляр базы данных, чтобы служить только вашей таблице
  • ...
Смежные вопросы