Як ми NoSQL в «реляционку» реплицировали

У наші дні NoSQL продовжує набирати популярність, але мало хто знає, що нереляційні СУБД з'явилися набагато раніше навіть самої реляційної алгебри. 40 і навіть 50 років тому в первинному «бульйоні», що зароджується IT індустрії «варилися» тільки NoSQL-продукти. І що найцікавіше – продукти, народжені в ті складні часи, живі до цих пір і прекрасно себе почувають.
Одним з таких продуктів стала СУБД GT.m, розроблена компанією Graystone Tehnologies в 70-80-х роках минулого століття. СУБД знайшла широке застосування в медицині, страхування та банківській сфері.

У нашому банку ми теж використовуємо GT.m, і цей інструмент прекрасно справляється з обробкою великої кількості транзакцій. Але… Є одна проблема: GT.m ніякої для аналітики, в ньому немає SQL, аналітичних запитів і всього того, що робить фінансового аналітика щасливим. Тому ми розробили власний «велосипед» для реплікації даних GT.m в «реляційні» СУБД.


А ось тут повинна була бути картинка з літаючим велосипедом

Всіх зацікавлених запрошуємо під кат.


Ппб… Не хочеш ще трохи GT.m? Вже в ті доісторичні часи GT.m мала (чи мав) потримаю ACID, серіалізацію транзакцій і наявність індексів і процедурного мови MUMPS. До речі, MUMPS – це не просто мова, це цілий напрямок, що з'явилося ще в 60-х роках 20 століття!

Однією з найбільш успішних і популярних MUMPS-based СУБД стала Caché, і ви, швидше за все, чули про неї.

Основою MUMPS СУБД, є ієрархічні структури – глобаль. Уявіть JSON, XML або структуру папок і файлів на вашому комп'ютері – приблизно те ж саме. І всім цим наші батьки і діди насолоджувалися до того, як це стало мейнстрімом.
Один важливий момент – у 2000 році СУБД стала Open Source.

Так от, старенька GT.m надійна і, незважаючи на свої похилі роки, обслуговує велика кількість специфічних транзакцій без будь-яких зусиль на відміну, наприклад, від своїх SQL побратимів (фраза, звичайно, холиварная, але для нас це факт: на певному навантаженні NoSQL все ж спритніше SQL). Проте всі проблеми починаються тоді, коли нам потрібно зробити найпростішу аналітику, передати дані в аналітичні системи або, не дай бог, автоматизувати все це.

Довгий час вирішенням даної проблеми були всюдисущі «вивантаження». CSV файли формувалися процедурами, написаними на мові M (MUMPS), і кожна така вивантаження розроблялася, тестувалася і впроваджувалася висококваліфікованими фахівцями. Зусилля, витрачені на розробку кожної вивантаження, були величезними, а вміст двох різних выгрузок могло істотно перетинатися між собою. Траплялося таке, що замовники вимагали вивантаження, на кілька полів відмінні від існуючих, і доводилося робити все заново. При цьому сама мова M код досить важкий для розуміння і читання, що тягне за собою додаткові «витрати» як на розробку, так і на підтримку всього цього хардкода.



Рішення з выгрузками

ODS (Operational Data Store)

У нас вже був реалізований архітектурний патерн під назвою ODS (Operational Data Store), в який ми реплицируем наші джерела з мінімальними відставаннями від 2 секунд до 15 хвилин.

Дані з ODS ми завантажуємо в сховище даних (DWH) або будуємо за ним оперативні звіти. І з реляційними СУБД типу Oracle, MS SQL, Sybase і т. д. немає проблем – вантажимо таблиці джерел в ті ж самі таблиці на ODS.



Ми дуже хотіли реалізувати подібну реплікацію GT.m в ODS.
Але як же вантажити NoSQL структури в прості таблиці? Як, наприклад, завантажити клієнта, у якого може бути 2 телефону, а може і 22?



