Ми – відділ розвитку технологій роздрібної мережі. Якось керівництво поставило завдання прискорити об'ємні обчислення за рахунок використання Apache Ignite у зв'язці з MSSQL, показало сайт із чудовими ілюстраціями та прикладами Java-коду. На сайті одразу сподобався
1. Постановка задачі
Суть завдання у наступному. Є довідник точок продажу SalesPoint та довідник товарів Sku (Stock Keeping Unit). Точка продажу має атрибут «типМагазина» зі значеннями «малий» та «великий». До кожної точки продажу підключається (завантажується із СУБД) асортимент (список товарів точки продажу) та подається інформація про те, що з вказаної дати вказаний товар
виключається з асортименту або додається до асортименту.
Потрібно організувати партиціонований кеш точок продажу та зберігати в ньому інформацію про підключені товари на місяць наперед. Сумісність із бойовою системою вимагає від клієнтського вузла Ignite завантажувати дані, обчислювати агрегат виду (типМагазина, кодТовара, день, число_точок_продажів) і вивантажувати його назад у СУБД.
2. Вивчення літератури
Досвіду поки що немає, тож починаю танцювати від грубки. Тобто з огляду на публікації.
Стаття 2016 року
оптимістично обіцяє "You'll be up and running in a jiffy!". Розбираюсь із налаштуваннями змінних середовища, дивлюся два відео Apache Ignite Essentials, для мого конкретного завдання вони виявилися не дуже корисними. Успішно запускаю Ignite з командного рядка зі стандартним файлом «example-ignite.xml», збираю перший додаток
Читаю далі, а там приклад одразу використовує affinityKey (створений раніше через SQL-запит), та ще й застосовується загадковий BinaryObject:
IgniteCache<BinaryObject, BinaryObject> people
= ignite.cache("Person").withKeepBinary();
Почитав
Переробляю Compute Application під власний випадок. Первинний ключ довідника точок продажу в MSSQL визначений як [id] [int] NOT NULL, створюю кеш за аналогією
IgniteCache<Integer, SalesPoint> salesPointCache=ignite.cache("spCache")
У XML-конфізі вказую, що кеш партиціонований
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/>
<property name="cacheMode" value="PARTITIONED"/>
</bean>
Партиціонування за точками продажів передбачає, що необхідний агрегат буде побудований на кожному вузлі кластера для записів salesPointCache, що є там, після чого клієнтський вузол виконає підсумкове підсумовування.
Читаю туторіал
@Override
public void run() {
SalesPoint sp=salesPointCache.get(spId);
sp.calculateSalesPointCount();
..
}
Додаю логіку агрегації та розвантаження, запускаю на тестовому наборі даних. Локально на сервері розробки все працює.
Запускаю два тестові сервери CentOs, вказую ip-адреси в default-config.xml, виконую на кожному
./bin/ignite.sh config/default-config.xml
Обидва вузли Ignite запускаються та бачать один одного. Вказую потрібні адреси в xml-конфізі клієнтської програми, він запускається, додає третій вузол у топологію і відразу вузлів стає знову два. У лозі значиться "ClassNotFoundException: model.SalesPoint" у рядку
SalesPoint sp=salesPointCache.get(spId);
StackOverflow каже, що причина помилки - на серверах CentOs немає класу користувача SalesPoint. Приїхали. Як же «ти не маєш manual manual deploy your Java code on each node» і далі за текстом? Чи "your Java code" - це не про SalesPoint?
Мабуть, я щось упустив — знову починаю шукати, читати і знову шукати. Через якийсь час виникає відчуття, що я прочитав по темі все, нічого нового вже немає. Поки шукав, знайшов кілька цікавих зауважень.
Model classes are not peer deployed, but you can use withKeepBinary() flag
on the cache and query BinaryObjects. This way you will avoid deserialization
on the server side and will not get ClassNotFoundException.
Ще одна авторитетна думка:
Стаття на Хабре
That's it. Start (..) node using MaintenanceServiceNodeStartup file or pass
maintenance-service-node-config.xml to Apache Ignite's ignite.sh/bat scripts.
If you prefer the latter then make sure to build a jar file that will contain
all the classes from java/app/common and java/services/maintenance directories.
The jar has to be added to the classpath of every node where the service
might be deployed.
Справді, що це. Ось він, виявляється, навіщо цей загадковий бінарний формат!
3. SingleJar
Denis посів у моєму особистому рейтингу перше місце, імхо найкорисніший туторіал з усіх доступних. В його
Роблю за образом і подобою, отримую єдиний файл jar, який запускає «data node» чи «client node» залежно аргументу командного рядка. Складання запускається і працює. Zero Deployment переможений.
Перехід від мегабайтів тестових даних до десятків гігабайтів бойових показав, що бінарний формат існує недаремно. Потрібно оптимізувати витрати пам'яті на нодах, і ось тут BinaryObject виявився дуже корисним.
4. висновки
Перший закид у незрозумілості документації проекту Apache Ignite виявився справедливим, з 2016 року змінилося небагато. Новачку непросто зібрати функціонуючий прототип на основі сайту та/або репозиторію.
За підсумками виконаної роботи склалося враження, що Zero Deployment працює, але лише на системному рівні. Приблизно так: BinaryObject застосовується, щоб навчити віддалені вузли кластера працювати з класами користувача; Zero Deployment – внутрішній механізм
самого Apache Ignite і розповсюджує за кластером системні об'єкти.
Сподіваюся, мій досвід буде корисним для нових користувачів Apache Ignite.
Джерело: habr.com