fv_2007
Agile innovative developer with deep insight into all shapes of lightweight technologies such as ROA, REST and Ruby. Absolute “early adopter” in Web 2.0 technologies, platforms and Framework. Large professional network and fervent speeches at the conference level on architecture, strategy, design patterns, restful services, object-oriented thinking and modeling languages. Special interest in language constructs based on a deep knowledge of programming languages such as Smalltalk, Erlang, Java, Clojure, Scala, Ruby ... read more
View Frank Vilhelmsen's profile on LinkedIn Recommend Me

Scaling Enterprise Java on 64-bit MultiCore November 01, 2008 17:51 2 months ago

Jeg skal hastighedsoptimere en Java applikation. Den skal performe max på kortest mulige tid. Den kan ikke skalere udad som man normalt ville ønske men kun opad. Det vil sige en enkelt supermaskine med 16 CPU’er og 16G ram i 64bit software.

I de senere år er kravet om hurtigere CPU hastigheder er faldet mens kravet om antal CPU’er er steget. Grunden er at en hurtig processor bruger mere strøm end to processorer på den samme kraft og man udnytter altså forholdet mellem ydeevne og forbrug.

Problemet med at skalere en Java applikation er først og fremmest at Java ikke kan udnytte en ægte multicore arkitektur så den ønskede effektivitet kan opnås. Man kan tilføre så mange CPU’er man vil men Java kan ikke udnytte dem. Dog kan man sige at sige at Java processerne får mere frihed idet de andre processer på maskinen som fx databaser kan køre på andre cores.

Selve Java applikationen er en heterogen monolitisk struktur og den skal eksekveres som en 32bit applikation. Det vil sige at den kun kan udnytte 2G hukommelse eller mindre. Det betyder desværre også at man skalere på den laveste fællesnævner.

Men hvad sker der når man flytter en applikation fra en dual core maskine til en ægte fysisk 16 core maskine? Min interesse i sagen er kun henvendt på i hvilken udtrækning Java kan udnytte de mange processorer. Hvis Java kun kan udnytte en processor må applikationen kunne køre på samme vis som på andre duals maskiner. Hvad ville der ske hvis Java kunne udnytte flere CPU’er og de enkelte processer udsættes for ægte samtidighed, altså potentielt mange samtidige eksekvererne tråde i samme objekt?

To ting vakte min opmærksomhed. Dels en memory leak og dels en slags forvirring omkring konfiguration og resourcer som fx databaseforbindelser. Memory leaks i applikationen skyldes bla ikke frigjorte værdier fra hukommelsen. Den andre adfærd var mere underlig. Applikationen kunne køre skiftevis langt før en tilstand reageret på manglede resourcer.

Til min store overraskelses opdager jeg efter flere timers debug session at problemet ligger i ThreadLocal objektet i Java eller rettere dem måde man bruger dem på. Applikations designeren binder databaseforbindelser i disse tråd relaterede objekter. Når en container tråd dør tager den de lokale objekter med sig. Men når 64bit maskinen bestemmes sig for at skifte CPU mister alle threadlocals konteksts. Det betyder at konfiguration og resources bliver frigivet midt i kørselen.

ThreadLocal har været en meget brugt strategi gennem mange år og benyttes til at bære fx et ID gennem en applikation både i en tråd men jeg vil påstå at det er et antipattern at benytte den til andet fx databaseforbindelser.

læs: Thread-local storage

Efter udbedrelse af problemerne køre softwaren fint på 64bit maskinen. Java installationen bruger to, måske tre CPU’er til at eksekvere Java softwaren. Når man skalere er det ønskeligt at kunne skalere lineært, altså ved en fordobling af kraft forøger man hastighed gange to. Reelt set køre denne Java applikation på en af de 16 hurtige CPU ad gange og udnyttelsen af den fine hardware stinker max.

Hvis man vil kunne skalere sine applikationer må man skrive dem til multicore.

Small Things, Loosely Joined, Written Fast


By Frank Vilhelmsen - 3 tags: java scaling multicore - Add comment