вторник, 14 сентября 2010 г.

Параллельное выполнение интерфейсов – новое решение.

Сегодня я хочу предложить перевод статьи Cezar Santos об одновременной загрузке данных в одну таблицу несколькими интерфейсами.


Описание проблемы:
Oracle Data Integrator использует имя целевой таблицы как базу для названия временных таблиц ($I, $E, C$), и, поэтому, если больше одного интерфеса, загружающего одну и ту же таблицу, работают одновременно, операции создания, добавления строк или удаления этих временных таблиц могут выполняться вразброд, ломая таким образом весь процесс загрузки.

Решение:

Решение очевидно простое. Необходимо сделать имена временных таблиц изменяющимися и привязать их к каждому выполнению. Лучше всего подходит для этого номер сессии ODI.

Мой подход таков:
Все решения, которые я видел на текущий момент, используют переменную ODI, но сталкиваются с проблемой превышения допустимой длины наименования таблиц.
В этом случае я решил использовать автоматическую обработку длины имени таблицы, которая присутствует в Oracle Data Integrator.

Все, что для этого необходимо сделать это:
1. Изменить все KM (как интеграционные, так и модули загрузки IKM, LKM) добавив в них новый шаг с такими параметрами:

Step name: Parallel Setup
Technology: Java Bean Shell
Code: <? String vSess = odiRef.getSession("SESS_NO"); ?>


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

2. Запустите Менеджер Топологий, и для тех физических схем, в которых предполагается параллельное выполнение (или для всех, если есть такое желание) измените префиксы временных таблиц на такие:

E$_<?=vSess?>
C$_<?=vSess?>
I$_<?=vSess?>


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

Ну и самое главное - это очень просто.


Ввиду такой простоты решения, у него достаточно недостатков, на которые обратили внимание те, кто данную статью откомментировал. Итак, недостатки решения:

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

2. Таблица с ошибками ($E_) с предыдущего запуска не будет просмотрена очередным запуском интерфейса.

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

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

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

См. также: Многотабличность интерфейсов ODI.

2 комментария:

  1. А не лучше ли вместо номера сессии использовать номер интерфейса(odiRef.getPop("I_POP"))? Проблема со временными таблицами отпадает, т.к. номер интерфейса остается прежним

    ОтветитьУдалить
  2. Тут вопрос, на самом деле, несколько иначе нужно ставить. В оригинальной статье речь шла о том, что если мы имеем стандартные модули знаний, то вот таким вот способом, который описан, можно быстро, на коленке, соорудить нечто помогающее делать параллельную загрузку.
    Если же нам требуется полноценное решение, это решение неизбежно будет затрагивать модули знаний. Т.е. приведет к их некой модификации.
    И для этой модификации уже можно думать, как поступить лучше. В этом смысле можно использовать как odiRef.getPop("I_POP"), так и просто добавить опцию в модуль знаний, в котором каким-либо образом указывать модификатор имени для временных таблиц.

    ОтветитьУдалить