Распоредување на Apache Ignite Zero: навистина нула?

Распоредување на Apache Ignite Zero: навистина нула?

Ние сме оддел за развој на технологија на малопродажната мрежа. Еден ден, менаџментот постави задача да ги забрза пресметките од големи размери со користење на Apache Ignite во врска со MSSQL и покажа веб-локација со прекрасни илустрации и примери на Java код. Веднаш ми се допадна страницата Нулта распоредување, чиј опис ветува чуда: не мора рачно да го распоредувате вашиот Java или Scala код на секој јазол во мрежата и повторно да го распоредувате секој пат кога ќе се промени. Како што напредуваше работата, се покажа дека Zero Deployment има специфични намени, чии карактеристики сакам да ги споделам. Под сечењето се мисли и детали за имплементацијата.

1. Изјава за проблемот

Суштината на проблемот е како што следува. Постои директориум за продажни точки на SalesPoint и директориум за производи Sku (Единица за чување акции). Продажното место има атрибут „Тип на продавница“ со вредности „мало“ и „големо“. Со секое продажно место е поврзан асортиман (список на производи на продажното место) (вчитан од DBMS) и се дава информација дека од наведениот датум наведениот производ
исклучени од асортиманот или додадени во асортиманот.

Потребно е да се организира поделена кеш на продажни места и да се складираат во неа информации за поврзаните производи еден месец однапред. Компатибилноста со борбениот систем бара Ignite клиентскиот јазол да вчита податоци, да пресмета агрегат од формуларот (тип на продавница, код на производ, ден, број_на_продажни_поени) и да го подигне назад во DBMS.

2. Изучување на литературата

Сè уште немам искуство, па почнувам да танцувам од шпоретот. Тоа е, од преглед на публикации.

член 2016 година Ви го претставуваме Apache Ignite: First Steps содржи линк до документацијата на проектот Apache Ignite и во исто време укор за нејасноста на оваа документација. Го препрочитав неколку пати, јасност не доаѓа. Се повикувам на официјалниот туторијал започнувањеКои
оптимистички ветува „Ќе трчаш за кратко време!“ Ги откривам поставките за променливата на околината, гледам две видеа на Apache Ignite Essentials, но тие не беа многу корисни за мојата конкретна задача. Успешно го стартував Ignite од командната линија со стандардната датотека „example-ignite.xml“, градејќи ја првата апликација Пресметај апликација користејќи Maven. Апликацијата работи и користи Zero Deployment, каква убавина!

Прочитав понатаму, и таму примерот веднаш користи affinityKey (создаден порано преку барање SQL), па дури и го користи мистериозниот BinaryObject:

IgniteCache<BinaryObject, BinaryObject> people 
        = ignite.cache("Person").withKeepBinary(); 

го прочитав малку: бинарен формат - нешто како рефлексија, пристап до полињата на објектот по име. Може да ја чита вредноста на полето без целосно да го десерилизира објектот (заштеда на меморија). Но, зошто се користи BinaryObject наместо Person, бидејќи постои Zero Deployment? Зошто IgniteCache префрлен во IgniteCache ? Сè уште не е јасно.

Ја преправам апликацијата Compute за да одговара на мојот случај. Примарниот клуч од директориумот на продажни места во 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 достапни таму, по што клиентскиот јазол ќе го изврши финалното сумирање.

Го читам туторијалот Прва апликација Ignite Compute, јас го правам тоа по аналогија. На секој јазол на кластерот извршувам IgniteRunnable(), нешто вака:

  @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 вели дека причината за грешката е што нема прилагодена класа SalesPoint на серверите CentOs. Стигнавме. Што велите за „не мора рачно да го распоредувате вашиот Java код на секој јазол“ и така натаму? Или „вашиот Java код“ не е за SalesPoint?

Веројатно нешто пропуштив - повторно почнувам да барам, да читам и повторно да барам. После некое време добивам чувство дека прочитав се на темава, веќе нема ништо ново. Додека барав, најдов неколку интересни коментари.

Валентин Куличенко, водечки архитект во GridGain Systems, одговори на StackOverflow, април 2016 година:

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.

Друго авторитативно мислење: Денис Магда, Директор за управување со производи, GridGain Systems.

Статија на Хабре за микросервисите упатува на три статии од Денис Магда: Микроуслуги Дел I, Микроуслуги Дел II, Микроуслуги Дел III 2016-2017 година. Во втората статија, Денис предлага да се започне кластерски јазол преку MaintenanceServiceNodeStartup.jar. Можете исто така да користите стартување со конфигурација на xml и командна линија, но потоа треба рачно да поставите сопствени класи на секој распореден јазол на кластерот:

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.Единечно Тегла

Денис го зазеде првото место во мојот личен рејтинг, IMHO најкорисното упатство од сите достапни. Во неговиот MicroServicesExample Github содржи целосно готов пример за поставување кластерски јазли, кој се компајлира без дополнително сквотирање.

Јас го правам тоа на ист начин и добивам една датотека jar која стартува „јазол на податоци“ или „јазол на клиент“ во зависност од аргументот на командната линија. Монтажата започнува и работи. Нулта распоредување е поразена.

Преминот од мегабајти тест податоци на десетици гигабајти борбени податоци покажа дека бинарниот формат постои со причина. Беше неопходно да се оптимизира потрошувачката на меморија на јазлите, и тука се покажа дека BinaryObject е многу корисен.

4. Заклучоци

Првиот укор на кој се сретнавме за нејасноста на проектната документација Apache Ignite се покажа како праведен; малку се промени од 2016 година. Не е лесно за почетник да состави функционален прототип врз основа на веб-страница и/или складиште.

Врз основа на резултатите од сработеното, впечатокот беше дека Zero Deployment функционира, но само на системско ниво. Нешто вака: BinaryObject се користи за да ги научи далечинските јазли на кластери да работат со сопствени класи; Нулта распоредување - внатрешен механизам
Самиот Apache Ignite и дистрибуира системски објекти низ кластерот.

Се надевам дека моето искуство ќе биде корисно за новите корисници на Apache Ignite.

Извор: www.habr.com

Додадете коментар