Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Stream processing en mémoire avec Hazelcast Jet par Claire VILLARD

143 vues

Publié le

Hazelcast Jet est un nouveau venu sur le marché des solutions de Stream Processing distribué. Appuyé sur la grille de données en mémoire bien connue Hazelcast In-Memory Data Grid, ce nouveau produit (version 0.3 publiée en février 2017) mérite que l’on s’y intéresse malgré sa jeunesse.

Je vais présenter ses fonctionnalités majeures, ses points forts et faibles actuels, et la roadmap annoncée de ce qui sera peut-être un produit incontournable du Stream Processing dans les années à venir.

Publié dans : Business
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Stream processing en mémoire avec Hazelcast Jet par Claire VILLARD

  1. 1. Stream Processing en mémoire avec HazelCast Jet Claire Villard neur0nia leneurone/hz-jet 1 / 14
  2. 2. Claire Villard Développeuse Java depuis 2011 Société V3D Travaille avec HazelCast IMDG depuis 2 ans Membre de Duchess France Organisatrice du LyonJUG 2 / 14
  3. 3. Qu'est-ce qu'HazelCast IMDG ? IMDG = In-Memory Data Grid, Grille de données en mémoire Stockage distribué de structures de données (Map, List, AtomicLong, ...) Calcul distribué sur ces structures Clustering Java-based Open-source 3 / 14
  4. 4. Qu'est-ce qu'HazelCast Jet ? Solution de stream et batch processing basée sur HazelCast IMDG Sauf mention contraire, les schémas proviennent de https://jet.hazelcast.org/ 4 / 14
  5. 5. Modélisation Utilise les graphes orientés acycliques (DAG, Directed Acyclic Graphs) 5 / 14
  6. 6. Fonctionnalités Nombreuses entrées / sorties Faible latence Contrôle du débit Support des traitements batchs comme des streams finis Sliding windows Facilement extensible En v0.5 : Tolérance aux crashs de noeuds avec redémarrage des jobs Garantie de traitement "au moins 1", "exactement 1" ou "au mieux" des messages 6 / 14
  7. 7. Roadmap Déjà annoncé production-ready v0.4 sortie le 14 juin 2017 Release 0.5 : octobre 2017 1.0 : prévue début 2018 APIs instables jusqu'à la v1.0 7 / 14
  8. 8. En pratique 8 / 14
  9. 9. DAG DAG dag = new DAG(); // Création des noeuds de traitement Vertex source = dag.newVertex("source", Sources.readMap("inputMap")); Vertex enricher = dag.newVertex("enricher", MetricEnricher::new); Vertex output = dag.newVertex("output", Sinks.writeMap("outputMap")); Vertex errorOutput = dag.newVertex("errorOutput", Sinks.writeMap("errorOutputMap")); // Création des arêtes du graphe entre les noeuds dag .edge(Edge.between(source, enricher)) .edge(Edge.from(enricher, 0).to(output)) .edge(Edge.from(enricher, 1).to(errorOutput)); // Démarrage de Jet JetInstance jet = Jet.newJetInstance(); // Démarrage du Job et attente du résultat jet.newJob(dag).execute().get(); 9 / 14
  10. 10. Processor public class MetricEnricher extends AbstractProcessor { private IMap<Integer, Customer> customerMap; // IMap des Customers @Override protected void init(@Nonnull Context context) throws Exception { // Utilisation de l'instance HazelCast sous-jacente customerMap = context.jetInstance().getHazelcastInstance().getMap("customers"); } @Override protected boolean tryProcess0(@Nonnull Object item) throws Exception { Metric metric = (Metric) item; // On tente de trouver le customer associé à la métrique dans une IMap Customer customer = customerMap.get(metric.getCustomerId()); // On choisit l'arête du graphe à utiliser if (customer != null) { return tryEmit(0, new EnrichedMetric(metric, customer)); } else { return tryEmit(1, metric); } } } 10 / 14
  11. 11. Stream Processing public class QueuePoller extends AbstractProcessor { private IQueue<Metric> inputQueue; // Queue d'entrée @Override protected void init(@Nonnull Context context) throws Exception { inputQueue = context.jetInstance().getHazelcastInstance().getQueue("inputQueue"); } // Utilisation d'un thread dédié obligatoire car poll(int, TimeUnit) est bloquante public QueuePoller() { setCooperative(false); } @Override public boolean complete() { try { Metric metric = inputQueue.poll(20, TimeUnit.MILLISECONDS); if(metric != null) { tryEmit(metric); } return false; // execution infinie tant que complete() retourne false } catch (Exception e) { return true; // arrêt de l'exécution } } } 11 / 14
  12. 12. Performances Intel® Core™ i7-5600U CPU @ 2.60GHz × 4 16Go RAM Fedora 26 64 bits JVM Oracle HotSpot 1.8.0_121 Configuration de Jet par défaut, 2 noeuds locaux Batch processing - 1 million de Metric Temps moyen d'exécution du Job : 22s, soit environ 45 400 items / seconde Stream processing Injection de Metric dans la queue et calcul de la latence totale Latence moyenne : 2 ms, latence max. sur 100 000 éléments : 27 ms 12 / 14
  13. 13. Limitations Qualité de la documentation... Pas de typage des entrées, sorties, ou arêtes entre noeuds, tout est Object. 13 / 14
  14. 14. Merci ! leneurone/hz-jet 14 / 14

×