
Мы — отдел развития технологий розничной сети. Однажды руководство поставило задачу ускорить объемные вычисления за счет использования Apache Ignite в связке с MSSQL, показало сайт с прекрасными иллюстрациями и примерами Java-кода. На сайте сразу понравился , описание которого обещает чудеса: you don’t have to manually deploy your Java or Scala code on each node in the grid and re-deploy it each time it changes. По ходу работы оказалось, что Zero Deployment обладает спецификой использования, особенностями которой я и хочу поделиться. Под катом размышления и подробности реализации.
1. Постановка задачи
Суть задачи в следующем. Есть справочник точек продаж SalesPoint и справочник товаров Sku (Stock Keeping Unit). Точка продаж имеет атрибут «типМагазина» со значениями «малый» и «большой». К каждой точке продаж подключается (загружается из СУБД) ассортимент (список товаров точки продаж) и подается информация о том, что с указанной даты указанный товар
исключается из ассортимента или добавляется в ассортимент.
Требуется организовать партиционированный кеш точек продаж и хранить в нем информацию о подключенных товарах на месяц вперед. Совместимость с боевой системой требует от клиентского узла Ignite загружать данные, вычислять агрегат вида (типМагазина, кодТовара, день, число_точек_продаж) и выгружать его обратно в СУБД.
2. Изучение литературы
Опыта пока что нет, так что начинаю плясать от печки. То есть с обзора публикаций.
Статья 2016 года содержит ссылку на документацию проекта Apache Ignite и заодно упрек в невнятности этой документации. Перечитал пару раз, ясность не наступает. Обращаюсь к официальному туториалу PC1-in ip ünvanını ağ qlobal ip ünvanı 91.105.8.10-a çevirir
оптимистично обещает «You’ll be up and running in a jiffy!». Разбираюсь с настройками переменных среды, смотрю два видео Apache Ignite Essentials, для моей конкретной задачи они оказались не очень полезны. Успешно запускаю Ignite из командной строки со стандартным файлом «example-ignite.xml», собираю первое приложение с помощью Maven. Приложение работает и использует Zero Deployment, какая красота!
Читаю дальше, а там пример сразу использует affinityKey (создан ранее через SQL-запрос), да еще и применяется загадочный BinaryObject:
IgniteCache<BinaryObject, BinaryObject> people
= ignite.cache("Person").withKeepBinary(); Почитал : бинарный формат — что-то вроде рефлексии, доступ к полям объекта по имени. Может читать значение поля без полной десериализации объекта (экономия памяти). Но зачем вместо Person используется BinaryObject, ведь есть Zero Deployment? Зачем IgniteCache<Key,Person> переводится в IgniteCache<BinaryObject, BinaryObject>? Пока неясно.
Переделываю Compute Application под свой случай. Первичный ключ справочника точек продаж в MSSQL определен как [id] [int] NOT NULL, создаю кеш по аналогии
IgniteCache<Integer, SalesPoint> satış nöqtəsiCache=ignite.cache("spCache")XML konfiqurasiyasında mən partitioned cache göstərirəm
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="spCache"/
>
<property name="cacheMode" value="PARTITIONED"/
>
<\/bean>Satış nöqtələrinə görə partionlaşdırma, tələb olunan agregatın hər bir klaster düyünündə orada olan satış nöqtəsiCache qeydləri üçün qurulacağını güman edir, bundan sonra müştəri düyünü cəmi əməliyyatını yerinə yetirir.
Təlimatı oxuyuram , analoji edirəm. Hər bir klaster düyünündə IgniteRunnable() işə salıram, təxminən belə:
@Override
public void run() {
SalesPoint sp=satış nöqtəsiCache.get(spId);
sp.calculateSalesPointCount();
..
}Agregasiya və çıxarma məntiqini əlavə edir, test məlumatları dəstində işə salıram. Yerlərdəki inkişaf serverində hər şey işləyir.
İki test serveri CentOs işə salıram, ip ünvanlarını default-config.xml-də göstərirəm, hər birində yerinə yetirirəm
.\/bin\/ignite.sh config\/default-config.xmlHər iki Ignite düyünü başlayır və bir-birini görür. Müştəri tətbiqi XML konfiqurasiyasında uyğun ünvanları göstərir, işə düşür, üçüncü düyünü topologiyaya əlavə edir və dərhal düyünlərin sayı yenidən iki olur. Log daxiləsində «ClassNotFoundException: model.SalesPoint» qeyd olunur
SalesPoint sp=satış nöqtəsiCache.get(spId);StackOverflow deyir ki, xətanın səbəbi — CentOs serverlərində istifadəçi sinfi SalesPoint yoxdur. Çatdıq. «Java kodunuzu hər bir düyünə əl ilə yerləşdirməyə ehtiyac yoxdur» ilə necə gedir? Yoxsa «Java kodunuz» — bu SalesPoint ilə bağlı deyil?
Görünür, nəsə qaçırdım — yenidən axtarışa başlayıram, oxumağa başlayıram və yenidən axtarıram. Bir müddət sonra mövzu üzrə hər şeyi oxuduğum kimi bir hiss başlayır, artıq yeni bir şey yoxdur. Axtararkən, bir neçə maraqlı qeydlər tapdım.
, GridGain Systems-də baş memar, StackOverflow-da, aprel 2016:
Model sinifləri tərəfdaş olaraq yerləşdirilmir, lakin siz cache-də withKeepBinary() flaqını istifadə edə bilərsiniz və BinaryObjects ilə sorğu verə bilərsiniz. Bu yolla siz server tərəfdə deserializasiya etmələrini qarşısını alacaqsınız və ClassNotFoundException almayacaqsınız.Yenə bir nüfuzlu fikir: , GridGain Systems-də məhsul idarəçiliyi direktoru.
Habrda məqalə Denis Magda-dan üç məqaləyə istinad edir: , , 2016-2017-ci illər. İkinci məqalədə Denis klaster düyününü MaintenanceServiceNodeStartup.jar vasitəsilə başlamağı təklif edir. XML konfiqurasiyası və komanda xətti ilə başlamaq da mümkündür, amma bu zaman istifadəçi siniflərini hər dəfə yerləşdiriləcək klaster düyünlərinə əllə qoymalısınız:
That's it. Start (..) düyünü MaintenanceServiceNodeStartup faylı ilə işə salın və ya maintenance-service-node-config.xml-i Apache Ignite-in ignite.sh/bat skriptlərinə verin. Əgər sonuncunu üstün tutursunuzsa, java/app/common və java/services/maintenance kataloglarındakı bütün sinifləri ehtiva edən bir jar faylı yaradılmasına əmin olun. Jar hər bir düyünün classpath-i əlavə edilməlidir.Həqiqətən, that’s it. Aydındır ki, bu gizli ikili formatın səbəbi budur!
3. SingleJar
Denis, şəxsi reytinqimdə birinci yerə yüksəldi, imho burada ən faydalı təlimatdır. Onun GitHub-da tam hazır bir cluster node konfigürasyonu örneği bulunmaktadır; bu, her türlü ekstra çaba harcamadan derleniyor.
Ben de benzer şekilde yapıyorum ve komut satırı argümanına bağlı olarak "data node" veya "client node" çalıştıran tek bir jar dosyası alıyorum. Derleme başlatılıyor ve çalışıyor. Zero Deployment yenildi.
Test verilerinin megabaytlarından savaş alanı verilerinin on gigabaytlarına geçiş, ikili formatın varlığının nedenini gösterdi. Node'larda bellek tüketimini optimize etmek gerekti, ve işte burada BinaryObject çok faydalı oldu.
4. Sonuçlar
Apache Ignite projesinin belgelendirmesindeki ilk karşılaştığım belirsizlik eleştirisi geçerli çıktı; 2016'dan bu yana pek bir şey değişmedi. Yeni başlayanlar için web sitesi ve/veya depodan çalışan bir prototip oluşturmak zor.
Yapılan çalışmaların sonucunda, Zero Deployment'ın yalnızca sistem düzeyinde çalıştığı izlenimi oluştu. Yaklaşık şöyle: BinaryObject, cluster'ın uzak node'larını kullanıcı sınıflarıyla çalışmaya öğretmek için uygulanıyor; Zero Deployment — Apache Ignite'ın iç mekanizmasıdır ve cluster genelinde sistem nesnelerini dağıtır.
Apache Ignite'ın kendisinin sistem nesnelerini dağıtan bir mekanizmasıdır.
Umuyorum ki tecrübem, Apache Ignite'ın yeni kullanıcıları için faydalı olacaktır.
Mənbə: habr.com
