Антон Долганин

Я инженер, который решает задачи, а не пишет на языке. Архитектура, разработка, DevOps — подбираю инструменты под цель, строю решения, которые работают в проде и масштабируются без боли.

У нас есть два потока: streamA и streamB. Нужно объединять их по ключу, но не всегда события есть в обоих потоках.

Различия типов Join:

Тип Join Поведение
Inner Только пары, где ключ есть в обоих
Left Все из streamA, + streamB, если есть
Outer Все пары из обоих потоков, даже если в одном нет

KStream<String, String> streamA = builder.stream("streamA");
KStream<String, String> streamB = builder.stream("streamB");

KStream<String, String> joined = streamA.leftJoin(
    streamB,
    (valueA, valueB) -> valueA + ":" + (valueB == null ? "NO_MATCH" : valueB),
    JoinWindows.of(Duration.ofMinutes(5))
);

joined.to("joined-topic");

Что получится: Если streamA содержит ключ, а streamB — нет, вернется valueA:NO_MATCH. Если ключ есть в обоих, вернется объединенное значение. Outer Join дополнительно возвращает записи из streamB, если нет соответствия в streamA.

Жизненный пример — корреляция заказов и оплат в интернет-магазине:

  • orders (ключ: order_id, value: заказ)
  • payments (ключ: order_id, value: платёж)

Inner Join

  • Покажет только оплаченные заказы.
  • Отлично для аналитики.

Left Join

  • Покажет все заказы, даже без оплаты.
  • Подходит для CRM и real-time панелей.

Outer Join

  • Покажет полную картину: и заказы без оплат, и оплаты без заказов.
  • Полезно для диагностики, расследований и мониторинга сбоев.

KStream-KStream Outer Join и Left Join — гибкость объединений в реальном времени