Сохранение в поток (постановка)

Материал из GedeminWiki
Перейти к: навигация, поиск

Требования к новому сохранению в поток:

  1. Увеличение скорости минимум в 10 раз;
  2. Уменьшение размера файла минимум в 10 раз (при использовании двоичного формата);
  3. Возможность сохранения в формате XML;
  4. Не использовать бизнес-объекты;
  5. Работать только с информацией о метаданных из реляционной БД. Сделать всю информацию, не укладывающуюся в реляционную схему, внешней по относительности к процессу сохранения (см. например, аттрибут "Перезаписывать данными из потока").
  6. Предусмотреть возможность сохранения только объектов измененных после указанной даты;
  7. Предусмотреть возможность инкрементного сохранения объектов;
  8. Предусмотреть возможность расширенного и краткого отображения информации о ходе процесса. Дать пользователю возможность прервать процесс в любой момент времени;
  9. Предусмотреть возможность запуска процесса из командной строки;
  10. Предусмотреть возможность сохранения всей базы данных в потоке;
  11. Процедура должна обрабатывать миллион записей на компьютере с 512 Мб оперативной памяти за приемлемое время;
  12. Формирование потока данных и загрузка его на базу должна осуществляться не в монопольном режиме.
См. сравнение механизмов репликации и сохранения данных в поток в статье Сохранение в поток и репликация.

Содержание

Сценарии использования сохранения в поток

Сценарий Чего хотим добиться
Пользователь выбирает объект или группу объектов и сохраняет их в поток. Минимум десятикратного ускорения по сравнению с действующим алгоритмом. Меньшего размера файла. Контроля над ходом процесса. Возможности прервать процесс в любой момент времени.
Пользователь указывает сохранить в поток объекты, измененные после указанной даты Аналогично предыдущему. Система производитв базе данных поиск всех объектов, измененных после указанной даты (как быть со множествами?).
Разработчик сохраняет настройку в формате XML. Текстовый файл, содержащий настройку ввиде форматированного XML, можно сравнить с прежней версией настройки и таким образом определить что было изменено. Такие настройки можно помещать в хранилище StarTeam и использовать систему контроля версий.
Пользователь производит загрузку потока на базу данных Ускорения процесса. Контроля над ходом выполнения и возможности прервать процесс в любой момент времени. Внятного разрешения конфликтных ситуаций: Обновлять записи всегда, Обновлять записи только если они новее, чем те, что находятся в базе данных, Пропускать записи. Возможности выставить действие по-умолчанию как для всего процесса, так и для объектов конкретного типа.
Пользователь настраивает однонаправленную репликацию

Увеличение скорости

Беглый анализ показывает, что основной проблемой существующего сохранения является использование рекурсии и бизнес объектов. Сейчас работает так:

  1. начинаем сохранять запись определенного типа (запись бизнес-объекта);
  2. создаем клиент датасет и переносим в него данные полей сохраняемой записи;
  3. записываем в поток служебную информацию и данные клиент датасета;
  4. находим поля-ссылки, создаем экземпляры бизнес-объектов соответствующего типа и рекурсивно вызываем процедуру сохранения в поток, т.е. переходим к п. 1.

Таким образом, в процессе сохранения объект одного и того же типа может создаваться неограниченное число раз.

Итак, первый шаг -- мы отказываемся от рекурсии и будем повторно использовать объект при необходимости. Второй шаг -- отказаться от использования бизнес-объектов. Поскольку, мы не храним данных в ином месте, кроме как в реляционной базе, следовательно все должно сработать правильно и перенестись на другую базу корректно. Отказавшись от бизнес объектов приходится брать на себя анализ структуры базы данных и по главной таблице бизнес объекта (GetListTable) находить все таблицы связанные связью один-к-одному, а так же таблицы элементов множества.

Тут возникает интересный момент: у нас, главная таблица для любого документа -- это gd_document, хотя специфические его данные
хранятся в присоединенной таблице. При анализе связей таблицы gd_document находим 216 ссылающихся таблиц. Пока не ясно, стоит ли 
с этим смириться или каким-то образом отсекать таблицы, связанные с gd_document, но не имеющие отношения к типу сохраняемого
бизнес-объекта.

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

  1. какие таблицы имеют отношение один-к-одному к главной таблице;
  2. какие таблицы имеют ссылку на главную таблицу с доменом MASTERKEY;
  3. какие таблицы входят в SELECT-запрос бизнес-объекта.

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

Почему использование бизнес-объекта замедляет процесс?

  • Бизнес-объект является наследником от класса TIBDataSet и уже в силу этого он медленее при обращении к данным чем легковесный TIBSQL;
  • Формирование, последующий парсинг и переформирование запроса бизнес-объекта занимают значительное время;
  • При создании экземпляра бизнес-объекта в скрипт-контрол загружаются скрипт-функции перекрытых методов;

Использование пула объектов сведет к минимуму затраты по первым двум пунктам, но проблема отключения макросов для конкретного объекта остается не решенной. если решить ее, то можно работать с бизнес-объектами вместо таблиц из базы.

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

Уменьшение размера файла

Уменьшения размера файла мы добьемся за счет отказа от рекурсии при формировании потока данных из-за которой мы имеем следующую внутреннюю структуру файла:

Save stream 1.png

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

Save stream 2.png


Алгоритм сохранения в поток

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты