Introduction à Apache Pulsar

Introduction à Apache Pulsar

Présentation d'Apache Pulsar, ses fonctions principales faite au meetup Paris Data Engineers en juin 2019.

Bc34f46fdfa199da05a78f26584ecec3?s=128

Bruno Bonnin

June 20, 2019
Tweet

Transcript

  1. Introduction à Apache Pulsar Bruno Bonnin Meetup #ParisDataEng - 20

    juin 2019
  2. Directeur technique @ Zenika Nantes

  3. None
  4. Pulsar, un système de messagerie distribué Né chez Yahoo !

    pour compenser certaines limites des solutions de l’époque Pour des apps critiques comme Yahoo Mail, Yahoo Finance, Yahoo Sports, etc Open sourcé en 2016 Devenu Top Level Project de la fondation Apache en sept 2018 Premier déploiement Q2 2015
  5. Pulsar, un système de messagerie distribué Données répliquées et enregistrées

    sur disque Garantie d’ordre des messages Réplication géographique des données Multi-entité (tenant) Fort débit / Faible latence Garantie de livraison Hautement scalable
  6. Concepts & architecture

  7. Des producteurs, des consommateurs, des topics, ... Topic 1 Producteur

    Consommateur Topic 2 Topic 3
  8. Gestion des messages Producteurs Stockage des messages Bookie 1 Bookie

    2 Bookie 3 Bookie 4 Consommateurs zkServer 1 zkServer 2 zkServer 3 Broker 1 Broker 2 Broker 3 lecture stockage meta-données coordination clusters stockage meta-données stockage des données Des brokers, des bookies, ... écriture Apache BookKeeper Apache Zookeeper
  9. Bookie 1 Une architecture scalable Broker 1 Broker 2 Bookie

    2 Bookie 3 Bookie 4 Gestion des messages Stockage des messages Producteurs Consommateurs Broker 3 Bookie 5 Topic 1
  10. None
  11. Apache BookKeeper Système de stockage scalable, tolérant aux pannes et

    à faible latence Conçu à l’origine comme une solution pour la haute disponibilité du NameNode de HDFS (WAL) Avec Pulsar: stockage des données et des offsets (cursors)
  12. Broker Topic 1 segment 2 segment 1 segment x ...

    Bookie 1 segment 1 Une architecture hautement disponible segment 1 segment 1 segment x segment x segment 2 segment 2 Bookie 2 Bookie 3 Un topic est constitué d’un ensemble de segments (ledgers) contenant les messages. Les segments sont stockés et répartis sur les bookies. segment x segment 2 Bookie 4
  13. Broker Topic 1 segment 2 segment 1 segment x ...

    Bookie 1 segment 1 Une architecture hautement disponible segment 1 segment 1 segment x segment x segment 2 segment 2 Bookie 2 Bookie 3 Sur défection d’un bookie, automatiquement, récupération des segments manquants pour respecter le facteur de réplication segment x segment 2 Bookie 4 segment x segment 1
  14. Modes de consommation

  15. Topic Producteur Consommateur - A1 Exclusive subscription Subscription A Consommateur

    - A2 Les tentatives de connexions de A2 échoueront Topics et abonnements
  16. Topic Producteur Consommateur - B1 Fail-over subscription Subscription B Consommateur

    - B2 Messages consommés par B2, uniquement en cas d’échec de B1 Topics et abonnements
  17. Topic Producteur Consommateur - C1 Subscription C Consommateur - C2

    Les messages sont envoyés aux n consommateurs (round robin) -> aucune garantie d’ordre ! Topics et abonnements Shared subscription
  18. Topic Producteur Consommateur - B1 Consommateur - B2 Consommateur -

    A1 Consommateur - C1 Consommateur - C2 Exclusive Subscription Il peut y avoir plusieurs abonnements sur un topic Fail-over Subscription Shared Subscription Topics et abonnements
  19. Les messages

  20. Messages Contenu d’un message: - Tableau d’octets (peut être conforme

    à un schéma) - Clé (optionnel) - Ensemble de propriétés (optionnel) - Nom du producteur - Id de séquence (numéro d’ordre dans le topic, attribué par le producteur) - Timestamps
  21. Cycle de vie des messages Avec rétention message acquitté message

    acquitté Messages supprimés (hors rétention) Messages gardés car dans la période de rétention Non traités message acquitté message acquitté message non acquitté message non acquitté Messages supprimés Messages supprimés car au-delà du TTL Non traités et encore dans le TTL message non acquitté message non acquitté message non acquitté message non acquitté message acquitté message acquitté Avec TTL message acquitté message acquitté Messages supprimés Non traités (sauvegardés dans BookKeeper) message non acquitté message non acquitté message acquitté message acquitté Cas nominal
  22. Développons avec Pulsar

  23. + API WebSocket

  24. // Création d’un client (idem producteur et conso) PulsarClient client

    = PulsarClient.builder() .serviceUrl("pulsar://myhostname:6650") .build(); .authentication(...) .connectionsPerBroker(5) .ioThreads(10) .keepAliveInterval(2, TimeUnit.MINUTES) .maxNumberOfRejectedRequestPerConnection(5) .operationTimeout(10, TimeUnit.SECONDS) ...
  25. Producer<byte[]> producer = client.newProducer() .topic("demo-topic") .producerName("demo-producer") .batchingMaxPublishDelay(10, TimeUnit.MILLISECONDS) .sendTimeout(10, TimeUnit.SECONDS)

    .blockIfQueueFull(true) .create(); MessageId msgId = producer.send("Hi Folks !".getBytes()); producer.sendAsync("Hi Folks !".getBytes()) .thenAccept(msgId -> { System.out.printf("Msg %s successfully sent", msgId); });
  26. Consumer consumer = client.newConsumer() .topic("demo-topic") .subscriptionName("demo-exclusive-sub") .subscriptionType(SubscriptionType.Exclusive) .subscribe(); // Lecture

    à partir du premier message non acquitté Message msg = consumer.receive(1000, TimeUnit.SECONDS); System.out.printf("Message: %s, from %s with id=%s\n", new String(msg.getData()), msg.getProducerName(), msg.getMessageId()); consumer.acknowledge(msg);
  27. Multi-tenancy

  28. Multi-tenancy Type de topic Nom de l’entité (tenant) Nom du

    namespace Nom du topic persistent://public/default/demo-topic
  29. Multi-tenancy Pulsar Cluster Products Ops Tenants Logs Orders Namespaces Stores

    2To Topics Rétention: 10j Topic-2 Topic-1 Topic-1 Topic-1 persistent://Products/Stores/Topic-1
  30. Geo-replication

  31. Réplication géographique Cluster A Topic 1 Producteur 1 Cluster B

    Topic 1 Producteur 2 Cluster C Topic 1 Producteur 3 Les topics doivent appartenir à un namespace global Réplication asynchrone ou synchrone (persistence local d’abord, puis envoi aux autres clusters) Possibilité pour un producteur de restreindre la réplication à des clusters donnés
  32. Pulsar Functions

  33. Pulsar Functions Topic de sortie F But: offrir un cadre

    d’exécution de traitements des données sans utiliser d’environnement complémentaire Topic d’entrée 1 Peut s’exécuter: dans les brokers, en local, et à terme, dans des containers (déploiement dans Kubernetes) Topic d’entrée 2 Topic des logs
  34. import java.util.function.Function; public class HiFunction implements Function<String, String> { @Override

    public String apply(String input) { return String.format("Hi %s!", input); } }
  35. def process(input): return "Hi %s!" % input

  36. $ pulsar-admin functions create \ --jar hifct.jar --className HiFunction \

    --fqfn talk/demo/hello \ --inputs persistent://talk/demo/input \ --output persistent://talk/demo/output
  37. import org.apache.pulsar.functions.api.Context; import org.apache.pulsar.functions.api.Function; import org.slf4j.Logger; public class EnhancedHiFunction implements

    Function<String, String> { @Override public String process(String input, Context context) throws Exception { Logger logger = context.getLogger(); String functionTenant = context.getTenant(); String functionNamespace = context.getNamespace(); String functionName = context.getFunctionName(); logger.info("Function {}/{}/{}: input={}", functionTenant, functionNamespace, functionName, input); return String.format("Hi %s!", input); } }
  38. $ pulsar-admin functions create \ --jar enhancedhifct.jar \ --className EnhancedHiFunction

    \ --fqfn talk/demo/hello \ --inputs persistent://talk/demo/input \ --output persistent://talk/demo/output \ --log-topic persistent://talk/demo/logs
  39. Démo

  40. # Lancement de tous les composants # broker, bookie, zookeeper

    (pour des tests/dev) $ pulsar standalone $ pulsar-admin clusters list standalone $ pulsar-admin clusters get standalone { "serviceUrl":"http://hostname:8080", "brokerServiceUrl": "pulsar://hostname:6650" }
  41. # Producteur: 100 messages, 1msg/sec $ pulsar-client produce \ -m

    "hello" \ -n 100 -r 1 \ demo-topic # Consommateur: 1msg/sec sans arrêt $ pulsar-client consume \ -n 0 -r 1 \ -s "demo-subs-exclusive" \ -t Exclusive \ demo-topic
  42. # Multi-tenancy # - création entité $ pulsar-admin tenants create

    talk # - création namespace $ pulsar-admin namespaces create talk/demo # - ajout de quotas $ pulsar-admin namespaces set-retention \ --size 1T --time 2d talk/demo
  43. Gestion des messages Brokers Stockage Bookies En résumé... Traitements Pulsar

    Functions Connecteurs Pulsar IO Analytics Pulsar SQL (Presto) Stockage tiers AWS Google Azure HDFS Clients Producteurs / Consommateurs
  44. Auto-promo : https://github.com/bbonnin/pulsar-express

  45. Conclusion Il existe beaucoup de fonctions intéressantes (plus ou moins

    matures): - découplage broker et stockage - gestion par segments - tier-storage, - geo-replication, - Pulsar IO - Pulsar Functions - Schema registry, - SQL, - … Environnement complet pour couvrir vos besoins en termes de stream processing Aujourd’hui chez Yahoo ! - > 2 millions de topics - > 100 milliards de messages / jour - > 150 brokers Plus d’infos: https://streaml.io/blog
  46. Merci ! @_bruno_b_ Illustrations: https://undraw.co/illustrations