logo
17.12.2019 12:49
1
Ahoj.

Čím parsujete velkém JSON soubory, aby to dělalo asi nějak postupně a ohledem na dostupnou pamět. . Musím zpracovat 200 MB JSON a i když mám limit paměti 1GB, tak to nestačí.

Díky za pomoc,

Martin

Co se právě děje na Webtrhu?

17.12.2019 13:13
2
a mas je fakt blbe strukturovany, nebo alespon object per radek ?

ja mam obrovsky pole jednotlivych malych a tam me to vychazi per radek, takze ctu soubor po radku a zpracovavam az ty dilci json stringy
17.12.2019 13:38
3
Musím zpracovat 200 MB JSON a i když mám limit paměti 1GB
nejak ti tu nesedi matika...

osobne neverim ze taky velky json bude jeden objekt. skor pojde o nejake pole(logy?), nie? ak ano tak proste naparsujes jednu hodnotu za druhou.
ak ide naozaj o objekt tak si napis vlastny parser a prechadzaj postupne hodnoty jednu za druhou, len sledujes strom a to je vsetko. prakticky normalny lexer.

ps: 10 sekund googlenia https://github.com/halaxa/json-machine
17.12.2019 14:14
4
pozor, rozložení json na objekty zabere více paměti než je velikost jsonu. Jedna věc je parsování a druhá věc je zpracování, nejlépe, když to celé napíšeš jak micro batching po X položkách najednou, pak jsi schopný parsovat libovolnou velikost. V rámci ETL procesů parsujeme i 1TB jsony.

V php kluci používají https://github.com/Rodenastyle/stream-parser, u některých starších projektů vidím https://github.com/salsify/jsonstreamingparser. Máš-li vlastní vps, je možné použít parsování přes https://github.com/crazyxman/simdjson_php, ale je s tím více nízkoúrovňového experimentování.
17.12.2019 23:55
5
Díky. Zkusím nějaké ty knihovny. Jsou to desetitisíce menších objektů obalené jedním velkým.
18.12.2019 08:11
6
V tomto případě se vykašlat na PHP a použít třeba GOLand. PHP na velké importy prostě není dělané.
18.12.2019 08:25
7
nevidím důvod přecházet na jiný jazyk, 100 mb není velký import, s go musíš řešit znovu věci jako napojení na db, logování, na provoz potřebuješ alespoň vps atd. Když už člověk má linux k dispozici, existuje tam na tohle pěkný balíček jq, kterým je možné data předpřipravit a rozdělit na menší kousky
18.12.2019 10:04
8
a) Goland je IDE, nie jazyk
b) PHP nema problem s importom velkych dat, len musis citat jeden riadok za druhym a nie cely subor naraz(na jazyku nezalezi), co v tomto pripade je problematickejsie
c) "s go musíš řešit znovu věci jako ... logování" ... ???????????????
d) "na provoz potřebuješ alespoň vps atd" ?????????????????????????????????????????????????? ?????????????????????
18.12.2019 10:12
9
ad c) předpokládám, že u aplikace nějak spravuješ a kontroluješ logy, apache s php ti je aspoň někam ukládá a máš je k dispozici, go je běžná aplikace, kde si tyhle zbytečnosti musíš zajistit sám, nic jako error log nemá a pokud si výstup neukládáš, nemáš nic, zmiňuji to, protože přesně na tyhle problémy narážím, když chce někdo pomoc řešit problém s go
ad d) na běžném web hostingu go nespustíš, buď musíš mít nějaký "go hosting", kde zase nefunguje php nebo vlastní vps, kde si spustíš cokoliv
18.12.2019 10:37
10
ok, beriem. technicky mas samozrejme pravdu, ale myslim ze tu zachadzame znacne mimo temy uz a do teritoria ifttt.
18.12.2019 10:55
11
jo, už to je mimo téma, nechtěl jsem to moc rozvádět, ale jen upozornit, že jiný jazyk může přidat více problémů než řeší
19.12.2019 07:23
12
Ano, GOLand je IDE ... měl jsem samozřejmě namysli GOLang. Pokud se bavíme o klasickém hostingu, tak vás stejně kopnou do zadku, když se tam budete snažit importovat tak velký JSON. Většina webhostingu je stejně hodně omezeno na paměť. Co se týče GOLang, tak má samozřejmě spoustu knihoven pro logování atd. Pokud to chceš pomalu a nespolehlivě, dělej importy přes PHP. Pokud to chceš rychle během pár sekund, tak zvol jiný jazyk.
19.12.2019 07:35
13
jak píše node, trik je v tom, že to nesmíš načítat celé do paměti, ale streamovaně zpracovat. PHP7 je na tom s rychlostí dobře a odkazoval jsem knihovny, které tohle umí načíst bleskurychle.

Autor se ptá na poměrně základní věc a tak mu doporučovat jiný jazyk není asi ta nejlepší volba, zůstal bych u php :).
19.12.2019 07:42
14
Původně odeslal TomášX
jak píše node, trik je v tom, že to nesmíš načítat celé do paměti, ale streamovaně zpracovat. PHP7 je na tom s rychlostí dobře a odkazoval jsem knihovny, které tohle umí načíst bleskurychle.

