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
7. 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
8. 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
9. 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 : Write-Ahead Logging)
Avec Pulsar: stockage des données et des
offsets (cursors)
10. Broker
Topic 1
segment 2segment 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
11. Broker
Topic 1
segment 2segment 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
13. TopicProducteur Consommateur - A1
Exclusive subscription
Subscription A
Consommateur - A2Les tentatives de connexions de A2
échoueront
Topics et abonnements
14. TopicProducteur Consommateur - B1
Fail-over subscription
Subscription B
Consommateur - B2
Messages consommés par B2,
uniquement en cas d’échec de B1
Topics et abonnements
15. TopicProducteur Consommateur - C1Subscription C
Consommateur - C2
Les messages sont envoyés aux deux consommateurs
(round robin) -> aucune garantie d’ordre !
Topics et abonnements
Shared subscription
16. TopicProducteur
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
18. 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
19. 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
27. 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=%sn",
new String(msg.getData()),
msg.getProducerName(),
msg.getMessageId());
consumer.acknowledge(msg); // A ne pas oublier
28. Schema Registry
Par défaut, le type des messages est byte[]
Pulsar fournit un système de contrôle des types de données:
uniquement valable pour les clients Java !!
Les schémas sont automatiquement uploadés sur les brokers à la
création des producteurs (et bien sûr sauvegardés dans
BookKeeper 😋)
Gestion des versions
29. // Côté producteur
Producer<Order> producer =
client.newProducer(JSONSchema.of(Order.class))
.topic("orders")
.create();
Order order = new Order(product, quantity);
producer.send(order);
30. // 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();
36. Pulsar Functions
Topic de sortieF
But: offrir un cadre d’exécution de traitements des
données sans utiliser d’environnement complémentaire
Topic d’entrée 1
Topic d’entrée 2
Topic des logs
State
38. // 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);
}
}
40. Dans les brokers
Pulsar Functions - Déploiement
Broker 1
Function workers
Broker 2
Function workers
Broker 1
Dans des containers
Function worker 1
Broker 2
Function worker 2
En local
Function
workers
42. Pulsar Functions
Exemples de cas d’utilisation des Functions:
- Routage des messages
- Filtrage
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;
return null;
}
43. Pulsar Functions
Exemples de cas d’utilisation des Functions:
- Modification des messages
- Alertes
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;
}
44. Pulsar Functions
Et quoi d’autres ?
- stockage de métriques, de compteurs (stockés
dans Apache BookKeeper, bien sûr)
- utilisation de paramètres de config,
- fenêtrage (sliding window, tumbling window)
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);
}
54. Réplication géographique
Cluster A
Topic 1Producteur
Cluster B
Topic 1
Cluster C
Topic 1Consommateur
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
Producteur
59. Conclusion
Il existe beaucoup de fonctions
intéressantes :
- découplage broker et stockage
- 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