Ми розуміли, що правильніше буде організувати реплікацію на основі бінарних логів СУБД (в інших СУБД вони називаються WAL, Redo, transaction log тощо), благо, GT.m журналирует кожну транзакцію, змінювану дані. При цьому на ринку вже існували готові продукти, одним з яких є Evolve Replicator від компанії CAV systems.

Evolve CAV systems

Evolve читає журнали транзакцій, трансформує їх і записує рядок у таблиці вже на реляційному приймачі.

Але була одна зовсім маленька проблема – це рішення нам не підходило… В наших структурах була велика кількість обчислюваних значень (Computed Data Items або CDI).

Спробую пояснити на пальцях. Це чимось нагадує «віртуальне поле» у таких СУБД, як Oracle, в яких значення не зберігається, а обчислюється на момент звернення до цього поля. При цьому CDI може мати досить складну логіку і базуватися на даних з дочірніх вузлів і т. д. І, як ви напевно вже здогадалися, такі Computed Data Items неможливо відтворити з журналів СУБД, так як інформація з ним там не зберігається, тому що в журнали записуються тільки зміни фізичних полів. Але такі поля-привиди нам дуже потрібні для аналітики, у них складна логіка, і мати аналітичну репліку без цих полів було б безглуздо.

Реалізувати подібну логіку з обчислюваними полями у репліці – нереально. По-перше, через продуктивності, по-друге – переписувати весь цей хардкод з мови М на SQL – справа невдячна.



FIS Profile

Крім рівня даних, в нашій системі ми маємо і рівень додатків, написаних на мові М. Так, в наші часи це звучить дико, але більшість банківських систем до сих пір живуть в парадигмі двухзвенной архітектури.

Таким додатком є FIS Profile (далі Profile) – це автоматизована банківська система, повністю інтегрована з GT.m. Крім функцій автоматизації банківської діяльності, Profile забезпечує наступний функціонал:
1. Найпростіший SQL select * from table where id=1)
2. Доступ до даних JDBC
3. Подання глобалів в табличний вигляд, при цьому один глобал може бути представлений в кілька різних таблиць
4. Тригери
5. Секьюрность
По суті, ми маємо ще одну СУБД поверх іншої СУБД. При цьому одна з них буде реляційної, а інша – NoSQL.

Profile є повністю пропрієтарним ПЗ, але є і Open Source аналоги, наприклад, Vista Fileman.


Логічні рівні нашої GT.m-системи.

Реалізація концепції

Для реплікації NoSQL-структур даних в SQL СУБД в першу чергу необхідно:

1. Уявити глобаль в табличному вигляді.
При цьому один вузол «дерева» може бути представлений у вигляді декількох, пов'язаних між собою таблиць. Таку можливість вже надає Profile, і все, що нам потрібно, – це правильно налаштувати такі табличні уявлення. Завдання хоч і складна, але цілком вирішувана.

2. Захоплення змін.
На жаль, наявність CDI в нашій системі не дозволяє зробити правильну реплікацію» з журналів СУБД. Єдиний можливий варіант – логічна реплікація тригерами. Змінилося значення в таблиці – тригер це відловив і записав зміна в журнальну таблицю. До речі, журнальна таблиця – це той же самий глобал. Зараз все самі побачите!

Ось так виглядає типовий глобал:



Розуміємо, виглядає як мінімум… дивно, але в ті далекі роки поняття краси були зовсім іншими. Структура глобал також називається багатовимірним розрідженим масивом». І ключ – це як би координата даних, які в ньому лежать.
До речі, за «даними» можна також будувати індекси, що буває дуже зручно для табличного подання.

Власне, з такої глобал ми можемо отримати 2 таблиці:

TABLE_HEADER


TABLE_SHED — лог змін


До речі, числові значення перетворилися в дати, наприклад, для поля TJD.

За наявними таблиць виконується запит


де:
:STARTPOINT – дата останнього запуску;
'Т' – поточна дата (виглядає як мінімум дивно, але ця функція – аналог sysdate() або now() в нормальних інших СУБД)

Як ми бачимо, відбувається з'єднання «таблиць»; за фактом з'єднання локальне, в межах кожного вузла, що не створює істотної навантаження.

