Top Banner
#backdaybyxebia William Montaz - Jean-Pascal Thiery Construire le SI de demain Chercher la performance efficace
73

Backday xebia - Chercher la performance efficacement

Jul 27, 2015

Download

Technology

Xebia France
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

William Montaz - Jean-Pascal Thiery

Construire le SI de demain

Chercher la performance efficace

Page 2: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

La performance, c’est quoi ?« Mon Application, elle poutre ! »

« Il faut moins de 2 heures à mon batch pour s`exécuter.»

« Mon algorithme utilise moins de 10% du CPU.» 

- Ensemble de données chiffrables

- Des niveaux de tolérance qui dépendent du type de traitement.

Page 3: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

La performance, pourquoi ?

Make it work

Make it right

Make it fast

Page 4: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

La performance, quand ?

Tests de performance Production

Cycle de développement

Page 5: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

La performance, comment ? L’environnement :

Page 6: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

La performance, comment ? L’environnement, les extras :

JMX

Page 7: Backday xebia - Chercher la performance efficacement

#backdaybyxebia#perfEfficace @willymontaz @jpthiery

Injecteurs

Graphite

Gatling

Gatling

Gatling

La performance, comment ?

Jenkins

JenkinsSlave

JenkinsSlave

JenkinsSlave

EntrypointAppA

Grafana

Report Gatling

Page 8: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Une démarche, quelques idées

Page 9: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

BIG THANKSKodewerk, Kirk Pepperdine

Java Performance Tuning

Page 10: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Démarche séquentielle

Page 11: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

J’utilise bien mon OS ?

- CPU - Mémoire - IO

Page 12: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

J’utilise bien ma JVM ?

- Optimisation de bytecode - Gestion de la mémoire

Page 13: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Mon application est-elle efficace ?

- Architecture - Algorithmes

Page 14: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Mon application est-elle bien utilisée ?

- Utilisation de l’application par des éléments extérieurs (utilisateurs, applications tierces, batchs, etc…)

Page 15: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Page 16: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

2 questions

Page 17: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Suis-je seul ?

OS

Page 18: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

TOP (!)

OS

Page 19: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

J’utilise 100% du CPU ?

OS

Page 20: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

CS -> 80 000 cycles, 6000CS pour 2GHZ -> 24% context switching

Context Switch Context Switch

Context Switch

OS

Syscall

Page 21: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

context switch ?SchedulingLockingI/OSyscall

OS

Page 22: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

context switch ?SchedulingLockingI/OSyscall

OS

+10% CPU Kernel space -> Problème

Page 23: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Dead lock

Problème d’I/O : Disque, Network, Système externe

Scheduling CPU par l’hyperviseur

Problème de scheduling OS

Je n’utilise pas 100% du CPU

OS

Page 24: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

vmstat OS

Page 25: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Page 26: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

HotSpot

JVM

Page 27: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

JIT Compiler

JVM

Page 28: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

JIT Compiler => 10 000 appels (CompileThreshold)

JVM

Page 29: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Huge Methods

JVM

Page 30: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Huge Methods => 8k bytecode, pas de compilation !

JVM

Page 31: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Inlining

JVM

Page 32: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Inlining: auto si < 35 bytes bytecode325 bytes pour les « Hot Methods »

JVM

https://github.com/AdoptOpenJDK/jitwatch/wiki/JarScan

Page 33: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Call Stack & Récursivité

JVM

Page 34: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Chargement/Déchargement de classloader

JVM

Page 35: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Coût de création des objets

JVM

Page 36: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Coût de création des objetsExemple :

Object foo = cache.get(val1 + ‘’-‘’ + val2)

JVM

Page 37: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Coût de création des objetsExemple :

Object foo = cache.get(val1 + ‘’-‘’ + val2)

Object foo = cache.get(new Key(val1, val2))

JVM

NB: en java 8, la concaténation de string est optimisée par le compilateur

Page 38: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Garbage Collection

JVM

Page 39: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Mark & Sweep

JVM

Page 40: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

JVM

Page 41: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

MarkJVM

Page 42: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

SweepJVM

Page 43: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Hypothèse générationnelle

Beaucoup d’objets sont transients Seulement quelques objets ont une longue durée de vie

JVM

Page 44: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Eden/Young Tenured/Old

Survivor 1/2

JVM

Page 45: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Eden/Young Tenured/Old

Survivor 1/2

JVM

Page 46: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Eden/Young Tenured/Old

Survivor 1/2

JVM

Page 47: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Promotion • Tenuring Threshold

JVM

Page 48: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Promotion • Tenuring Threshold • Survivor plein

JVM

Page 49: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Roots ?

JVM

Page 50: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Roots ?stack frames

JVM

Page 51: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Roots ?stack frames References JNI

JVM

Page 52: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Roots ?stack frames References JNI Class loaders

JVM

Page 53: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Roots ?stack frames References JNI Class loaders Objets dans le Tenured Space !

JVM

Page 54: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Young GenerationSerialCollectorParallelGC

+ Efficace si beaucoup d’objets morts - Stop-of-the world

JVM

Page 55: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

GC Old GenerationSerial (-XX:+UseParallelGC)Parallel (-XX:+UseParallelOldGC par défaut sur Java 7u4) + Pas d’overhead + Compaction de la heap - Stop-of-the-world

Concurrent Mark-and-Sweep (CMS -XX:+UseConcMarkSweepGC)+ (Presque) pas stop-of-the-world - Overhead CPU (10-40%) - Fragmentation !! Peut déclencher des FullGC

JVM

Page 56: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Combinaison des GCuint i = 0; if (UseSerialGC) i++; if (UseConcMarkSweepGC || UseParNewGC) i++; if (UseParallelGC || UseParallelOldGC) i++; if (UseG1GC) i++; if (i > 1) { jio_fprintf(defaultStream::error_stream(), "Conflicting collector combinations in option list; " "please refer to the release notes for the combinations " "allowed\n"); status = false; }

JVM

Page 57: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Log GCBeaucoup d’infos Exploitables directement dans des outils dédiés

GCViewer Censum

-verbose:gc -XX:+PrintGCDetails -XX:+PrintTenuringDistribution

-Xloggc:filename

JVM

Page 58: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Memory LeakJVM

Page 59: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Memory LeakHEAP DUMP -> Memory Analysis Tool

JVM

Page 60: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

JIT Friendly Chauffer la JVM Eviter les changements de class loaders Choisir un GC adapté (throughput vs disponibilité) Aider le GC si besoin (référence null) Dimensionner correctement les pools

Notamment les survivors ! Utilisez les log GC

JVM

Ajout suite à la présentation -> Essayer de passer en Java 8 +15% de performances Utilisation du GC G1 qui peut résoudre d’un coup beaucoup de problèmes de GC

Page 61: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

OS

JVM

Application

Actors

Page 62: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

APP

Detecter les problèmes de lock

Page 63: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Detecter les problèmes de lock

THREAD DUMP !

APP

Page 64: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Detecter les problèmes d’architecture/d’algorithme

Utiliser un profiler VisualVM JProfiler

Faire des benchmarks Pas d’instrumentation Reflet de la réalité (caches CPU, TLB, paging, …)

APP

Page 65: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Le benchmarking, c’est très dur !!

Optimisations JIT Chauffe de la JVM Profile-guided optims Loop unrolling, Dead code

False sharing Déclenchement de GC Synchronisation des threads Variance

APP

Page 66: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

JMH

public class JMHSample_03_States {

@State(Scope.Thread) public static class ThreadState { volatile double x = Math.PI; }

@Benchmark public void measureUnshared(ThreadState state) { state.x++; }

public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(JMHSample_03_States.class.getSimpleName()) .warmupIterations(5) .measurementIterations(5) .threads(4) .forks(1) .build();

new Runner(opt).run(); }

}

APP

Page 67: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Problèmes fréquents

Pas de cache

APP

Page 68: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Problèmes fréquents

Pas de cache Mauvaise utilisation des collections

Mauvaise implémentation : ConcurrentHashMap

ConcurrencyLevel (LockStriping/Segment jdk < 1.8) Lock

ConcurrentSkipListMap LockFree

Pas de sizing initial

APP

Page 69: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Problèmes fréquents

Pas de cache Mauvaise utilisation des collections

Mauvaise implémentation : ConcurrentHashMap

ConcurrencyLevel (LockStriping/Segment jdk < 1.8) Lock

ConcurrentSkipListMap LockFree

Pas de sizing initial Logs

Trop de logs Trop de processing

Date -> timestamp

APP

Page 70: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Problèmes fréquents

Pas de cache Mauvaise utilisation des collections

Mauvaise implémentation : ConcurrentHashMap

ConcurrencyLevel (LockStriping/Segment jdk < 1.8) Lock

ConcurrentSkipListMap LockFree

Pas de sizing initial Logs

Trop de logs Trop de processing

Date -> timestamp Serialisation

APP

Page 71: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Problèmes fréquents

Pas de cache Mauvaise utilisation des collections

Mauvaise implémentation : ConcurrentHashMap

ConcurrencyLevel (LockStriping/Segment jdk < 1.8) Lock

ConcurrentSkipListMap LockFree

Pas de sizing initial Logs

Trop de logs Trop de processing

Date -> timestamp Serialisation Pool sous/sur-dimensionné

Circuit breaker

APP

Page 72: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

Pratiques Low Level:

NIOepollFileChannels

Algos LockFreeVolatile, Compare And Swap

Affinité de cacheL1: 32KB 1ns (4 c), L2: 256KB 3-4ns (12 c), L3: plusieurs MB (30c) 12-15ns, RAM 70-100nsMemory Acces Patterns :

affinité temporelle, affinité spaciale, predictible

Translation Lookaside Buffers (TLB)Virtual Pages -> Physical pages in page tableTLB -> cache local pour éviter le parcours de la « page table »Utiliser les Huge Pages (4MB) -> plus d’adresses mémoire dans les TLB

APP

Page 73: Backday xebia - Chercher la performance efficacement

#backdaybyxebia

http://openjdk.java.net/projects/code-tools/jmh/

http://www.7-cpu.com/cpu/SandyBridge.html

http://mechanical-sympathy.blogspot.fr/2013/07/java-garbage-collection-distilled.html

Dmitry Vyazelenko

http://martinfowler.com/articles/lmax.html

http://mechanical-sympathy.blogspot.fr/2012/08/memory-access-patterns-are-important.html

JDK (!)

Martin Thompson

Martin Fowler

Lecture