Хранение больших наборов данных на уровне сеанса? - PullRequest
2 голосов
/ 04 сентября 2011

Я работаю над созданием веб-приложения, которое состоит из пользователей, выполняющих следующие действия:

  1. Просмотр и поиск на сервере Solr, содержащем миллионы записей. (Эта часть приложения работает очень хорошо.)

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

  3. Выполнить несколько различных операций с этим набором данных.

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

Шаг второй, и как получить данные для шага 3, вот что доставляет мне неприятности. Мне нужно иметь возможность временно сохранять наборы данных, восстанавливать их, когда они нужны, и через некоторое время истекает. Проблема в том, что мои результаты имеют идентификаторы контрольной суммы SHA1, поэтому каждый идентификатор состоит из 48 символов. Набор данных из 500 000 записей, даже если я храню только идентификаторы, - это 22 МБ данных. Поэтому я не могу просто создать одну таблицу базы данных и добавить в нее строку для каждого набора данных, который создает пользователь.

Кому-нибудь когда-нибудь было нужно что-то подобное раньше? Как лучше всего подойти к этой проблеме? Должен ли я генерировать отдельную таблицу для каждого набора данных, который создает пользователь? Если это так, каков наилучший способ истечения / удаления этих таблиц через некоторое время? Я могу развернуть сервер MySQL, если это необходимо (хотя у меня его еще нет, все данные в Solr), и я был бы открыт для некоторого более безумного программного обеспечения, если что-то еще отвечает всем требованиям.

РЕДАКТИРОВАТЬ: Некоторые более подробную информацию, в ответ на Джефф Ферланд ниже.

Объекты данных неизменны, статичны и полностью находятся в базе данных Solr. Это может быть более эффективным в качестве файлов, но я бы предпочел (по причинам поиска и просмотра) хранить их там, где они есть. Ни данные, ни наборы данных не должны быть распределены по нескольким системам, я не ожидаю, что мы когда-либо получим такую ​​нагрузку. Пока что вся эта чертова штука работает внутри одной виртуальной машины (я могу пересечь этот мост, если доберусь туда).

Под "восстановлением, когда это необходимо", я имею в виду что-то вроде этого: пользователь выполняет действительно тщательно разработанный поисковый запрос, который в результате дает ему некоторый набор объектов. Затем они решают, что хотят манипулировать этим набором. Когда они (в качестве случайного примера) нажимают кнопку «Построить график этих объектов по году», мне нужно иметь возможность получить полный набор идентификаторов объектов, чтобы я мог вернуть их на сервер Solr и выполнить больше запросов. Я бы предпочел хранить идентификаторы объектов (а не поисковый запрос), поскольку набор результатов может измениться под пользователем, когда мы добавим больше объектов.

"while" - это примерно продолжительность пользовательского сеанса. Однако может возникнуть проблема, которая может иметь значение: мне может понадобиться реализовать очередь заданий, чтобы я мог отложить обработку, и в этом случае «время» должно быть «столько времени, сколько требуется для обработки вашей работы».

Спасибо Джеффу за то, что он подтолкнул меня предоставить правильные подробности.

1 Ответ

2 голосов
/ 04 сентября 2011

Первый трюк: не представляйте свой SHA1 как текст, а скорее как 20 байтов, которые он занимает. Шестнадцатеричное значение, которое вы видите, является способом отображения байтов в удобочитаемой форме. Если вы храните их правильно, вы получите 9,5 МБ вместо 22.

Во-вторых, вы на самом деле не объяснили природу того, что вы делаете. Ваши сохраненные наборы данных ссылаются на неизменяемые объекты в существующей базе данных? Что вы имеете в виду, восстанавливая их при необходимости? Как долго "время", когда вы говорите об истечении срока? Являются ли базовые данные, на которые вы ссылаетесь, статическими или динамическими? Можете ли вы сохранить шаблон поиска и смещение, или вам нужно сохранить отдельную ссылку?

Нужно ли вставлять данные, относящиеся к сеансу, в базу данных? Может ли это быть более эффективным в файлах? Это нужно распределить по нескольким системам?

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


Обновление : Есть много возможных решений для этого. Вот два:

  • Запишите их в одну таблицу (сохраненные_поиски и т. Д.), У которой есть увеличивающийся идентификатор поиска. Бонусные баллы за вставку ключей в отсортированном порядке. (search_id unsigned bigint, item_id char (20), первичный ключ (search_id, item_id). Это действительно ограничит фрагментацию, сохранит каждый поиск кластеризованным и освободит страницы в примерно последовательном порядке. Это почти скользящая таблица, и это о лучший вариант для выполнения большого количества вставок и удалений. В этом случае вы платите стоимость за вставку и удваиваете эту стоимость за удаление. Вы также должны повторять весь результат поиска.
  • Если ваши элементы поиска имеют увеличивающийся первичный идентификатор, так что любая новая вставка в базу данных будет иметь более высокое значение, чем все, что уже есть в базе данных, это наиболее эффективно. С другой стороны, вставка метки даты приведет к тому же эффекту с меньшей эффективностью (каждая строка должна проверяться в запросе, а не только в записях индекса). Если вы запомните этот максимальный идентификатор и не удаляете записи, вы можете сохранить результаты поиска, которые используют нулевое пространство, всегда устанавливая максимальный идентификатор для сохраненного запроса.
...