Назад | Перейти на главную страницу

Как сохранить 3 миллиона записей в формате ключ-значение?

Мы должны хранить основную информацию о 3 миллионах товаров. В настоящее время это один CSV-файл размером 180 МБ, который обновляется ежеквартально.

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

Это для Интернета, поэтому высокая производительность имеет решающее значение.

Должны ли мы использовать MySQL, даже если нам действительно не нужна реляционная база данных? Должны ли мы генерировать 3 миллиона статических html-файлов каждый квартал? Должны ли мы хранить однострочный CSV для каждого продукта в чем-то вроде Amazon S3 или Rackspace Cloud Files? Как лучше всего это сделать?

Поскольку MySQL так широко поддерживается, и это действительно довольно тривиальная вещь, я бы посоветовал пойти с ней. Если на сервере нет хотя бы нескольких ГБ памяти, я бы посоветовал придерживаться MySQL, а не использовать систему в памяти.

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

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

Вы можете использовать специальный тип Key-Value базы данных NoSQL, который оптимизированный для такого рода задач. Посмотри на:

  • Redis - Redis - это расширенное хранилище ключей и значений с открытым исходным кодом. Его часто называют сервером структуры данных, поскольку ключи могут содержать строки, хэши, списки, наборы и отсортированные наборы.
  • MemcacheDB - MemcacheDB - это распределенная система хранения ключей и значений, предназначенная для постоянного хранения.
  • другие (один из таких списков можно найти здесь: http://nosql-database.org/)

Конечно, вы можете использовать MySQL или любую другую реляционную базу данных, но решения специально предназначены для данных типа ключ-значение, которые должны быть лучше (в противном случае, в чем смысл их разработки в первую очередь, кроме возможно Дело в том, что это будет намного меньшее (с точки зрения ОЗУ и HDD) решение).

А сейчас нечто соверешнно другое:

Дано:

  • 180 МБ / 3 млн товаров = в среднем 62 байта на товар.
  • 30 000 запросов в день = 0,34 запроса в секунду
  • Обновляется ежеквартально = по существу статические данные

Нестандартное решение:

Выгрузите каждый продукт в виде записи ресурса TXT и сохраните ее в DNS, например:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

Преимущества:

  • чрезвычайно надежный и проверенный (вы уже зависите от него каждый день)
  • может быть построен практически на любой платформе
  • почти каждый язык поддерживает DNS-запросы в той или иной форме
  • серверы с открытым исходным кодом и коммерческие серверы поддерживают различные типы серверных баз данных
  • можно тривиально скопировать (просто укажите несколько серверов имен)
  • обрабатывает атомарные обновления, даже если реплицируется на дюжину серверов
  • может быть криптографически подписан для обеспечения целостности данных
  • может обрабатывать на порядки более высокую скорость запросов в секунду (10 000 запросов на второй легко обрабатываются на стандартном оборудовании)

Причины, по которым это может быть плохой идеей:

  • вам нужно искать данные (DNS - это исключительно поиск ключа / значения)
  • вам нужно скрыть данные (DNS не имеет конфиденциальности)

MySQL с MyISAM и некоторыми хорошими индексами звучит идеально для этого. Конечно, есть много других вариантов, но MySQL очень широко (если не повсеместно) поддерживается на любом коммерческом веб-хосте. В зависимости от требуемой скорости memcached также стоит посмотреть, но без знания размера каждой пары ключ / значение хранение 3 миллионов из них в памяти может быть даже хуже, чем файл CSV размером 180 МБ (подождите, это файл CSV размером 180 МБ, поэтому мы знаем, насколько они велики. Они должны быть довольно маленькими парами, поэтому memcached может быть еще лучше).

Вы делаете не хотите 3 миллиона статических файлов HTML, это сильно повредит вашей файловой системе. Однострочный CSV, даже на S3, будет иметь ту же проблему. Никто не хочет, чтобы в папке было 3 миллиона файлов.

Вы могли бы использовать базу данных Berkeley, которая делает именно такие вещи, даже если она не была модной с момента появления Perl5. Беркли поддерживает только пары ключ-значение, и вы привязываете весь db к хешу и получаете к нему доступ как таковой.

Использование Беркли подробно описано во многих старых ссылках на Perl, которые лежат у вас на полке, или попробуйте Perldoc для модуля BerkeleyDB CPAN. Я обычно избегаю использования Berkeley DB (хотя у моего работодателя много древнего кода, в котором он играет заметную роль, а некоторые базы данных такие же большие, как у вас), потому что это неинтересно, когда ваши данные становятся более сложными.

Вы отметили свой вопрос как amazon S3.

Я хотел бы обратить ваше внимание на один из других связанных с ними продуктов, который называется Amazon SimpleDB.
Похоже, модель данных SimpleDB хорошо подходит для вашего типа приложения.

Это не плагин для этого, но стоит обратить внимание, особенно если вы планируете использовать облачные сервисы Amazon.

Модель данных SDB напоминает электронную таблицу.

См. Здесь для получения дополнительной информации: http://aws.amazon.com/simpledb/ И модель данных: http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

Несмотря на то, что 180 МБ данных могут быть легко обработаны любой реляционной базой данных, я настоятельно рекомендую MongoDB (http://www.mongodb.org/) над MySQL, Redis, MemcacheDB и другими более простыми хранилищами ключей и значений или реляционными базами данных. Причина в том, что для такого рода проблем MongoDB является самой быстрой и выразительной системой для использования, позволяющей сверхбыстрые динамические обновления без ограничений схемы, поэтому ваши документы могут иметь разные форматы, если они вам нравятся. На днях я был на презентации guardian.co.uk, и они приняли политическое решение запретить все реляционные базы данных и использовать MongoDB исключительно для подачи своих новостей. Вы можете почувствовать, насколько быстрым является их веб-сайт и который работает с 1995 года (старейшая онлайн-газета в Великобритании). В прошлом они также сталкивались со всевозможными узкими местами из-за реляционных баз данных. Для 180 МБ MongoDB будет обслуживать все из памяти, поэтому, вероятно, будет иметь место время загрузки менее миллисекунд.

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

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

Осмелюсь сказать, что все подойдет. Ваша нагрузка составляет 30000 запросов в день, это означает, что (при условии, что ваша нагрузка постоянна в течение дня) у вас будет один запрос каждые 20 секунд; это не так уж плохо.

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

Лучший способ сделать это действительно зависит от качества и характера ваших данных и запросов. Для начала, 180 МБ данных в одной таблице для продуктов не проблема, как бы вы на это ни смотрели. А 30 тысяч запросов в день - еще меньшая проблема. С правильно настроенной базой данных с этой нагрузкой справится любой старый компьютер.

Другие уже указали на два ваших основных варианта: MySQL или база данных noSQL.

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

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

Что касается производительности: раньше я работал в компании, занимающейся электронной коммерцией, где долгое время веб-сайт получал данные с сервера MySQL. На этом сервере было 2 ГБ ОЗУ, общая база данных была ок. При размере 5 ГБ и при максимальной нагрузке сервер обрабатывал несколько тысяч запросов в секунду. Да, мы много работали над оптимизацией запросов, но это определенно выполнимо.