производительность веб-приложения с большим количеством вставок - PullRequest
2 голосов
/ 24 ноября 2008

Какова лучшая стратегия ввода-вывода для веб-приложения с высоким трафиком, которое регистрирует поведение пользователя на веб-сайте и где ВСЕ трафик приведет к записи ввода-вывода? Будет ли запись в файл и в одночасье делать пакетные вставки в базу данных? Или просто сделать INSERT (или INSERT DELAYED) для каждого запроса? Я понимаю, что для правильного рассмотрения этой проблемы потребовалось бы гораздо больше подробностей об архитектуре, но было бы очень полезно подтолкнуть ее в правильном направлении.

Ответы [ 11 ]

1 голос
/ 24 ноября 2008

Записывая в БД, вы позволяете СУБД решать, когда должен произойти ввод-вывод на диск - например, если у вас достаточно ОЗУ, возможно, она эффективно кэширует все эти вставки в памяти, записывая их на диск при меньшей нагрузке. или на каком-либо другом механизме планирования.

Запись непосредственно в файловую систему будет в большей степени ограничена пропускной способностью, чем запись в БД, которая затем записывает, в частности, потому что БД может - теоретически - записывать в более эффективных размерах, непрерывно и в «удобное» время.

1 голос
/ 17 октября 2009

При работе с СУБД наиболее важна оптимизация операций записи на диск. Что-то где-то должно быть сброшено () в постоянное хранилище (дисководы) для завершения каждой транзакции, что ОЧЕНЬ дорого и занимает много времени. Минимизация количества транзакций и максимальное количество написанных последовательных страниц является ключом к производительности.

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

Моя рекомендация - ставить сообщения в очередь и периодически .. скажем, каждые 15 секунд или около того начинать транзакцию ... отправлять все вставленные в очередь вставки ... фиксировать транзакцию.

Если ваша база данных поддерживает отправку нескольких записей журнала в одном запросе / команде, это может оказать заметное влияние на производительность, когда между приложением и РСУБД имеется некоторая задержка в сети, за счет уменьшения количества обратных вызовов.

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

Помогает экономное использование индексов и выбор последовательных первичных ключей.

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

1 голос
/ 16 октября 2009

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

  1. Как и выше, запишите данные в таблицу загрузчиков, если какая-либо прикладная среда поддерживает пакетные вставки, а затем используйте их, это ускорит ее. Затем при каждом запросе x выполняйте слияние (через вызов SP) с главной таблицей, где вы можете нормализовать данные с низкой энтропией. Например, если вы сохраняете, если HTTP-тип запроса (get / post / etc), это может быть только пара типов, и его лучше хранить как Int и получить улучшенную производительность запросов ввода-вывода +. Ваши главные таблицы также могут быть проиндексированы, как вы это обычно делаете.

  2. Если этого недостаточно, вы можете передавать запросы к файлам в локальной файловой системе, а затем обрабатывать их извне (т.е. отделять процесс от веб-сервера) и обрабатывать их в базу данных. Это будет происходить за счет большего количества движущихся частей и, возможно, большей задержки между получением запросов и их попаданием в базу данных

Надеюсь, это поможет, Ace

0 голосов
/ 06 ноября 2009

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

0 голосов
/ 30 октября 2009

Вы регистрируете больше, чем было бы доступно в журналах веб-сервера? Это может быть довольно много, см., Например, Информация журнала Apache 2.0 .

Если нет, тогда вы можете использовать старый добрый метод буферизации, а затем пакетную запись. Вы можете буферизовать в разных местах: в памяти на вашем сервере, затем пакетно вставить их в дБ или записать в файл в файл каждые X запросов и / или каждые X секунд.

Если вы используете MySQL, есть несколько различных опций / методов для эффективной загрузки большого количества данных: ЗАГРУЗКА ДАННЫХ INFILE , INSERT DELAYED и так далее.

Множество деталей о скоростях вставки .

Некоторые другие советы включают в себя:

  • разбиение данных на разные таблицы за период времени (т. Е. За день или за неделю)
  • с использованием нескольких дБ соединений
  • с использованием нескольких серверов БД
  • хорошее оборудование (SSD / многоядерный)

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

0 голосов
/ 17 октября 2009

Привет из левого поля, но никто не спросил (а вы не указали), насколько важно, чтобы вы никогда не потеряли данные?

Если проблема в скорости, оставьте все это в памяти и скопируйте в базу данных партиями.

0 голосов
/ 24 ноября 2008

Есть более простой способ ответить на этот вопрос. Профиль производительности двух решений.

Создайте одну страницу, которая выполняет вставку в БД, другую, которая записывает в файл, и другую, которая не делает ни того, ни другого. В противном случае страницы должны быть идентичными. Нажмите на каждую страницу с помощью тестера нагрузки (например, JMeter) и посмотрите, как это влияет на производительность.

Если вам не нравятся показатели производительности, вы можете легко настроить каждую страницу, чтобы попытаться немного оптимизировать производительность или попробовать новые решения ... все - от MSMQ, поддерживаемого MSSQL, до отложенных вставок в общие журналы для отдельных файлов с фоновый рабочий БД.

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

0 голосов
/ 24 ноября 2008

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

0 голосов
/ 24 ноября 2008

Единственная проблема с использованием файловой системы для обратной записи - это как вы расширяете журнал.

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

Этот журнал в конечном итоге превысил ограничение памяти phps и, таким образом, стал узким местом для всего проекта.

Однако, если вы все сделаете правильно, операции чтения / записи файловой системы будут идти непосредственно в системный кеш и будут сбрасываться на диск каждые 10 или более секунд (в зависимости от настроек FS / OS), что приводит к незначительному снижению производительности по сравнению с записью в произвольные адреса памяти.

О, да, и какую бы систему вы ни использовали, вам нужно подумать о одновременном добавлении журнала. Если вы используете базу данных, высокая загрузка вставки может привести к возникновению условий взаимоблокировки, а для файлов необходимо убедиться, что у вас не будет двух одновременных записей, которые взаимно отменяют друг друга.

0 голосов
/ 24 ноября 2008

Мой инстинкт должен был бы использовать только базу данных, избегая прямого ввода-вывода файловой системы любой ценой. Если вам нужно создать какой-то артефакт файловой системы, я бы использовал ночное задание cron (или что-то в этом роде) для чтения записей в БД и записи в файловую систему.

ТАКЖЕ: используйте «INSERT DELAYED» только в тех случаях, когда вы не возражаете потерять несколько записей в случае сбоя или перезапуска сервера, поскольку некоторые записи почти наверняка будут потеряны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...