Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Stream processing avec Apache Pulsar

Bruno Bonnin
December 11, 2019

Stream processing avec Apache Pulsar

Présentation de Apache Pulsar et de ses possibilités pour le développement d'applications de Stream Processing, faite lors de Paris Open Source Summit 2019.

Bruno Bonnin

December 11, 2019
Tweet

More Decks by Bruno Bonnin

Other Decks in Technology

Transcript

  1. Topic 1 Producteur 2 Consommateur 1 Topic 2 Topic 3

    Producteur 1 Consommateur 2 Consommateur 3
  2. 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
  3. Bookie 1 Broker 1 Broker 2 Bookie 2 Bookie 3

    Bookie 4 Producteurs Consommateurs Broker 3 Bookie 5
  4. Broker segment 1 Bookie 1 segment 1 segment 1 segment

    1 Bookie 2 Bookie 3 topic ensemble de segments Bookie 4
  5. 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é message acquitté message acquitté Messages supprimés Non traités (sauvegardés dans BookKeeper) message non acquitté message non acquitté message acquitté message acquitté
  6. Type de topic Nom de l’entité (tenant) Nom du namespace

    Nom du topic persistent://public/default/demo-topic
  7. Cluster A Topic 1 Producteur Cluster B Topic 1 Cluster

    C Topic 1 Consommateur topics namespace global asynchrone synchrone persistence local d’abord restreindre la réplication Producteur
  8. # Installation “à l’ancienne”: # >>>> https://pulsar.apache.org $ wget http://.../pulsar/apache-pulsar-2.4.1-bin.tar.gz

    $ tar xzf apache-pulsar-2.4.1-bin.tar.gz # Lancement de tous les composants # broker, bookie, zookeeper (pour des tests/dev) $ pulsar standalone
  9. # Producteur: 100 messages, 1msg/sec $ pulsar-client produce \ -m

    "Hello Open Source Summit !" \ -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
  10. // 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) ...
  11. Producer<byte[]> producer = client.newProducer() .topic("demo-topic") .producerName("demo-producer") .... .create(); // Envoi

    synchrone MessageId msgId = producer.send("Hi OS Summit!".getBytes()); // Envoi asynchrone (retourne une CompletableFuture) producer.sendAsync("Hi OS Summit!".getBytes()) .thenAccept(msgId -> { System.out.printf("Msg %s successfully sent", msgId); });
  12. 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); // A ne pas oublier
  13. // Côté consommateur Consumer<Order> consumer = client.newConsumer(JSONSchema.of(Order.class)) .topic("orders") ... .subscribe();

    Message<Order> msg = consumer.receive(1000, TimeUnit.SECONDS); Order order = msg.getValue();
  14. // Exemple le plus simple, sans framework import java.util.function.Function; public

    class HiFunction implements Function<String, String> { @Override public String apply(String inputMsg) { return String.format("Hi %s!", inputMsg); } }
  15. 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); } }
  16. if ("US".equals(order.country()) context.publish("sales/online/orders-us", order); else context.publish("sales/online/orders-not-us", order); public Order process(Order

    order) { if (order.total() > 10000) return order; // Envoi vers le topic des “grosses” commandes return null; }
  17. public Order process(Order order) { order.setEmail(anonymize(order.getEmail())); return order; } public

    String process(Sensor sensor) { if (sensor.getTemp() > 50) // Envoi d’un mail ... return null; }
  18. public Void process(Order order, Context context) { Double threshold =

    context.getUserConfigValue("threshold"); Float previous = context.getState(order.getId() + "-metric"); context.incrCounter(order.getId() + "-metric", 1); }
  19. Broker 1 Function workers Broker 2 Function workers Broker 1

    Function worker 1 Broker 2 Function worker 2 Function workers
  20. # Déploiement d’une fonction $ pulsar-admin functions create \ --jar

    my_pulsar_fct.jar \ --className MyPulsarFunction \ --fqfn demo/test/hello \ --inputs persistent://demo/test/input \ --output persistent://demo/test/output \ --log-topic persistent://demo/test/logs \ --cpu 8 \ --ram 8589934592 \ --disk 10737418240
  21. $ pulsar sql presto> show catalogs; presto> show schemas in

    pulsar; presto> show tables in pulsar."demo/ecommerce"; Catalog --------- pulsar system Schema ----------------------- information_schema public/default public/functions demo/ecommerce Table --------------- orders-all orders-not-us orders-us TOPICS NAMESPACES
  22. presto> select id, orderdate, ipaddress, amount, email from pulsar."demo/ecommerce"."orders-all"; id

    | orderdate | ipaddress | amount | email -------------+---------------+-----------------+--------+---------------------------------- 307-02-9402 | 1561409774204 | 94.244.112.41 | 596.59 | [email protected] 470-87-6280 | 1561409774501 | 82.244.158.201 | 135.39 | [email protected] 842-89-5722 | 1561409774704 | 60.73.130.208 | 112.89 | [email protected] 795-45-3565 | 1561409775408 | 231.96.223.0 | 60.75 | [email protected] 876-36-9065 | 1561409775924 | 29.189.193.82 | 768.13 | [email protected] 840-97-8273 | 1561409776044 | 93.240.237.245 | 308.92 | [email protected] 043-41-7461 | 1561409776348 | 186.116.245.21 | 206.03 | [email protected] 069-72-8645 | 1561409776591 | 106.113.25.240 | 144.54 | [email protected]
  23. Apache Pulsar Analytics Connecteurs Consommateurs de commandes Transformation / Enrichissement

    Producteur de commandes Broker Topic orders-all Topic orders-us Stockage Bookie Functions FilterOrder Consommateurs API Pulsar Connectors (IO) Elasticsearch Sink Analytics Pulsar SQL (Presto) Producteurs API Pulsar
  24. - - tier-storage (AWS, Google, HDFS, …), - - -

    - intégration avec Spark, Flink, Nifi - Yahoo ! https://streaml.io/blog