web-dev-qa-db-fra.com

Kafka API Streams: KStream à KTable

J'ai un sujet Kafka où j'envoie des événements de localisation (key = user_id, value = user_location). Je peux le lire et le traiter comme un KStream:

KStreamBuilder builder = new KStreamBuilder();

KStream<String, Location> locations = builder
        .stream("location_topic")
        .map((k, v) -> {
            // some processing here, omitted form clarity
            Location location = new Location(lat, lon);
            return new KeyValue<>(k, location);
        });

Cela fonctionne bien, mais j'aimerais avoir un KTable avec la dernière position connue de chaque utilisateur. Comment pourrais-je le faire?

Je suis capable de l'écrire et de lire sur un sujet intermédiaire:

// write to intermediate topic
locations.to(Serdes.String(), new LocationSerde(), "location_topic_aux");

// build KTable from intermediate topic
KTable<String, Location> table = builder.table("location_topic_aux", "store");

Existe-t-il un moyen simple d'obtenir un KTable à partir d'un KStream? Ceci est ma première application utilisant Kafka Streams, donc je manque probablement quelque chose d'évident.

29
Guido

Pour l'instant, il n'y a pas de moyen simple de le faire. Votre approche est absolument valide, comme indiqué dans la FAQ Confluent: http://docs.confluent.io/current/streams/faq.html#how-can-i-convert-a-kstream-to-a-ktable -sans-une-étape-d'agrégation

Il s'agit de l'approche la plus simple en ce qui concerne le code. Cependant, il présente les inconvénients que (a) vous devez gérer un sujet supplémentaire et (b) qu'il en résulte un trafic réseau supplémentaire car les données sont écrites et relues depuis Kafka.

Il existe une alternative, en utilisant une "réduction factice":

KStreamBuilder builder = new KStreamBuilder();
KStream<String, Long> stream = ...; // some computation that creates the derived KStream

KTable<String, Long> table = stream.groupByKey().reduce(
    new Reducer<Long>() {
        @Override
        public Long apply(Long aggValue, Long newValue) {
            return newValue;
        }
    },
    "dummy-aggregation-store");

Cette approche est un peu plus complexe en ce qui concerne le code par rapport à l'option 1, mais présente l'avantage (a) qu'aucune gestion manuelle des rubriques n'est requise et (b) la relecture des données de Kafka is pas nécessaire.

Dans l'ensemble, vous devez décider vous-même de l'approche que vous préférez:

Dans l'option 2, Kafka Streams créera une rubrique de journal des modifications interne pour sauvegarder le KTable pour la tolérance aux pannes. Ainsi, les deux approches nécessitent un stockage supplémentaire dans Kafka et Dans l'ensemble, il s'agit d'un compromis entre un code légèrement plus complexe dans l'option 2 et la gestion manuelle des rubriques dans l'option 1.

24
Matthias J. Sax