Autor se ptá na poměrně základní věc a tak mu doporučovat jiný jazyk není asi ta nejlepší volba, zůstal bych u php :).
PHP7.x je sice o něco rychlejší, ale i tak je to pomalý šnek. A to píšu jako kovaný PHPkář. Snažil jsem se velké JSON načítat sekvenčně, ale vždy to byl celkem opruz, nebo to fakt nebylo ono. V GoLang se to načítá poměrně snadno právě sekvenčně ... ale nebudu tu už dále psát o tomto jazyku. Jen jsem to chtěl doporučit jako možnou rychlou alternativu.
30.12.2019 14:01
15
Původně odeslal TomášX
Autor se ptá na poměrně základní věc a tak mu doporučovat jiný jazyk není asi ta nejlepší volba, zůstal bych u php :).
Zase ze mně nedělej blba :-). To že se to musí načítat postupně mi bylo jasný už než jsem psal vlákno. Načítal jsem postupně v minulosti 2GB csv a 400 MB XMLko. Čekal jsem jen tip na nějakou knihovnu, protože jsem jednu vyzkoušel, ta mi nešla a nechtěl jsem to dělat pokus omyl. Tak jsem se jen prostě ptal na ověřený postup.

JInak jen pro info, bez použití nějaké knihovny mi na localhostu trvá v PHP dekódování celého jsonu necelé 2 sekundy, jen to zabere 1445 MB paměti a ty prostě na hostingu nemám.

Ale už to je vyřešené jinak.
31.12.2019 08:29
16
Původně odeslal Martin Kejzlar
...
JInak jen pro info, bez použití nějaké knihovny mi na localhostu trvá v PHP dekódování celého jsonu necelé 2 sekundy, jen to zabere 1445 MB paměti a ty prostě na hostingu nemám.
...
Ta paměť je přesně ten důvod, proč na jakékoliv parsování naní PHP vhodné :-). Jak jsi to nakonec vyřešil?
31.12.2019 09:21
17
obcas sa s pamatou da pracovat, len navrh musi byt vymysleny idealne tak, ze data sa spracovavaju postupne a kazda cast ktora je uz spracovana sa nasledne zlikviduje z pamate napr.

priradenim NULL - zmizne hodnota premennej (aj vsetkym referenciam)..

unset zmaze len odkaz na premennu..
31.12.2019 10:14
18
Původně odeslal tomas86
Ta paměť je přesně ten důvod, proč na jakékoliv parsování naní PHP vhodné :-). Jak jsi to nakonec vyřešil?
Je mi jasný, že když třeba Go má nějaké sekvenční načítání v základu, tak to tolik paměti nepotřebuje, ale pokud bych zpracovával v čemkoliv 200 MB json jako celek, tak by snad všechny jazyky potřebovaly dostupnou paměť několikrát vyšší, než je velikost souboru, ne? Uznávám, že 1500 MB je dost, ale třeba těch 600MB by to potřebovalo všude, ne?

Vyřešil jsem to úplně jinak. Zjistil jsem, že kolega má stejná data v XML, takže to beru z toho.
31.12.2019 10:39
19
ked ziskas nespracovany "surovy" json o velkosti 200MB napr. pomocou file_get_contents, bude mat .... no prekvapivo 200MB

mozes ho "rozsekat" parserom napr.

https://github.com/salsify/jsonstreamingparser

jednotlive casti json postupne spracujes, vysledok ulozis, a spracovane data "vynullujes" a takto dookola..

pamat sa ti bude alokovat - 200MB + najvacsi kus spracovanych dat + nejaka rezia

bude to sice pomalsie, ale neprezeries pamat ako pri klasickych rieseniach typu json_encode atd...

nedavno som spracovaval 3000 fotiek (lepil som vodoznak), a memory usage < 80MB .. zaklad je len zahadzovat data, ktore uz su spracovane, a na ich uvolnene miesto pridu dalsie data ktore sa po nich spracovavaju
31.12.2019 16:24
20
Původně odeslal Martin Kejzlar
Je mi jasný, že když třeba Go má nějaké sekvenční načítání v základu, tak to tolik paměti nepotřebuje, ale pokud bych zpracovával v čemkoliv 200 MB json jako celek, tak by snad všechny jazyky potřebovaly dostupnou paměť několikrát vyšší, než je velikost souboru, ne? Uznávám, že 1500 MB je dost, ale třeba těch 600MB by to potřebovalo všude, ne?

Vyřešil jsem to úplně jinak. Zjistil jsem, že kolega má stejná data v XML, takže to beru z toho.
Ono si jaksi nemusíš natáhnout celý JSON/XML/Text... do paměti. Můžeš třeba pracovat jen s části souboru. To pak nebudeš potřebovat tolik paměti. Já jsem tahal několika Gb soubory a tam PHP fakt nestačilo. Přešel jsem na GO ... a s využítím GoRutin a front to šlo hodně rychle. Ale, pokud jsi masochysta, dělej to v PHP :-). Mimochodem, právě ty Rutiny a možnost poslat si v ně programu zprávu, v PHP hodně chybí (spíš je celý koncept jazyka zamýšlen jinak).
31.12.2019 16:35
21
trepes strasne koniny
31.12.2019 17:39
22
Původně odeslal tomas86
Ono si jaksi nemusíš natáhnout celý JSON/XML/Text... do paměti. Můžeš třeba pracovat jen s části souboru. To pak nebudeš potřebovat tolik paměti. Já jsem tahal několika Gb soubory a tam PHP fakt nestačilo. Přešel jsem na GO ... a s využítím GoRutin a front to šlo hodně rychle. Ale, pokud jsi masochysta, dělej to v PHP :-). Mimochodem, právě ty Rutiny a možnost poslat si v ně programu zprávu, v PHP hodně chybí (spíš je celý koncept jazyka zamýšlen jinak).
Limity a obmedzenia kazdeho jazyka su najcastejsie v hlave programatora
03.01.2020 10:43
23
fyi https://hackernoon.com/json-lines-format-76353b4e588d