I. Hratky s Elasticem – Hromadny import JSON

Posledni dobou jsem opet narazil na sve hranice schopnosti a znalosti v Elasticu … neskutecny jak se clovek musi porad ucit. Rozhodl jsem se tedy, ze ty ruzny problemy a jejich reseni budu prezentovat zde. Nejsem zadny datovy expert, ale samouk, a proto muzu obcas psat i blbosti 🙂
Dlouhe roky vyuzivam pro hromadny import JSON dokumentu uzasny nastroj esbulk napsany v Go jazyce: https://github.com/miku/esbulk
Nastroj vyuziva Bulk API Elastiku pro hromadny vkladani JSON dokumentu a za me funguje vytecne. Hromadne takto importuju miliardy radku denne ( z logu Anycastu, proxy, NXD, atd – proste vse co nelze importovat v realnem case).
Obcas ale narazim na use-case kde nepotrebuju vlozit/prepsat nove radky, ale vlozit pouze neexistujici radky, nebo doplnit pouze chybejici polozky, ci updatnout jen nekterou cast dokumentu. Elastic na toto mysli a proto pri Bulk API lze vyuzit, tkzv OpType (operation type) a to: create , index, update a delete. Esbulk vyuzival natvrdo typ „index“
Mam k dispozici dokument domain_1 o obsahu:
"_source" : { "avail" : 0 }
create
Pokud vkladam dokument s neexistujicim ID, je takovy dokument nove zalozen. Pokud vkladam ale dokument s jiz existujicim ID, dostanu chybu ze dokument jiz existuje.
POST /_bulk { "create" : { "_index" : "test_bulk", "_id" : "domain_1"}} { "ip": "10.0.0.1" }
"error" : { "type" : "version_conflict_engine_exception", "reason" : "[domain_1]: version conflict, document already exists (current version [2])", "index_uuid" : "d_-lPsDeQByGOQ35PtZO5g", "shard" : "0", "index" : "test_bulk" }
index
Pokud vkladam dokument s neexistujicim ID, je takovy dokument nove zalozen. Pokud vkladam ale dokument s jiz existujicim ID, tak pri typu index dochazi k prepsani dokumentu kompletne novym obsahem:
POST /_bulk { "index" : { "_index" : "test_bulk", "_id" : "domain_1"}} { "ip": "10.0.0.1" }
Nove me tedy vznikne:
"_source" : { "ip" : "10.0.0.1" }
update
Pokud vkladam dokument s neexistujicim ID, dostanu chybu, ze dokument neexistuje. Pokud ale pridam parametr doc_as_upsert, chova se funkce jako pri create/index a dokument me nove zalozi. Pokud vsak ale vkladam dokument s jiz existujicim ID, nedojde k jeho prepsani jako v pripade index, ale k aktualizaci polozek. Pokud polozka existuje, je zmenena, pokud neexistuje, je vlozena.
POST /_bulk { "update" : { "_index" : "test_bulk", "_id" : "domain_1"}} { "doc" : {"avail": 1, "ip": "10.0.0.1" }, "doc_as_upsert" : true}
dokument je pak nove radne aktualizovany:
"_source" : { "ip" : "10.0.0.1", "avail" : 1 }
A proc ?
A proc to vubec resim ? Muj use-case je totiz takovy slozitejsi. Resim obrovskou databazi domen do ktery chci ukladat data z ruznych zdroju, jejich jedinym spolecnym identifikatorem je domena. Tzn, napriklad mam seznam CZ domen z cctld.cz a ten si nahraju do ES s tim ze id dokumentu bude domena. V takovem pripade pak dostanu do DB informace o registraci, expiraci, registratorovi a DNS. Pak mam nastroj na hromadne overeni domen ktery mi vygeneruje A zaznamy pro existujici a funkcni domeny a cilovy JSON: {„domain“: „domena.cz“,“ip“:“1.2.3.4″}. V pripade ze bych takovy dokument nacetl hromadne metodou index, prepise mi veskere data v DB co mam z puvodniho seznamu, ja ale potrebuju pouze pridat parametr „ip“ ke stavajicim datum. Podobnym zpusobem mam pak dalsi zdroje dat, ktere chci k domenam naimportovat a ziskat tak kompletni prehled. Melo by se s tim dat lepe pracovat hlavne pri hromadnem nahledu, nez pri spojovani ruznorodych zdroju v realnym case a agregacema nad nimi.
Jak na to ?
Bohuzel jsem na to nikdy nemel rozumne reseni a moje bulk operace nebyly moc vykonove efektivni. Jiz v roce 2018 jsem navrhl tuto moznost vyvojari esbulk, ktery si ji dal do ToDo. Tehdy jsem nemel jeste dostatecny koule na to abych pridaval neco do cizich kodu a jeste to nechal zverejnit 😀 Uteklo 2,5 roku a pro moji praci se tato funkce stala nyni naprosto nezbytna. Tak jsem nelenil a tech par radku do toho dopsal 🙂 Poprve v zivote jsem tak zverejnil kus nejaky upravy/opravy kodu a zazadal o pull request (tj o prijmuti mych zmen do jeho kodu) a s naprostou hrdosti musim rict, ze behem par hodin tyto zmeny prijal 🙂
Ve verzi 0.7.2 jiz tedy je nove parametr -optype ktery umoznuje definovat co s dokumentama se bude provadet – index (default), create, update a delete 🙂