Самый эффективный способ хранения большого количества строковых сообщений в SQL Server?

#.net #sql-server-2008

#.net #sql-server-2008

Вопрос:

Мое приложение получает примерно 2000 строковых сообщений в секунду, каждое сообщение длиной около 300 символов.

Мне нужно хранить все сообщения в БД. Я использую SQL Express 2008 и .NET.

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

Таким образом, данные будут записываться на жесткий диск каждые 5 секунд, а не каждую секунду.

Достаточно ли хорош мой подход? Какой подход я должен использовать для достижения следующих результатов?

  1. сообщения не накапливаются в памяти
  2. Жесткий диск не совершит самоубийство 🙂

Примечание: нет необходимости анализировать строки, единственное, что нужно сохранить их в порядке их поступления.

Комментарии:

1. Это звучит как много данных. Быстрый расчет говорит мне, что вам нужно будет хранить около 50 ГБ данных в день, и я не думаю, что это возможно сохранить в базе данных. Должны ли эти данные храниться бесконечно или они обрабатываются и постепенно удаляются?

2. И давайте не будем забывать о явном ограничении (IIRC) 10 ГБ на базу данных. Вы преодолеете это ограничение примерно через 5 часов.

3. @CyberDude: Спасибо за быстрый ответ. Я предпочитаю хранить столько, сколько могу. Но поскольку данных много, как только я достигну предела хранения, я сотру некоторые старые данные, чтобы освободить место для новых.

4. @SWeko: Я не знал о таком ограничении (новичок в БД). Есть ли другая свободная база данных без такого ограничения? Может быть, мне следует использовать обычные файлы и сжимать их?

5. Если вы не выполняете запросы на основе SQL для своих строк, то, возможно, лучше просто сохранить их в виде файлов. Поскольку их так много, вам также необходимо хранить их в разделенной структуре папок, потому что очень большое количество файлов в одной папке может вызвать проблемы при попытке доступа к ним. Архивирование строки из 300 символов не будет иметь большого значения, возможно, если вы сможете сгруппировать больше таких строк по отдельным строкам в одном файле (скажем, по одному файлу на каждый час?).

Ответ №1:

Если вы более подробно опишете, что вы хотите сделать с этими огромными объемами данных после их сохранения, будет легче сделать четкое предложение о том, что с этим делать.

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

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

Ответ №2:

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

Следующим решением будут файлы на диске, и поскольку вы имеете дело с простым текстом (не двоичным), возможно, быстрое сжатие также поможет. Однако, поскольку файлы будут такими маленькими (300 байт), сжатие не даст никаких разумных результатов. Данные должны быть сгруппированы в файлы большего размера, например, по одному фрагменту данных на строку и по одному такому файлу в день. Этот файл должен быть достаточно большим, чтобы сжатие давало удовлетворительные результаты, если возникнет проблема с дисковым пространством.

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

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

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

Пример разбиения на разделы:

  • имена файлов соответствуют этому формату: yyyymmddhhss-<counter>.txt (например: 201104252345-1.txt , 201104252345-2.txt , и т.д.)
  • структура папок соответствует временным частям: yyyymmdd или yyyymmddhh и т. Д. (Столько уровней, сколько потребуется решению для сохранения управляемого количества файлов)
  • результат: 201104252345-1.txt сохраняется как 2011425201104252345-1.txt и т. Д

Ответ №3:

Я не буду этого делать в вашей ситуации. Предполагая:

(2000 * 300) / 1024 (кб) / 1024 (мб) = около 0,54 МБ в секунду.

Один день имеет: 60 (сек) * 60 (мин) * 24 (час) = 86400 секунд.

0,54 * 86400 = 43200 МБ в день.

Если вы будете использовать кодировку UTF-8, размер будет в два раза больше! (varchar против nvarchar)

Это означает, что вы будете получать около 40 ГБ в день грот. Ваш экспресс-сервер не выдержит, даже если вы будете писать запрос insert каждые 5 секунд, даже 10 или 20 секунд. Подумайте о перестройке индекса для повышения производительности запросов, резервном копировании базы данных в определенный период времени и других материалах базы данных, которые вам нужно носить с собой. Ваша база данных не будет обрабатывать запросы.

Я бы рекомендовал вам хранить строки в текстовых файлах (если ваш текст будет редко читаться конечным пользователем, в противном случае я рекомендую использовать какой-нибудь механизм индексации (возможно, Lucene)) и кэшировать их на сервере приложений. Сохраняйте только путь к этим файлам в базе данных.

Примечание. Это только мое собственное решение, основанное на некоторых фактах и опыте.

Редактировать

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