3. Вибірка даних з журнальних таблиць і подальша їх передача в ODS.
Існував на той момент даних JDBC-драйвер чудово працював з атомарними запитами, але викликав витоку пам'яті під час масованих операцій Select. Наявний драйвер довелося значно переписати.

4. Доставка та застосування змін.
Дуже важливий аспект – швидке застосування даних на приймачі. Якщо GT.m успішно справляється з великою кількістю атомарних транзакцій, то для реляційних СУБД типу Oracle це несе велике навантаження. При цьому в наш ODS ллються дані з великої кількості інших джерел (всього близько 15).
Для вирішення цієї проблеми, необхідно збирати такі операції в пачки і застосовувати їх групою. Такі операції називаються Bulk і повністю залежать від специфіки СУБД приймача.


Поточна архітектура реплікації

Наше додаток – до речі, ми його назвали Profile Loader – завантажує в ODS два типи таблиць: журнальні і дзеркальні. Ми постараємося розповісти про ODS в майбутніх статтях, але якщо коротко, то:
журнальні таблиці – таблиці логів змін, ці таблиці зручні для инкрементальной завантаження, наприклад, в аналітичні системи і DWH
дзеркальні таблиці – таблиці, що містять у собі повну копію даних джерела, такі таблиці можна використовувати для аудиту і для оперативної аналітики.

5. Пункт управління.
Для зручного адміністрування ми зробили веб-мордочку для запуску і зупинки потоків реплікації. Та й взагалі, вся основна логіка була написала на Java, що дозволило використовувати вже готові Open Source компоненти для вирішення якихось специфічних кейсів.

Завдання, які вирішуються SQL реплікою

1. Позбавлення від розрізнених выгрузок. Ми отримали єдине вікно для всіх споживачів даних.
2. Аудит. Спрощується процедура аудиту за рахунок того, що дані лежать в зручному вигляді, а міць SQL дозволяє зручно і швидко оперувати цими даними.
3. Якість даних. Наприклад, в GT.m всього 2 типу даних – числовий і рядковий. Коли дані прилітають в ODS, вони перетвориться в інші види, у тому числі й на дати. Якщо дата в неправильному форматі, ми можемо легко відловлювати такий інцидент і покращувати якість даних вже на джерелі.
4. Обчислення инкремента для подальшого завантаження в DWH.

Подальші шляхи розвитку

На майбутнє плануємо реалізувати наступне:
1. Повністю позбавитися від існуючих CSV-выгрузок. Зараз вони все ще живі, але ми їх будемо потихеньку «відстрілювати».
2. Оптимізувати деякі проблеми з продуктивністю.
3. Поділитися ідеями з зацікавленим співтовариством, можливо і підтримувати проект OpenSource.
4. Спробувати інтеграцію з Oracle GoldenGate на рівні доставки змін.
5. Можливо, зробити зворотний репліку (додаткову, не ODS) Replica -> GT.m, для сервісних процесів підвищення якості даних.
6. Розвивати оперативну звітність поверх ODS.

Резюме

У статті ми розповіли про наше дітище – Profile Loader і про те, як NoSQL дані можна аналізувати в SQL СУБД. Дане рішення можливо не зовсім правильне і елегантне, але воно прекрасно працює і виконує покладені на нього зобов'язання.

Якщо ви вирішите повторити свою NoSQL БД в «реляционку» для зручної аналітики, в першу чергу оцініть обсяги змін, модель даних і можливості тих технологій, які все це будуть забезпечувати.

Бажаємо успіхів у ваших починаннях!
Завжди готові відповісти на ваші питання.

P. S. Також висловлюємо подяку колегам, які брали участь та активно допомагали у проекті: Шевельову Дмитру, Чебанову Миколі, Бубону Роману, Бистрову Денису, Бейспекову Кайсару, Люфко Андрію, Кудюрову Павлу, Воробйову Сергію, Лисих Сергію, Кулешову Денису, Никитчик Олені, Мушкет Ользі, Чечеткиной Юлії, Пасынкову Юрію та колегам з CAV Systems і FIS.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.