Využití cachování na disk u virtuálního stroje (Java, .NET)

anonym

Mám takový záludný dotaz. Řeším parsování několika gigabajtového XML souboru a jeho vkládání do databáze. Klasická možnost je zrpacovávat ho líně v proudu. Mě ale napadla ještě jedna možnost a to, zpracovat ho prostě najednou s tím, že nastavím parametrem virtuálnímu stroji, např. JVM, maximální obsazení paměti spouštěnou aplikací s tím, že co je navíc, si bude JVM sám nějak cachovat na disk.

Zásadní výhoda je, že kód bude tímto jednoduchý. Prostě načtu celé XML, celé ho naráz deserializuju a jednotlivé objekty nastrkám do DB.

Nevýhoda je jenom ta, že na disku budu muset mít volné místo, což jaksi v dnešní době neberu jako problém a taky, že pokud se tento několikaminutový proces zastaví, nebudu mít na co navázat. Řekněme, že mi to nevadí.

Problém je v tom, že vlastně nevím, jestli toto virtuální stroj umí a nějak se mi to nedaří ani googlit. Potřebuju to pro .NET, ale nevadí mi ani řešení pro JVM. Tak kdo je tady JVM/.NET ninja?


Lopata

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #1 kdy: 28. 01. 2018, 14:16:27 »
A v čem vám v tomto případě nevyhovuje proudové zpracování? Nebo nevyhovuje jen proto, že vás napadla jiná možnost? Různá řešení (streamy) tu jsou proto, aby se jimi vyřešily určité problémy (nutnost načtení celého souboru do paměti), takže pokud nemáte jiný kritický požadavek, např. náhodné čtení ze souboru, tak raději nevymýšlejte řešení "přes ruku", která zřejmě beztak nebudou fungovat.

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #2 kdy: 28. 01. 2018, 14:17:39 »
JVM to rozhodně neumí. A to především z toho důvodu, že je to velmi špatný nápad.

Pokud opravdu chceš, tak to umí samotný OS - stačí mít nedostatek fyzické paměti, případně konfigurací donutit kernel aby agresivně všechno cpal do swapu. A pak uvidíš proč je to špatně - než to dotrashuje do konce, tak budeš mít hotovou a odladěnou implementaci přes streaming API (mimochodem, v tomto případě doporučuji zvážit pull API).

První pravidlo provozování JVM: limit paměti (Xmx + metaspace + stack*threads) musít být takový, aby se vešel do fyzické paměti a nikdy se neocitl ve swapu (tj. ještě musí zbýt místo na ostatní procesy, včetně věcí jako např. puppet).

tnr

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #3 kdy: 28. 01. 2018, 14:21:48 »
Nic takoveho JVM neumi a je to navic blbost, to by bylo jednoznacne pomalejsi nez SaX. To, co popisujes, resi swap v OS :)

Udelat to pomoci streamingu (SaX) je navic velmi jednoduche - staci si udelat stavovy automat reagujici na jednotlive elementy v XML (coz z principu neni vubec slozite), data ukladat do fronty a v jinem vlaknu frontu vyprazdnovat a plnit do DB.

Jedinym problemem by mohlo byt to, pokud to XML obsahuje propojena data (ze v jednom okamziku potrebujes data z ruznych nesouvisejicich mist) - to by byl samozrejme problem, pak by bylo potreba to zrejme drzet v pameti.

Ale na druhou stranu 1 GB neni nic velkeho, takze pokud te netrapi vykon, nebo je to moc propojene a slozite na proudove zpracovani, tak to proste nacti do pameti, JVM to zvladne v pohode, pokud ma server dostatek RAM.

anonym

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #4 kdy: 28. 01. 2018, 14:30:50 »
JVM to rozhodně neumí. A to především z toho důvodu, že je to velmi špatný nápad.

Pokud opravdu chceš, tak to umí samotný OS - stačí mít nedostatek fyzické paměti, případně konfigurací donutit kernel aby agresivně všechno cpal do swapu. A pak uvidíš proč je to špatně - než to dotrashuje do konce, tak budeš mít hotovou a odladěnou implementaci přes streaming API (mimochodem, v tomto případě doporučuji zvážit pull API).

První pravidlo provozování JVM: limit paměti (Xmx + metaspace + stack*threads) musít být takový, aby se vešel do fyzické paměti a nikdy se neocitl ve swapu (tj. ještě musí zbýt místo na ostatní procesy, včetně věcí jako např. puppet).

Já teď deserializuju tak, že:

1. Proudově čtu XML se serializovanými objekty do bufferu a po určité velikosti dávky ji uzavřu na úrovní Root nodu. Tím dostanu menší, validní XML, které rovněž představuje serializovaný List<Trida>.
2. Nad tímto malým XML volám XMLSerialize.deserialize(). Chci použít XMLSerialize, protože mám k XMLku XSD soubor, ze kterého si můžu automatizovaně přes utilitku XSD.exe vygenerovat modelové třídy. Do těch modelových tříd samozřejmě umí XMLSerialize automaticky data nastrkat.

Bohužel se mi nelíbí, že to dlouho trvá. 1000000 záznamů asi 5 vteřin. Chtěl bych to mít rychlejší, ale to bych musel upravit parsování přes XMLReader a to by mi zkomplikovalo život. Protož mě napadlo vypustit celý krok č. 1 a nechat si to swapovat přes disk virtuálním strojem, že to jakože třeba bude mít optimalizovanější.


anonym

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #5 kdy: 28. 01. 2018, 14:35:14 »
Já tam totiž, kvůli tomu, že XMLSerialize neumí načítat data líně, dělám 2x jednu a tu samou operaci:

1. Parsuju to xml přes XMLReader, element po elementu
2. XMLSerialize dela znovu uplne to same, element po elementu parsuje XML v paměti.

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #6 kdy: 28. 01. 2018, 14:58:33 »
Jak píšou ostatní, není důvod, aby tohle řešil virtuální stroj, protože přesně tohle dělá swap operačního systému.

Pokud to, co zpracováváte, je dlouhý seznam menších objektů, dá se to řešit tak, že do DOMu načtete vždy ten menší objekt, a když ho zpracujete, rovnou ho uvolníte z paměti. Např. Javovská knihovna dom4j pro to má podporu – v FAQ si najděte „How does dom4j handle very large XML documents?“.

Re:Využití cachování na disk u virtuálního stroje (Java, .NET)
« Odpověď #7 kdy: 29. 01. 2018, 00:55:22 »
Není mi jasné, proč nemůžete to několika gigové xml načíst do paměti celé bez swapu? Je na tom stroji málo paměti? Pak by to mohl možná  zachránit swap na extra rychlý SSD disk, ale hádám, že to bude i tak řádově pomalejší.

Pokud je málo RAM, tak mě ještě napadá nějaká on the fly komprese - zram nebo něco xml-specifického.

Jinými slovy - nejste jediný, kdo pracuje s velkým xml a chce mít jednoduchý kód, jak to dělají ostatní?